Events and the organisation profile now have an address, with a "Directions" link and an embedded Google Maps view (no API key required) shown on event pages, event cards, and the Contact page. New events default their location to the org's configured address.
729 lines
25 KiB
Plaintext
729 lines
25 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum UserRole {
|
|
admin
|
|
supervisor
|
|
staff
|
|
user
|
|
}
|
|
|
|
enum NotificationPreference {
|
|
email
|
|
whatsapp
|
|
both
|
|
}
|
|
|
|
enum RegistrationStatus {
|
|
pending
|
|
confirmed
|
|
partial_paid
|
|
paid
|
|
cancelled
|
|
}
|
|
|
|
enum CashupStatus {
|
|
open
|
|
closed
|
|
}
|
|
|
|
enum CashupAction {
|
|
closed
|
|
quick_closed
|
|
reopened
|
|
}
|
|
|
|
enum EventCostType {
|
|
once_off
|
|
per_item
|
|
}
|
|
|
|
enum SecurityEventType {
|
|
login
|
|
password_changed
|
|
password_reset
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
name String
|
|
email String @unique
|
|
password String
|
|
createdAt DateTime @default(now())
|
|
isActive Boolean @default(true)
|
|
phoneNumber String? @unique
|
|
updatedAt DateTime @updatedAt
|
|
role UserRole @default(user)
|
|
failedAttempts Int @default(0)
|
|
lockUntil DateTime?
|
|
tokenVersion Int @default(0)
|
|
notificationPreference NotificationPreference @default(email)
|
|
registrations Registration[]
|
|
payments Payment[]
|
|
paymentsRecorded Payment[] @relation("PaymentRecordedBy")
|
|
tickets Ticket[]
|
|
ticketScans TicketUsage[]
|
|
passwordResets PasswordReset[]
|
|
|
|
Event Event[]
|
|
FormDraft FormDraft[]
|
|
|
|
eventsClosed Event[] @relation("EventClosedBy")
|
|
eventsReopened Event[] @relation("EventReopenedBy")
|
|
cashupsPerformed EventCashup[]
|
|
notifyForEvents Event[] @relation("EventNotifyRecipients")
|
|
|
|
personCashCountsFor EventCashupPersonCount[] @relation("EventCashupPersonCountFor")
|
|
personCashCountsEntered EventCashupPersonCount[] @relation("EventCashupPersonCountEnteredBy")
|
|
|
|
securityEvents SecurityEvent[]
|
|
}
|
|
|
|
model Event {
|
|
id String @id @default(uuid())
|
|
title String
|
|
description String?
|
|
startDate DateTime
|
|
endDate DateTime
|
|
registrationDeadline DateTime?
|
|
goLiveAt DateTime @default(now())
|
|
price Float
|
|
picture String?
|
|
isActive Boolean @default(true)
|
|
isHidden Boolean @default(false)
|
|
requiresAuth Boolean @default(true)
|
|
requiresRegistration Boolean @default(true)
|
|
contactName String?
|
|
contactPhone String?
|
|
contactEmail String?
|
|
location String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
createdById String?
|
|
createdBy User? @relation(fields: [createdById], references: [id], onDelete: SetNull)
|
|
redirectUrl String? @unique
|
|
eventOptions EventOption[]
|
|
registrations Registration[]
|
|
payments Payment[]
|
|
tickets Ticket[]
|
|
attachments EventAttachment[]
|
|
form EventForm?
|
|
Section Section[]
|
|
|
|
cashupStatus CashupStatus @default(open)
|
|
cashupDraft Json?
|
|
closedAt DateTime?
|
|
closedById String?
|
|
closedBy User? @relation("EventClosedBy", fields: [closedById], references: [id], onDelete: SetNull)
|
|
reopenedAt DateTime?
|
|
reopenedById String?
|
|
reopenedBy User? @relation("EventReopenedBy", fields: [reopenedById], references: [id], onDelete: SetNull)
|
|
costs EventCost[]
|
|
cashups EventCashup[]
|
|
personCashCounts EventCashupPersonCount[]
|
|
|
|
// Users who should receive registration/payment/daily-summary notifications for this
|
|
// event. Falls back to `createdBy` when empty (see backend/src/utils/notifications.js).
|
|
notifyRecipients User[] @relation("EventNotifyRecipients")
|
|
|
|
@@index([createdById])
|
|
@@index([closedById])
|
|
@@index([reopenedById])
|
|
}
|
|
|
|
model EventOption {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
name String
|
|
price Float
|
|
isMainTicket Boolean
|
|
stockLimit Int @default(0)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Restrict)
|
|
registrationOptions RegistrationOption[]
|
|
earlyBirdTiers EarlyBirdTier[]
|
|
SectionOption SectionOption[]
|
|
variants OptionVariant[]
|
|
costs EventCost[]
|
|
|
|
@@index([eventId])
|
|
}
|
|
|
|
model EarlyBirdTier {
|
|
id String @id @default(uuid())
|
|
eventOptionId String
|
|
variantId String?
|
|
deadline DateTime
|
|
price Float
|
|
order Int @default(0)
|
|
stockLimit Int @default(0)
|
|
eventOption EventOption @relation(fields: [eventOptionId], references: [id], onDelete: Cascade)
|
|
variant OptionVariant? @relation(fields: [variantId], references: [id], onDelete: Cascade)
|
|
registrationOptions RegistrationOption[]
|
|
tranches RegistrationOptionTranche[]
|
|
|
|
@@index([eventOptionId, deadline])
|
|
@@index([variantId])
|
|
}
|
|
|
|
model OptionVariant {
|
|
id String @id @default(uuid())
|
|
eventOptionId String
|
|
name String
|
|
price Float?
|
|
stockLimit Int @default(0)
|
|
order Int @default(0)
|
|
eventOption EventOption @relation(fields: [eventOptionId], references: [id], onDelete: Cascade)
|
|
registrationOptions RegistrationOption[]
|
|
earlyBirdTiers EarlyBirdTier[]
|
|
|
|
@@index([eventOptionId])
|
|
}
|
|
|
|
model Registration {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
eventId String
|
|
status RegistrationStatus @default(pending)
|
|
checkoutId String? @unique
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Restrict)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Restrict)
|
|
registrationOptions RegistrationOption[]
|
|
payments Payment[]
|
|
formResponses FormResponse[]
|
|
formDrafts FormDraft[]
|
|
|
|
@@index([userId])
|
|
@@index([eventId])
|
|
@@index([userId, status])
|
|
@@index([eventId, status])
|
|
@@index([createdAt, status])
|
|
}
|
|
|
|
model RegistrationOption {
|
|
id String @id @default(uuid())
|
|
registrationId String
|
|
eventOptionId String
|
|
quantity Int @default(1)
|
|
variantId String?
|
|
appliedTierId String?
|
|
priceSnapshot Float?
|
|
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Restrict)
|
|
eventOption EventOption @relation(fields: [eventOptionId], references: [id], onDelete: Restrict)
|
|
variant OptionVariant? @relation(fields: [variantId], references: [id], onDelete: SetNull)
|
|
appliedTier EarlyBirdTier? @relation(fields: [appliedTierId], references: [id], onDelete: SetNull)
|
|
tickets Ticket[]
|
|
tranches RegistrationOptionTranche[]
|
|
|
|
@@index([registrationId])
|
|
@@index([eventOptionId])
|
|
@@index([variantId])
|
|
@@index([appliedTierId])
|
|
}
|
|
|
|
// One row per purchase-at-a-price for a RegistrationOption. Never mutated after creation
|
|
// (mirrors the Payment model's append-only pattern) — this is what lets a single ticket
|
|
// type be bought in multiple batches at different early-bird prices without either batch's
|
|
// price bleeding into the other. RegistrationOption.quantity/priceSnapshot/appliedTierId
|
|
// stay in sync as an aggregate (quantity = sum of tranche quantities; priceSnapshot/appliedTierId
|
|
// mirror the most recently added tranche) for the many call sites that only need "how many"
|
|
// or a single display price.
|
|
model RegistrationOptionTranche {
|
|
id String @id @default(uuid())
|
|
registrationOptionId String
|
|
quantity Int
|
|
priceSnapshot Float
|
|
appliedTierId String?
|
|
createdAt DateTime @default(now())
|
|
registrationOption RegistrationOption @relation(fields: [registrationOptionId], references: [id], onDelete: Cascade)
|
|
appliedTier EarlyBirdTier? @relation(fields: [appliedTierId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([registrationOptionId])
|
|
@@index([appliedTierId])
|
|
}
|
|
|
|
model Payment {
|
|
id String @id @default(uuid())
|
|
amount Float
|
|
method String
|
|
userId String
|
|
recordedById String?
|
|
registrationId String?
|
|
eventId String?
|
|
isDonation Boolean @default(false)
|
|
externalId String? @unique
|
|
status String?
|
|
originalPaymentId String?
|
|
createdAt DateTime @default(now())
|
|
user User @relation(fields: [userId], references: [id], onDelete: Restrict)
|
|
recordedBy User? @relation("PaymentRecordedBy", fields: [recordedById], references: [id], onDelete: SetNull)
|
|
registration Registration? @relation(fields: [registrationId], references: [id], onDelete: SetNull)
|
|
event Event? @relation(fields: [eventId], references: [id], onDelete: SetNull)
|
|
originalPayment Payment? @relation("SplitPayments", fields: [originalPaymentId], references: [id], onDelete: SetNull)
|
|
splitPayments Payment[] @relation("SplitPayments")
|
|
YocoTransaction YocoTransaction[]
|
|
|
|
@@index([userId])
|
|
@@index([recordedById])
|
|
@@index([registrationId])
|
|
@@index([eventId])
|
|
@@index([createdAt])
|
|
@@index([originalPaymentId, isDonation])
|
|
}
|
|
|
|
model Ticket {
|
|
id String @id @default(uuid())
|
|
qrCode String @unique
|
|
registrationOptionId String
|
|
userId String
|
|
eventId String
|
|
quantity Int @default(1)
|
|
isUsed Boolean @default(false)
|
|
emailSent Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
registrationOption RegistrationOption @relation(fields: [registrationOptionId], references: [id], onDelete: Restrict)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Restrict)
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Restrict)
|
|
usages TicketUsage[]
|
|
|
|
@@index([eventId])
|
|
@@index([userId])
|
|
@@index([registrationOptionId])
|
|
@@index([createdAt])
|
|
}
|
|
|
|
model TicketUsage {
|
|
id String @id @default(uuid())
|
|
ticketId String
|
|
scannedById String
|
|
scannedAt DateTime @default(now())
|
|
quantityRedeemed Int @default(1)
|
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Restrict)
|
|
scannedBy User @relation(fields: [scannedById], references: [id], onDelete: Restrict)
|
|
|
|
@@index([ticketId])
|
|
@@index([scannedAt])
|
|
@@index([scannedById, scannedAt])
|
|
}
|
|
|
|
model PasswordReset {
|
|
id String @id @default(uuid())
|
|
userId String
|
|
token String @unique
|
|
expiresAt DateTime
|
|
used Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
}
|
|
|
|
// Append-only "Account activity" log for the Profile & Security page (logins, password
|
|
// changes). Nullable FK with SetNull (not Cascade) so entries survive account
|
|
// close/anonymization, the same pattern EventCashup uses for its performedBy audit trail.
|
|
model SecurityEvent {
|
|
id String @id @default(uuid())
|
|
userId String?
|
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
type SecurityEventType
|
|
ip String?
|
|
device String?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, createdAt])
|
|
}
|
|
|
|
model EventAttachment {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
originalName String
|
|
filename String
|
|
mimeType String
|
|
size Int
|
|
url String
|
|
createdAt DateTime @default(now())
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([eventId])
|
|
}
|
|
|
|
// Event registration forms
|
|
enum FormFieldType {
|
|
yes_no
|
|
text
|
|
date
|
|
numeric
|
|
statement
|
|
paragraph
|
|
}
|
|
|
|
model EventForm {
|
|
id String @id @default(uuid())
|
|
eventId String @unique
|
|
isRequired Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
fields EventFormField[]
|
|
}
|
|
|
|
model EventFormField {
|
|
id String @id @default(uuid())
|
|
formId String
|
|
type FormFieldType
|
|
label String
|
|
isRequired Boolean @default(false)
|
|
order Int @default(0)
|
|
helpText String?
|
|
options Json?
|
|
form EventForm @relation(fields: [formId], references: [id], onDelete: Cascade)
|
|
answers FormAnswer[]
|
|
|
|
@@index([formId])
|
|
}
|
|
|
|
model FormResponse {
|
|
id String @id @default(uuid())
|
|
registrationId String
|
|
createdAt DateTime @default(now())
|
|
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
|
|
answers FormAnswer[]
|
|
|
|
@@index([registrationId])
|
|
}
|
|
|
|
model FormAnswer {
|
|
id String @id @default(uuid())
|
|
responseId String
|
|
fieldId String
|
|
value String
|
|
response FormResponse @relation(fields: [responseId], references: [id], onDelete: Cascade)
|
|
field EventFormField @relation(fields: [fieldId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([responseId])
|
|
@@index([fieldId])
|
|
}
|
|
|
|
// Draft storage for in-progress attendee forms
|
|
model FormDraft {
|
|
id String @id @default(uuid())
|
|
registrationId String
|
|
userId String
|
|
data Json
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
registration Registration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([registrationId, userId])
|
|
}
|
|
|
|
// Stores all webhook events from Yoco. If a Payment is created (registration or donation),
|
|
// the record is marked reconciled and linked via paymentId. Otherwise, remains unreconciled.
|
|
model YocoTransaction {
|
|
id String @id @default(uuid())
|
|
externalId String @unique // Yoco payment/event id
|
|
amount Int?
|
|
currency String?
|
|
createdDate DateTime?
|
|
checkoutId String?
|
|
methodType String? // paymentMethodDetails.type (e.g., card)
|
|
reconciled Boolean @default(false)
|
|
ignored Boolean @default(false)
|
|
paymentId String?
|
|
payment Payment? @relation(fields: [paymentId], references: [id], onDelete: SetNull)
|
|
raw Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([paymentId])
|
|
}
|
|
|
|
model Section {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
name String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
allowedOptions SectionOption[]
|
|
|
|
@@index([eventId])
|
|
}
|
|
|
|
model SectionOption {
|
|
id String @id @default(uuid())
|
|
sectionId String
|
|
eventOptionId String
|
|
|
|
section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade)
|
|
eventOption EventOption @relation(fields: [eventOptionId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([sectionId, eventOptionId])
|
|
}
|
|
|
|
model AppSetting {
|
|
key String @id
|
|
value String
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model EventCost {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
eventOptionId String?
|
|
eventOption EventOption? @relation(fields: [eventOptionId], references: [id], onDelete: Cascade)
|
|
label String
|
|
costType EventCostType
|
|
amount Float
|
|
paidFromMethod String? // 'cash' | 'card' | 'eft' | 'other' | null — null = not paid from event takings
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([eventId])
|
|
@@index([eventOptionId])
|
|
}
|
|
|
|
// Append-only audit trail: one row per close / quick-close / reopen. Never updated or deleted.
|
|
model EventCashup {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
action CashupAction
|
|
unallocatedDonationsTotal Float @default(0)
|
|
totalCosts Float @default(0)
|
|
totalExpectedRevenue Float @default(0)
|
|
totalActualRevenue Float?
|
|
notes String?
|
|
performedById String?
|
|
performedBy User? @relation(fields: [performedById], references: [id], onDelete: SetNull)
|
|
createdAt DateTime @default(now())
|
|
lines EventCashupLine[]
|
|
|
|
@@index([eventId, createdAt])
|
|
}
|
|
|
|
model EventCashupLine {
|
|
id String @id @default(uuid())
|
|
cashupId String
|
|
cashup EventCashup @relation(fields: [cashupId], references: [id], onDelete: Cascade)
|
|
method String
|
|
expectedAmount Float @default(0)
|
|
actualAmount Float?
|
|
variance Float?
|
|
notes String?
|
|
denominations EventCashupDenomination[]
|
|
|
|
@@index([cashupId])
|
|
}
|
|
|
|
model EventCashupDenomination {
|
|
id String @id @default(uuid())
|
|
lineId String
|
|
line EventCashupLine @relation(fields: [lineId], references: [id], onDelete: Cascade)
|
|
value Float
|
|
count Int
|
|
|
|
@@index([lineId])
|
|
}
|
|
|
|
// Actual physical cash counted for one staff member's recorded cash payments, entered any
|
|
// time (not part of the close flow) purely for accountability — compared against the
|
|
// system-expected amount (computeCashAccountabilityByUser) to show a per-person variance.
|
|
model EventCashupPersonCount {
|
|
id String @id @default(uuid())
|
|
eventId String
|
|
userId String
|
|
enteredById String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
|
user User @relation("EventCashupPersonCountFor", fields: [userId], references: [id], onDelete: Cascade)
|
|
enteredBy User? @relation("EventCashupPersonCountEnteredBy", fields: [enteredById], references: [id], onDelete: SetNull)
|
|
denominations EventCashupPersonCountDenomination[]
|
|
|
|
@@unique([eventId, userId])
|
|
@@index([eventId])
|
|
}
|
|
|
|
model EventCashupPersonCountDenomination {
|
|
id String @id @default(uuid())
|
|
countId String
|
|
value Float
|
|
count Int
|
|
personCount EventCashupPersonCount @relation(fields: [countId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([countId])
|
|
}
|
|
|
|
// ─── Church Website Models (disabled — kept for reference, not active Prisma models) ──
|
|
//
|
|
// model Ministry {
|
|
// id String @id @default(uuid())
|
|
// slug String @unique
|
|
// title String
|
|
// description String?
|
|
// image String?
|
|
// isActive Boolean @default(true)
|
|
// order Int @default(0)
|
|
// leaderId String?
|
|
// leader TeamMember? @relation(fields: [leaderId], references: [id], onDelete: SetNull)
|
|
// interests MinistryInterest[]
|
|
// createdAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
//
|
|
// @@index([isActive, order])
|
|
// @@index([leaderId])
|
|
// }
|
|
//
|
|
// model TeamMember {
|
|
// id String @id @default(uuid())
|
|
// name String
|
|
// title String
|
|
// bio String?
|
|
// photo String?
|
|
// order Int @default(0)
|
|
// isActive Boolean @default(true)
|
|
// email String?
|
|
// createdAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
// ministries Ministry[]
|
|
//
|
|
// @@index([isActive, order])
|
|
// }
|
|
//
|
|
// model ContentBlock {
|
|
// id String @id @default(uuid())
|
|
// page String
|
|
// key String
|
|
// value String
|
|
// type String @default("text")
|
|
// updatedAt DateTime @updatedAt
|
|
//
|
|
// @@unique([page, key])
|
|
// @@index([page])
|
|
// }
|
|
//
|
|
// model ChurchDocument {
|
|
// id String @id @default(uuid())
|
|
// title String
|
|
// description String?
|
|
// fileUrl String
|
|
// category String @default("other")
|
|
// isPublic Boolean @default(true)
|
|
// uploadedAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
// }
|
|
//
|
|
// model FellowshipGroup {
|
|
// id String @id @default(uuid())
|
|
// name String
|
|
// description String?
|
|
// leader String?
|
|
// isActive Boolean @default(true)
|
|
// order Int @default(0)
|
|
// members ChurchMember[]
|
|
// createdAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
//
|
|
// @@index([isActive, order])
|
|
// }
|
|
//
|
|
// model ChurchMember {
|
|
// id String @id @default(uuid())
|
|
// status String @default("pending")
|
|
// mainName String
|
|
// mainEmail String
|
|
// mainPhone String?
|
|
// mainBirthday DateTime?
|
|
// mainOccupation String?
|
|
// mainEmploymentStatus String?
|
|
// mainDateOfSalvation DateTime?
|
|
// mainDateOfWaterBaptism DateTime?
|
|
// mainHolySpiritBaptism Boolean @default(false)
|
|
// spouseName String?
|
|
// spouseEmail String?
|
|
// spousePhone String?
|
|
// spouseBirthday DateTime?
|
|
// spouseOccupation String?
|
|
// spouseEmploymentStatus String?
|
|
// spouseDateOfSalvation DateTime?
|
|
// spouseDateOfWaterBaptism DateTime?
|
|
// spouseHolySpiritBaptism Boolean?
|
|
// homeAddress String?
|
|
// inFellowshipGroup Boolean @default(false)
|
|
// fellowshipGroupId String?
|
|
// fellowshipGroup FellowshipGroup? @relation(fields: [fellowshipGroupId], references: [id], onDelete: SetNull)
|
|
// membershipConfirmed Boolean @default(false)
|
|
// notes String?
|
|
// appliedAt DateTime @default(now())
|
|
// approvedAt DateTime?
|
|
// createdAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
// children ChurchChild[]
|
|
// ministryInterests MinistryInterest[]
|
|
// donations Donation[]
|
|
//
|
|
// @@index([status])
|
|
// @@index([mainEmail])
|
|
// @@index([fellowshipGroupId])
|
|
// }
|
|
//
|
|
// model ChurchChild {
|
|
// id String @id @default(uuid())
|
|
// memberId String
|
|
// name String
|
|
// birthday DateTime?
|
|
// member ChurchMember @relation(fields: [memberId], references: [id], onDelete: Cascade)
|
|
//
|
|
// @@index([memberId])
|
|
// }
|
|
//
|
|
// model MinistryInterest {
|
|
// id String @id @default(uuid())
|
|
// memberId String
|
|
// ministryId String
|
|
// forSpouse Boolean @default(false)
|
|
// member ChurchMember @relation(fields: [memberId], references: [id], onDelete: Cascade)
|
|
// ministry Ministry @relation(fields: [ministryId], references: [id], onDelete: Cascade)
|
|
//
|
|
// @@unique([memberId, ministryId, forSpouse])
|
|
// @@index([memberId])
|
|
// @@index([ministryId])
|
|
// }
|
|
//
|
|
// model Donation {
|
|
// id String @id @default(uuid())
|
|
// donorName String?
|
|
// donorEmail String?
|
|
// donorPhone String?
|
|
// amount Float
|
|
// method String
|
|
// reference String?
|
|
// note String?
|
|
// isAnonymous Boolean @default(false)
|
|
// linkedMemberId String?
|
|
// linkedMember ChurchMember? @relation(fields: [linkedMemberId], references: [id], onDelete: SetNull)
|
|
// createdAt DateTime @default(now())
|
|
// updatedAt DateTime @updatedAt
|
|
//
|
|
// @@index([linkedMemberId])
|
|
// @@index([createdAt])
|
|
// @@index([method])
|
|
// }
|