datasource db { provider = "postgresql" url = env("DATABASE_URL") } generator client { provider = "prisma-client-js" } model Client { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt firstName String lastName String email String @unique phone String? address String? notes String? @default("") customFields Json? isActive Boolean @default(true) pets Pet[] bookings Booking[] invoices Invoice[] messages Message[] @relation("ClientMessages") pricing ClientPricing[] @@map("clients") } model Pet { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String species String breed String? age Int? weight String? color String? tags String[] @default([]) notes String? @default("") customFields Json? clientId String client Client @relation(fields: [clientId], references: [id], onDelete: Cascade) bookings Booking[] @relation("PetBookings") @@map("pets") } model Service { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt name String description String @default("") duration Int basePrice Float perClientPricing ClientPricing[] bookings Booking[] @@map("services") } model ClientPricing { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt price Float discountType String @default("none") discountValue Float @default(0) serviceId String service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade) clientId String client Client @relation(fields: [clientId], references: [id], onDelete: Cascade) @@unique([serviceId, clientId]) @@map("client_pricing") } model Booking { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt startAt DateTime endAt DateTime status BookingStatus @default(scheduled) notes String? @default("") customFields Json? clientId String client Client @relation(fields: [clientId], references: [id]) serviceId String service Service @relation(fields: [serviceId], references: [id]) assignedStaff String? priceOverride Float? petId String? pet Pet? @relation("PetBookings", fields: [petId], references: [id]) invoice Invoice? @relation() recurringRule Json? @@map("bookings") } enum BookingStatus { scheduled confirmed in_progress completed cancelled } model Invoice { id String @id @default(cuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt invoiceNumber String @unique dueDate DateTime status InvoiceStatus @default(draft) stripePaymentIntentId String? subtotal Float @default(0) tax Float @default(0) total Float @default(0) notes String? @default("") clientId String client Client @relation(fields: [clientId], references: [id]) bookingId String? @unique booking Booking? @relation(fields: [bookingId], references: [id]) invoiceItems InvoiceItem[] @@map("invoices") } enum InvoiceStatus { draft sent paid overdue cancelled } model InvoiceItem { id String @id @default(cuid()) createdAt DateTime @default(now()) description String quantity Int @default(1) unitPrice Float amount Float invoiceId String invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade) @@map("invoice_items") } model Message { id String @id @default(cuid()) createdAt DateTime @default(now()) readAt DateTime? content String isFromStaff Boolean @default(false) clientId String client Client @relation("ClientMessages", fields: [clientId], references: [id]) staffId String @@map("messages") }