425 lines
10 KiB
Plaintext
425 lines
10 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum UserRole {
|
|
ADMIN
|
|
DRIVER
|
|
}
|
|
|
|
enum BookingStatus {
|
|
RESERVED // Initial (nach E-Mail-Eingang)
|
|
CONFIRMED // Admin hat bestätigt & gesendet
|
|
READY_FOR_ASSIGNMENT // Vertrag unterschrieben → Admin-Freigabe
|
|
OPEN_FOR_DRIVERS // Admin hat freigegeben → Fahrer können sich melden
|
|
ASSIGNED // Admin hat Fahrer zugewiesen & Tour erstellt
|
|
COMPLETED // Event abgeschlossen
|
|
CANCELLED // Storniert
|
|
}
|
|
|
|
enum PhotoboxStatus {
|
|
AVAILABLE
|
|
IN_USE
|
|
MAINTENANCE
|
|
DAMAGED
|
|
}
|
|
|
|
enum PhotoboxModel {
|
|
VINTAGE_SMILE
|
|
VINTAGE_PHOTOS
|
|
NOSTALGIE
|
|
MAGIC_MIRROR
|
|
}
|
|
|
|
enum InvoiceType {
|
|
PRIVATE
|
|
BUSINESS
|
|
}
|
|
|
|
enum EquipmentType {
|
|
PRINTER
|
|
CARPET
|
|
VIP_BARRIER
|
|
ACCESSORIES_KIT
|
|
PRINTER_PAPER
|
|
TRIPOD
|
|
OTHER
|
|
}
|
|
|
|
enum EquipmentStatus {
|
|
AVAILABLE
|
|
IN_USE
|
|
MAINTENANCE
|
|
DAMAGED
|
|
RESERVED
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
name String
|
|
password String
|
|
role UserRole @default(DRIVER)
|
|
phoneNumber String?
|
|
vehiclePlate String?
|
|
vehicleModel String?
|
|
active Boolean @default(true)
|
|
available Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
driverTours Tour[]
|
|
notifications Notification[]
|
|
driverAvailability DriverAvailability[]
|
|
}
|
|
|
|
model Location {
|
|
id String @id @default(cuid())
|
|
name String
|
|
city String
|
|
slug String @unique
|
|
websiteUrl String
|
|
contactEmail String
|
|
active Boolean @default(true)
|
|
|
|
imapHost String?
|
|
imapPort Int?
|
|
imapUser String?
|
|
imapPassword String?
|
|
imapSecure Boolean @default(true)
|
|
|
|
smtpHost String?
|
|
smtpPort Int?
|
|
smtpUser String?
|
|
smtpPassword String?
|
|
smtpSecure Boolean @default(true)
|
|
|
|
emailSyncEnabled Boolean @default(false)
|
|
lastEmailSync DateTime?
|
|
|
|
priceConfig PriceConfig[]
|
|
photoboxes Photobox[]
|
|
bookings Booking[]
|
|
equipment Equipment[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([slug])
|
|
}
|
|
|
|
model PriceConfig {
|
|
id String @id @default(cuid())
|
|
locationId String
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
|
|
|
|
model PhotoboxModel
|
|
basePrice Float
|
|
pricePerKm Float
|
|
includedKm Int @default(0)
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@unique([locationId, model])
|
|
}
|
|
|
|
model Photobox {
|
|
id String @id @default(cuid())
|
|
locationId String
|
|
location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
|
|
|
|
model PhotoboxModel
|
|
serialNumber String @unique
|
|
status PhotoboxStatus @default(AVAILABLE)
|
|
active Boolean @default(true)
|
|
|
|
description String?
|
|
purchaseDate DateTime?
|
|
lastMaintenance DateTime?
|
|
|
|
bookings Booking[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([locationId, model])
|
|
@@index([status])
|
|
}
|
|
|
|
model Booking {
|
|
id String @id @default(cuid())
|
|
bookingNumber String @unique
|
|
|
|
locationId String
|
|
location Location @relation(fields: [locationId], references: [id])
|
|
|
|
photoboxId String?
|
|
photobox Photobox? @relation(fields: [photoboxId], references: [id])
|
|
|
|
status BookingStatus @default(RESERVED)
|
|
|
|
customerName String
|
|
customerEmail String
|
|
customerPhone String
|
|
customerAddress String?
|
|
customerCity String?
|
|
customerZip String?
|
|
|
|
invoiceType InvoiceType @default(PRIVATE)
|
|
companyName String?
|
|
|
|
eventDate DateTime
|
|
eventAddress String
|
|
eventCity String
|
|
eventZip String
|
|
eventLocation String?
|
|
|
|
setupTimeStart DateTime
|
|
setupTimeLatest DateTime
|
|
dismantleTimeEarliest DateTime?
|
|
dismantleTimeLatest DateTime?
|
|
|
|
distance Float?
|
|
calculatedPrice Float?
|
|
|
|
// Contract Management
|
|
contractSigned Boolean @default(false)
|
|
contractSignedAt DateTime?
|
|
contractGenerated Boolean @default(false)
|
|
contractGeneratedAt DateTime?
|
|
contractSentAt DateTime?
|
|
contractSignedOnline Boolean @default(false)
|
|
contractPdfUrl String?
|
|
contractSignatureData String? @db.Text
|
|
contractSignedBy String?
|
|
contractSignedIp String?
|
|
contractUploadedBy String?
|
|
|
|
lexofficeOfferId String?
|
|
lexofficeInvoiceId String?
|
|
lexofficeContactId String?
|
|
lexofficeConfirmationId String?
|
|
confirmationSentAt DateTime?
|
|
|
|
// KI-Analyse
|
|
aiParsed Boolean @default(false)
|
|
aiResponseDraft String? @db.Text
|
|
aiProcessedAt DateTime?
|
|
|
|
// Freigabe-Status
|
|
readyForAssignment Boolean @default(false)
|
|
openForDrivers Boolean @default(false)
|
|
|
|
// Kalender-Sync (Nextcloud)
|
|
calendarEventId String?
|
|
calendarSynced Boolean @default(false)
|
|
calendarSyncedAt DateTime?
|
|
|
|
tourId String?
|
|
tour Tour? @relation(fields: [tourId], references: [id])
|
|
|
|
notes String?
|
|
internalNotes String?
|
|
|
|
emails Email[]
|
|
bookingEquipment BookingEquipment[]
|
|
driverAvailability DriverAvailability[]
|
|
setupWindows SetupWindow[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([eventDate])
|
|
@@index([status])
|
|
@@index([locationId])
|
|
}
|
|
|
|
model SetupWindow {
|
|
id String @id @default(cuid())
|
|
bookingId String
|
|
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade)
|
|
|
|
setupDate DateTime
|
|
setupTimeStart DateTime
|
|
setupTimeEnd DateTime
|
|
preferred Boolean @default(false)
|
|
selected Boolean @default(false)
|
|
|
|
notes String?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([bookingId])
|
|
@@index([setupDate])
|
|
}
|
|
|
|
enum TourStatus {
|
|
PLANNED
|
|
IN_PROGRESS
|
|
COMPLETED
|
|
CANCELLED
|
|
}
|
|
|
|
model Tour {
|
|
id String @id @default(cuid())
|
|
tourDate DateTime
|
|
tourNumber String @unique
|
|
|
|
driverId String?
|
|
driver User? @relation(fields: [driverId], references: [id])
|
|
|
|
bookings Booking[]
|
|
|
|
routeOptimized Json?
|
|
totalDistance Float?
|
|
estimatedDuration Int?
|
|
|
|
status TourStatus @default(PLANNED)
|
|
startedAt DateTime?
|
|
completedAt DateTime?
|
|
|
|
notes String?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([tourDate])
|
|
@@index([driverId])
|
|
@@index([status])
|
|
}
|
|
|
|
model Notification {
|
|
id String @id @default(cuid())
|
|
userId String?
|
|
user User? @relation(fields: [userId], references: [id])
|
|
|
|
type String
|
|
title String
|
|
message String
|
|
read Boolean @default(false)
|
|
|
|
metadata Json?
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([userId, read])
|
|
}
|
|
|
|
model Email {
|
|
id String @id @default(cuid())
|
|
locationSlug String?
|
|
|
|
from String
|
|
to String
|
|
subject String
|
|
textBody String?
|
|
htmlBody String?
|
|
|
|
messageId String? @unique
|
|
inReplyTo String?
|
|
|
|
bookingId String?
|
|
booking Booking? @relation(fields: [bookingId], references: [id])
|
|
|
|
parsed Boolean @default(false)
|
|
parsedData Json?
|
|
|
|
direction String @default("INBOUND")
|
|
|
|
receivedAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([locationSlug])
|
|
@@index([bookingId])
|
|
@@index([receivedAt])
|
|
}
|
|
|
|
model Project {
|
|
id String @id @default(cuid())
|
|
name String
|
|
description String?
|
|
active Boolean @default(true)
|
|
|
|
equipment Equipment[]
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model Equipment {
|
|
id String @id @default(cuid())
|
|
name String
|
|
type EquipmentType
|
|
brand String?
|
|
model String?
|
|
serialNumber String? @unique
|
|
quantity Int @default(1)
|
|
status EquipmentStatus @default(AVAILABLE)
|
|
|
|
locationId String?
|
|
location Location? @relation(fields: [locationId], references: [id])
|
|
|
|
projectId String?
|
|
project Project? @relation(fields: [projectId], references: [id])
|
|
|
|
notes String?
|
|
purchaseDate DateTime?
|
|
purchasePrice Decimal?
|
|
|
|
minStockLevel Int?
|
|
currentStock Int?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
bookingEquipment BookingEquipment[]
|
|
|
|
@@index([type])
|
|
@@index([status])
|
|
@@index([locationId])
|
|
}
|
|
|
|
model BookingEquipment {
|
|
id String @id @default(cuid())
|
|
|
|
bookingId String
|
|
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade)
|
|
|
|
equipmentId String
|
|
equipment Equipment @relation(fields: [equipmentId], references: [id])
|
|
|
|
quantity Int @default(1)
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([bookingId, equipmentId])
|
|
@@index([bookingId])
|
|
@@index([equipmentId])
|
|
}
|
|
|
|
model DriverAvailability {
|
|
id String @id @default(cuid())
|
|
|
|
bookingId String
|
|
booking Booking @relation(fields: [bookingId], references: [id], onDelete: Cascade)
|
|
|
|
driverId String
|
|
driver User @relation(fields: [driverId], references: [id], onDelete: Cascade)
|
|
|
|
available Boolean @default(true)
|
|
message String? @db.Text
|
|
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([bookingId, driverId])
|
|
@@index([bookingId])
|
|
@@index([driverId])
|
|
}
|