Files
petmaster/api/prisma/schema.prisma
T
Robert Perez d8a4e43bcc feat(web): Schedule-First redesign
- Top header bar + narrow sidebar layout
- Dashboard: calendar-style schedule with timeline cards
- Clients: card-based layout with avatar initials and pet count
- Services: grid cards with emoji indicators and pricing
- Bookings: timeline cards with time slots, status chips, inline actions
- Invoices: cards with status badges, action buttons
- All pages: search bars, empty states, modal forms
- Consistent color system: indigo primary, amber alerts, gray hierarchy
2026-07-14 05:13:04 +00:00

172 lines
4.2 KiB
Plaintext

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")
}