163 lines
4.0 KiB
Plaintext
163 lines
4.0 KiB
Plaintext
|
|
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")
|
||
|
|
|
||
|
|
@@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? // e.g. "55 lbs"
|
||
|
|
color String?
|
||
|
|
tags String[] @default([])
|
||
|
|
notes String? @default("")
|
||
|
|
customFields Json?
|
||
|
|
clientId String
|
||
|
|
client Client @relation(fields: [clientId], references: [id], onDelete: Cascade)
|
||
|
|
|
||
|
|
@@map("pets")
|
||
|
|
}
|
||
|
|
|
||
|
|
model Service {
|
||
|
|
id String @id @default(cuid())
|
||
|
|
createdAt DateTime @default(now())
|
||
|
|
updatedAt DateTime @updatedAt
|
||
|
|
name String
|
||
|
|
description String @default("")
|
||
|
|
duration Int // minutes
|
||
|
|
basePrice Float // dollars
|
||
|
|
|
||
|
|
perClientPricing ClientPricing[]
|
||
|
|
|
||
|
|
@@map("services")
|
||
|
|
}
|
||
|
|
|
||
|
|
model ClientPricing {
|
||
|
|
id String @id @default(cuid())
|
||
|
|
createdAt DateTime @default(now())
|
||
|
|
updatedAt DateTime @updatedAt
|
||
|
|
price Float
|
||
|
|
discountType String @default("none") // none, percentage, flat
|
||
|
|
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(fields: [petId], references: [id])
|
||
|
|
invoice Invoice?
|
||
|
|
|
||
|
|
recurringRule Json? // { interval: "weekly" | "biweekly" | "monthly", count: Int, endDate: DateTime? }
|
||
|
|
|
||
|
|
@@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?
|
||
|
|
booking Booking? @relation(fields: [bookingId], references: [id])
|
||
|
|
|
||
|
|
items 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 // staff member identifier
|
||
|
|
|
||
|
|
@@map("messages")
|
||
|
|
}
|