783 lines
23 KiB
Plaintext
783 lines
23 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model Tenant {
|
|
id String @id @default(cuid())
|
|
name String
|
|
slug String @unique
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
users User[]
|
|
roles Role[]
|
|
events Event[]
|
|
attendees Attendee[]
|
|
registrations Registration[]
|
|
invitees Invitee[]
|
|
rsvps RSVP[]
|
|
payments PaymentTransaction[]
|
|
settings TenantSetting?
|
|
integrations IntegrationSetting[]
|
|
eventPages EventPage[]
|
|
ticketTypes TicketType[]
|
|
forms Form[]
|
|
formSubmissions FormSubmission[]
|
|
qrCodes QRCode[]
|
|
checkIns CheckIn[]
|
|
communicationTemplates CommunicationTemplate[]
|
|
communicationLogs CommunicationLog[]
|
|
paystackWebhookEvents PaystackWebhookEvent[]
|
|
crmLeads CRMLead[]
|
|
crmDeals CRMDeal[]
|
|
crmActivities CRMActivity[]
|
|
workflows Workflow[]
|
|
workflowTriggers WorkflowTrigger[]
|
|
workflowActions WorkflowAction[]
|
|
calendarRoutingForms CalendarRoutingForm[]
|
|
calendarSlots CalendarSlot[]
|
|
bookings Booking[]
|
|
formFields FormField[]
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
email String
|
|
fullName String
|
|
phone String?
|
|
addressLine1 String?
|
|
addressLine2 String?
|
|
city String?
|
|
state String?
|
|
country String?
|
|
avatarUrl String?
|
|
mustChangePassword Boolean @default(false)
|
|
passwordHash String
|
|
refreshTokenId String? @unique
|
|
refreshTokenHash String?
|
|
refreshTokenExpiresAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
roles UserRole[]
|
|
performedCheckIns CheckIn[] @relation("CheckInUser")
|
|
crmActivities CRMActivity[] @relation("CRMActivityUser")
|
|
|
|
@@unique([tenantId, email])
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model TenantSetting {
|
|
id String @id @default(cuid())
|
|
tenantId String @unique
|
|
appName String?
|
|
logoUrl String?
|
|
modules Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model IntegrationSetting {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
key String
|
|
value String?
|
|
isSecret Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([tenantId, key])
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model Role {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
users UserRole[]
|
|
permissions RolePermission[]
|
|
|
|
@@unique([tenantId, name])
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model Permission {
|
|
id String @id @default(cuid())
|
|
key String @unique
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
roles RolePermission[]
|
|
}
|
|
|
|
model UserRole {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
roleId String
|
|
createdAt DateTime @default(now())
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, roleId])
|
|
}
|
|
|
|
model RolePermission {
|
|
id String @id @default(cuid())
|
|
roleId String
|
|
permissionId String
|
|
createdAt DateTime @default(now())
|
|
|
|
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
|
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([roleId, permissionId])
|
|
}
|
|
|
|
enum EventStatus {
|
|
draft
|
|
active
|
|
closed
|
|
}
|
|
|
|
model Event {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
slug String
|
|
status EventStatus @default(draft)
|
|
startsAt DateTime
|
|
venue String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
attendees Attendee[]
|
|
registrations Registration[]
|
|
invitees Invitee[]
|
|
rsvps RSVP[]
|
|
payments PaymentTransaction[]
|
|
eventPage EventPage?
|
|
ticketTypes TicketType[]
|
|
forms Form[]
|
|
formSubmissions FormSubmission[]
|
|
checkIns CheckIn[]
|
|
crmLeads CRMLead[]
|
|
crmDeals CRMDeal[]
|
|
calendarRoutingForms CalendarRoutingForm[]
|
|
bookings Booking[]
|
|
|
|
@@unique([tenantId, slug])
|
|
@@index([tenantId])
|
|
@@index([tenantId, status])
|
|
}
|
|
|
|
enum RegistrationStatus {
|
|
pending
|
|
confirmed
|
|
cancelled
|
|
}
|
|
|
|
model Registration {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
attendeeId String
|
|
ticketTypeId String?
|
|
status RegistrationStatus @default(pending)
|
|
code String @unique
|
|
source String @default("admin")
|
|
checkedInAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
attendee Attendee @relation(fields: [attendeeId], references: [id], onDelete: Cascade)
|
|
ticketType TicketType? @relation(fields: [ticketTypeId], references: [id], onDelete: SetNull)
|
|
qrCode QRCode?
|
|
checkIns CheckIn[]
|
|
formSubmissions FormSubmission[]
|
|
communicationLogs CommunicationLog[]
|
|
payments PaymentTransaction[]
|
|
|
|
@@unique([tenantId, eventId, attendeeId])
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
@@index([eventId])
|
|
@@index([ticketTypeId])
|
|
}
|
|
|
|
enum InviteeStatus {
|
|
invited
|
|
delivered
|
|
opened
|
|
rsvped
|
|
bounced
|
|
}
|
|
|
|
model Invitee {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
fullName String
|
|
email String
|
|
phone String?
|
|
status InviteeStatus @default(invited)
|
|
code String @unique
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
rsvps RSVP[]
|
|
communicationLogs CommunicationLog[]
|
|
|
|
@@unique([tenantId, eventId, email])
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
}
|
|
|
|
enum RSVPResponse {
|
|
yes
|
|
no
|
|
maybe
|
|
}
|
|
|
|
model RSVP {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
inviteeId String?
|
|
response RSVPResponse
|
|
note String?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
invitee Invitee? @relation(fields: [inviteeId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
@@index([inviteeId])
|
|
}
|
|
|
|
enum PaymentStatus {
|
|
initialized
|
|
success
|
|
failed
|
|
}
|
|
|
|
model PaymentTransaction {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
registrationId String?
|
|
ticketTypeId String?
|
|
email String
|
|
amountKobo Int
|
|
currency String @default("NGN")
|
|
provider String @default("paystack")
|
|
reference String @unique
|
|
status PaymentStatus @default(initialized)
|
|
raw Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
|
|
ticketType TicketType? @relation(fields: [ticketTypeId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
@@index([eventId])
|
|
@@index([registrationId])
|
|
@@index([ticketTypeId])
|
|
}
|
|
|
|
model Attendee {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String?
|
|
fullName String
|
|
email String
|
|
phone String?
|
|
tags String[] @default([])
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
registrations Registration[]
|
|
formSubmissions FormSubmission[]
|
|
checkIns CheckIn[]
|
|
crmLeads CRMLead[]
|
|
bookings Booking[]
|
|
|
|
@@unique([tenantId, email])
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
actorUserId String?
|
|
action String
|
|
entityType String?
|
|
entityId String?
|
|
ip String?
|
|
userAgent String?
|
|
metadata Json?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([tenantId])
|
|
@@index([actorUserId])
|
|
@@index([entityType, entityId])
|
|
}
|
|
|
|
model EventPage {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String @unique
|
|
title String
|
|
heroTitle String?
|
|
description String?
|
|
content Json?
|
|
theme Json?
|
|
publishedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model TicketType {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
name String
|
|
description String?
|
|
priceKobo Int @default(0)
|
|
currency String @default("NGN")
|
|
capacity Int?
|
|
soldCount Int @default(0)
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
registrations Registration[]
|
|
payments PaymentTransaction[]
|
|
|
|
@@unique([tenantId, eventId, name])
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
}
|
|
|
|
model Form {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String?
|
|
name String
|
|
slug String
|
|
description String?
|
|
isPublic Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
fields FormField[]
|
|
submissions FormSubmission[]
|
|
|
|
@@unique([tenantId, slug])
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
}
|
|
|
|
model FormField {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
formId String
|
|
label String
|
|
key String
|
|
type String
|
|
required Boolean @default(false)
|
|
options Json?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
form Form @relation(fields: [formId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([formId, key])
|
|
@@index([tenantId])
|
|
@@index([formId])
|
|
}
|
|
|
|
model FormSubmission {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
formId String
|
|
eventId String?
|
|
attendeeId String?
|
|
registrationId String?
|
|
data Json
|
|
source String @default("admin")
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
form Form @relation(fields: [formId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
|
|
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([formId])
|
|
@@index([eventId])
|
|
@@index([attendeeId])
|
|
@@index([registrationId])
|
|
}
|
|
|
|
model QRCode {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
registrationId String @unique
|
|
code String @unique
|
|
payload Json
|
|
status QRCodeStatus @default(active)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
}
|
|
|
|
enum QRCodeStatus {
|
|
active
|
|
revoked
|
|
}
|
|
|
|
model CheckIn {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String
|
|
registrationId String
|
|
attendeeId String?
|
|
checkedInByUserId String?
|
|
code String
|
|
result CheckInResult @default(checked_in)
|
|
note String?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
|
|
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
|
|
checkedInBy User? @relation("CheckInUser", fields: [checkedInByUserId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([tenantId, eventId])
|
|
@@index([registrationId])
|
|
@@index([attendeeId])
|
|
}
|
|
|
|
enum CheckInResult {
|
|
checked_in
|
|
duplicate
|
|
rejected
|
|
}
|
|
|
|
model CommunicationTemplate {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
channel CommunicationChannel
|
|
subject String?
|
|
body String
|
|
variables Json?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
logs CommunicationLog[]
|
|
|
|
@@unique([tenantId, name, channel])
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model CommunicationLog {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
templateId String?
|
|
inviteeId String?
|
|
registrationId String?
|
|
channel CommunicationChannel
|
|
to String
|
|
subject String?
|
|
body String
|
|
status CommunicationStatus @default(queued)
|
|
providerMessageId String?
|
|
error String?
|
|
raw Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
template CommunicationTemplate? @relation(fields: [templateId], references: [id], onDelete: SetNull)
|
|
invitee Invitee? @relation(fields: [inviteeId], references: [id], onDelete: SetNull)
|
|
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([templateId])
|
|
@@index([inviteeId])
|
|
@@index([registrationId])
|
|
}
|
|
|
|
enum CommunicationChannel {
|
|
email
|
|
sms
|
|
whatsapp
|
|
}
|
|
|
|
enum CommunicationStatus {
|
|
queued
|
|
sent
|
|
failed
|
|
}
|
|
|
|
model PaystackWebhookEvent {
|
|
id String @id @default(cuid())
|
|
tenantId String?
|
|
event String
|
|
reference String?
|
|
status String @default("received")
|
|
raw Json
|
|
receivedAt DateTime @default(now())
|
|
processedAt DateTime?
|
|
|
|
tenant Tenant? @relation(fields: [tenantId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([reference])
|
|
}
|
|
|
|
model CRMLead {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String?
|
|
attendeeId String?
|
|
fullName String
|
|
email String
|
|
phone String?
|
|
source String @default("manual")
|
|
status String @default("new")
|
|
valueKobo Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
|
|
deals CRMDeal[]
|
|
activities CRMActivity[]
|
|
|
|
@@unique([tenantId, email])
|
|
@@index([tenantId])
|
|
@@index([eventId])
|
|
@@index([attendeeId])
|
|
}
|
|
|
|
model CRMDeal {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
leadId String?
|
|
eventId String?
|
|
title String
|
|
stage String @default("new")
|
|
valueKobo Int @default(0)
|
|
probability Int @default(0)
|
|
ownerUserId String?
|
|
expectedCloseAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
lead CRMLead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
activities CRMActivity[]
|
|
|
|
@@index([tenantId])
|
|
@@index([leadId])
|
|
@@index([eventId])
|
|
}
|
|
|
|
model CRMActivity {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
leadId String?
|
|
dealId String?
|
|
userId String?
|
|
type String @default("note")
|
|
note String
|
|
dueAt DateTime?
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
lead CRMLead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
|
|
deal CRMDeal? @relation(fields: [dealId], references: [id], onDelete: SetNull)
|
|
user User? @relation("CRMActivityUser", fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([leadId])
|
|
@@index([dealId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model Workflow {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
name String
|
|
description String?
|
|
enabled Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
triggers WorkflowTrigger[]
|
|
actions WorkflowAction[]
|
|
|
|
@@unique([tenantId, name])
|
|
@@index([tenantId])
|
|
}
|
|
|
|
model WorkflowTrigger {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
workflowId String
|
|
type String
|
|
config Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
@@index([workflowId])
|
|
}
|
|
|
|
model WorkflowAction {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
workflowId String
|
|
type String
|
|
config Json?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
@@index([workflowId])
|
|
}
|
|
|
|
model CalendarRoutingForm {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
eventId String?
|
|
name String
|
|
slug String
|
|
description String?
|
|
durationMinutes Int @default(30)
|
|
active Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
slots CalendarSlot[]
|
|
bookings Booking[]
|
|
|
|
@@unique([tenantId, slug])
|
|
@@index([tenantId])
|
|
@@index([eventId])
|
|
}
|
|
|
|
model CalendarSlot {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
routingFormId String
|
|
startsAt DateTime
|
|
endsAt DateTime
|
|
capacity Int @default(1)
|
|
bookedCount Int @default(0)
|
|
active Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
routingForm CalendarRoutingForm @relation(fields: [routingFormId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tenantId])
|
|
@@index([routingFormId])
|
|
@@index([startsAt])
|
|
}
|
|
|
|
model Booking {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
routingFormId String
|
|
eventId String?
|
|
attendeeId String?
|
|
fullName String
|
|
email String
|
|
phone String?
|
|
startsAt DateTime
|
|
endsAt DateTime
|
|
status String @default("booked")
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
routingForm CalendarRoutingForm @relation(fields: [routingFormId], references: [id], onDelete: Cascade)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
attendee Attendee? @relation(fields: [attendeeId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([tenantId])
|
|
@@index([routingFormId])
|
|
@@index([eventId])
|
|
@@index([attendeeId])
|
|
@@index([startsAt])
|
|
}
|