generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String? // hashed password name String? username String @unique role Role @default(GUEST) events Event[] @relation("EventCreator") createdAt DateTime @default(now()) FileUpload FileUpload[] } enum Role { COUPLE PLANNER GUEST } model Event { id String @id @default(cuid()) name String date DateTime? venue Venue? @relation(fields: [venueId], references: [id]) venueId String? creator User @relation("EventCreator", fields: [creatorId], references: [id]) creatorId String guests Guest[] eventGuests EventGuest[] notes String? todos EventTodo[] createdAt DateTime @default(now()) FileUpload FileUpload[] vendors Vendor[] } model Venue { id String @id @default(cuid()) name String address String city String state String postalCode String country String @default("United States") phone String? email String? createdAt DateTime @default(now()) Event Event[] } model Guest { id String @id @default(cuid()) event Event @relation(fields: [eventId], references: [id]) eventId String name String email String? rsvp RsvpStatus @default(PENDING) // attended RsvpStatus @default(PENDING) } enum RsvpStatus { YES NO PENDING } model InviteToken { id String @id @default(cuid()) email String @unique role Role token String @unique eventId String? expiresAt DateTime accepted Boolean @default(false) createdAt DateTime @default(now()) } model GuestBookEntry { id String @id @default(cuid()) fName String lName String email String? phone String? address String? notes String? side String congratulated Boolean? eventGuests EventGuest[] createdAt DateTime @default(now()) } model EventGuest { id String @id @default(cuid()) event Event @relation(fields: [eventId], references: [id]) eventId String guestBookEntry GuestBookEntry @relation(fields: [guestBookEntryId], references: [id]) guestBookEntryId String rsvp RsvpStatus @default(PENDING) createdAt DateTime @default(now()) @@unique([eventId, guestBookEntryId]) } model EventTodo { id String @id @default(cuid()) name String complete Boolean @default(false) dueDate DateTime? notes String? event Event @relation(fields: [eventId], references: [id]) eventId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Optional for future extensibility // category String? // assignedTo String? // could link to User in future } model FileUpload { id String @id @default(cuid()) filepath String filename String filetype String filesize Int //in bytes uploadedAt DateTime @default(now()) uploadedBy User @relation(fields: [uploadedById], references: [id]) uploadedById String event Event? @relation(fields: [eventId], references: [id]) eventId String? @@unique([filename, uploadedById]) } model Vendor { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String type VendorType description String? website String? contactPerson String? email String? phone String? address Address? @relation(fields: [addressId], references: [id]) addressId String? status VendorStatus @default(CONTACTING) isBooked Boolean @default(false) bookedDate DateTime? quotedPrice Float? finalCost Float? depositPaid Float? depositDueDate DateTime? finalPaymentDue DateTime? paymentNotes String? contractUrl String? proposalUrl String? notes String? events Event[] categories Category[] } model Address { id String @id @default(cuid()) street String city String state String zip Int vendors Vendor[] } model Category { id String @id @default(cuid()) name String @unique description String? color String? @default("#3B82F6") // For UI purposes vendors Vendor[] } enum VendorType { VENUE CATERER PHOTOGRAPHER VIDEOGRAPHER FLORIST BAKERY DJ BAND OFFICIANT HAIR_MAKEUP TRANSPORTATION RENTALS DECOR PLANNER STATIONERY OTHER } enum VendorStatus { RESEARCHING // Just found them CONTACTING // Reached out but no response yet RESPONDED // They responded PROPOSAL_RECEIVED // Got their quote/proposal NEGOTIATING // Discussing terms/price CONTRACT_SENT // Sent contract for review CONTRACT_SIGNED // Officially booked! DECLINED // Not using them BACKUP // Keeping as backup option }