Files
holiday-property-booking/prisma/schema.prisma

228 lines
5.9 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum BookingStatus {
PENDING_PAYMENT
PAYMENT_RECEIVED
CONFIRMED
CANCELLED
FAILED
}
enum PaymentStatus {
REQUIRES_PAYMENT
COMPLETED
FAILED
REFUNDED
}
enum AvailabilityBlockReason {
MAINTENANCE
OWNER_BLOCKED
BASE_RULE
OTHER
}
enum ContentPageStatus {
DRAFT
PUBLISHED
ARCHIVED
}
model SiteSettings {
id String @id @default(cuid())
businessName String
tagline String?
contactEmail String?
contactPhone String?
defaultSeoTitle String?
defaultSeoDescription String?
bookingHoldMinutes Int @default(30)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Property {
id String @id @default(cuid())
slug String @unique
title String
summary String
longDescription String
locationText String
sleeps Int
bedrooms Int
bathrooms Int
petsAllowed Boolean @default(false)
published Boolean @default(false)
featured Boolean @default(false)
minStayNights Int?
checkInTime String?
checkOutTime String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
images PropertyImage[]
amenities PropertyAmenity[]
pricingRules PricingRule[]
availability AvailabilityBlock[]
bookings Booking[]
enquiries Enquiry[]
testimonials Testimonial[]
}
model PropertyImage {
id String @id @default(cuid())
propertyId String
url String
altText String
displayOrder Int @default(0)
primaryImage Boolean @default(false)
createdAt DateTime @default(now())
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
@@index([propertyId, displayOrder])
}
model Amenity {
id String @id @default(cuid())
slug String @unique
name String
createdAt DateTime @default(now())
properties PropertyAmenity[]
}
model PropertyAmenity {
propertyId String
amenityId String
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
amenity Amenity @relation(fields: [amenityId], references: [id], onDelete: Cascade)
@@id([propertyId, amenityId])
@@index([amenityId])
}
model PricingRule {
id String @id @default(cuid())
propertyId String
label String?
basePriceCents Int
weekendPriceCents Int?
guestDeltaCents Int?
validFrom DateTime?
validTo DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
@@index([propertyId, validFrom, validTo])
}
model AvailabilityBlock {
id String @id @default(cuid())
propertyId String
startDate DateTime
endDate DateTime
reason AvailabilityBlockReason @default(OTHER)
notes String?
createdAt DateTime @default(now())
property Property @relation(fields: [propertyId], references: [id], onDelete: Cascade)
@@index([propertyId, startDate, endDate])
}
model Booking {
id String @id @default(cuid())
propertyId String
firstName String
lastName String
email String
phone String?
arrivalDate DateTime
departureDate DateTime
adults Int
children Int @default(0)
pets Int @default(0)
specialRequests String?
termsAccepted Boolean @default(false)
holdExpiresAt DateTime?
totalCents Int
currency String @default("GBP")
status BookingStatus @default(PENDING_PAYMENT)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
property Property @relation(fields: [propertyId], references: [id], onDelete: Restrict)
payment Payment?
@@index([propertyId, arrivalDate, departureDate])
@@index([status])
}
model Payment {
id String @id @default(cuid())
bookingId String @unique
stripeCheckoutSessionId String? @unique
stripePaymentIntentId String? @unique
stripeEventId String? @unique
amountCents Int
currency String @default("GBP")
status PaymentStatus @default(REQUIRES_PAYMENT)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade)
}
model Enquiry {
id String @id @default(cuid())
propertyId String?
name String
email String
phone String?
message String
createdAt DateTime @default(now())
property Property? @relation(fields: [propertyId], references: [id], onDelete: SetNull)
@@index([propertyId, createdAt])
}
model Testimonial {
id String @id @default(cuid())
propertyId String?
authorName String
content String
rating Int?
published Boolean @default(false)
displayOrder Int @default(0)
createdAt DateTime @default(now())
property Property? @relation(fields: [propertyId], references: [id], onDelete: SetNull)
@@index([published, displayOrder])
}
model ContentPage {
id String @id @default(cuid())
slug String @unique
title String
body String
status ContentPageStatus @default(DRAFT)
seoTitle String?
seoDescription String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}