generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } enum BookingStatus { received contacting confirmed completed cancelled } enum BookingRequestType { package private_chef } enum ContactPreference { wechat phone none } enum FulfillmentType { pickup delivery } model BrandProfile { id String @id @default(uuid()) name String tagline String? description String? avatarUrl String? coverUrl String? hours String? address String? deliveryNote String? contactPhone String? contactWechat String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt services Service[] bookings Booking[] customerUsers CustomerUser[] tags Tag[] } model Service { id String @id @default(uuid()) brandId String brand BrandProfile @relation(fields: [brandId], references: [id]) name String description String coverUrl String? priceText String? priceAmount Int? bookingEnabled Boolean @default(true) isEnabled Boolean @default(true) sortOrder Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt bookings Booking[] bookingItems BookingItem[] @@index([brandId, isEnabled, sortOrder]) } model CustomerUser { id String @id @default(uuid()) brandId String brand BrandProfile @relation(fields: [brandId], references: [id]) openid String lastLoginAt DateTime @default(now()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt bookings Booking[] @@unique([brandId, openid]) } model Booking { id String @id @default(uuid()) bookingNo String @unique brandId String brand BrandProfile @relation(fields: [brandId], references: [id]) customerUserId String customerUser CustomerUser @relation(fields: [customerUserId], references: [id]) requestType BookingRequestType customerName String phone String? wechatId String? contactPreference ContactPreference fulfillmentType FulfillmentType? serviceId String? service Service? @relation(fields: [serviceId], references: [id], onDelete: SetNull) requestedDate DateTime? requestedTime String? deliveryAddress String? estimatedAmount Int? extraData Json? note String? adminNote String? status BookingStatus @default(received) isRead Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt items BookingItem[] tags BookingTag[] @@index([brandId, status, createdAt]) @@index([customerUserId, createdAt]) } model BookingItem { id String @id @default(uuid()) bookingId String booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade) serviceId String? service Service? @relation(fields: [serviceId], references: [id], onDelete: SetNull) serviceNameSnapshot String unitPriceSnapshot Int quantity Int subtotalSnapshot Int } model Tag { id String @id @default(uuid()) brandId String brand BrandProfile @relation(fields: [brandId], references: [id]) name String isPreset Boolean @default(false) isEnabled Boolean @default(true) createdAt DateTime @default(now()) bookings BookingTag[] @@unique([brandId, name]) } model AdminUser { id String @id @default(uuid()) username String @unique passwordHash String displayName String role String @default("admin") isEnabled Boolean @default(true) lastLoginAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model BookingTag { bookingId String tagId String booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade) tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade) @@id([bookingId, tagId]) }