// VIP Coordinator - Prisma Schema // This is your database schema (source of truth) generator client { provider = "prisma-client-js" binaryTargets = ["native", "linux-musl-openssl-3.0.x"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // ============================================ // User Management // ============================================ model User { id String @id @default(uuid()) auth0Id String @unique // Auth0 sub claim email String @unique name String? picture String? role Role @default(COORDINATOR) isApproved Boolean @default(false) driver Driver? // Optional linked driver account createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete @@map("users") } enum Role { ADMINISTRATOR COORDINATOR DRIVER } // ============================================ // VIP Management // ============================================ model VIP { id String @id @default(uuid()) name String organization String? department Department arrivalMode ArrivalMode expectedArrival DateTime? // For self-driving arrivals airportPickup Boolean @default(false) venueTransport Boolean @default(false) notes String? @db.Text flights Flight[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete @@map("vips") } enum Department { OFFICE_OF_DEVELOPMENT ADMIN } enum ArrivalMode { FLIGHT SELF_DRIVING } // ============================================ // Flight Tracking // ============================================ model Flight { id String @id @default(uuid()) vipId String vip VIP @relation(fields: [vipId], references: [id], onDelete: Cascade) flightNumber String flightDate DateTime segment Int @default(1) // For multi-segment itineraries departureAirport String // IATA code (e.g., "JFK") arrivalAirport String // IATA code (e.g., "LAX") scheduledDeparture DateTime? scheduledArrival DateTime? actualDeparture DateTime? actualArrival DateTime? status String? // scheduled, delayed, landed, etc. createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("flights") @@index([vipId]) @@index([flightNumber, flightDate]) } // ============================================ // Driver Management // ============================================ model Driver { id String @id @default(uuid()) name String phone String? // Optional - driver should add via profile department Department? userId String? @unique user User? @relation(fields: [userId], references: [id]) // Shift/Availability shiftStartTime DateTime? // When driver's shift starts shiftEndTime DateTime? // When driver's shift ends isAvailable Boolean @default(true) events ScheduleEvent[] assignedVehicle Vehicle? @relation("AssignedDriver") messages SignalMessage[] // Signal chat messages createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete @@map("drivers") } // ============================================ // Vehicle Management // ============================================ model Vehicle { id String @id @default(uuid()) name String // "Blue Van", "Suburban #3" type VehicleType @default(VAN) licensePlate String? seatCapacity Int // Total seats (e.g., 8) status VehicleStatus @default(AVAILABLE) // Current assignment currentDriverId String? @unique currentDriver Driver? @relation("AssignedDriver", fields: [currentDriverId], references: [id]) // Relationships events ScheduleEvent[] notes String? @db.Text createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete @@map("vehicles") } enum VehicleType { VAN // 7-15 seats SUV // 5-8 seats SEDAN // 4-5 seats BUS // 15+ seats GOLF_CART // 2-6 seats TRUCK // For equipment/supplies } enum VehicleStatus { AVAILABLE // Ready to use IN_USE // Currently on a trip MAINTENANCE // Out of service RESERVED // Scheduled for upcoming trip } // ============================================ // Schedule & Event Management // ============================================ model ScheduleEvent { id String @id @default(uuid()) vipIds String[] // Array of VIP IDs for multi-passenger trips title String // Location details pickupLocation String? dropoffLocation String? location String? // For non-transport events // Timing startTime DateTime endTime DateTime actualStartTime DateTime? actualEndTime DateTime? description String? @db.Text type EventType @default(TRANSPORT) status EventStatus @default(SCHEDULED) // Assignments driverId String? driver Driver? @relation(fields: [driverId], references: [id], onDelete: SetNull) vehicleId String? vehicle Vehicle? @relation(fields: [vehicleId], references: [id], onDelete: SetNull) // Metadata notes String? @db.Text // Reminder tracking reminder20MinSent Boolean @default(false) reminder5MinSent Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete @@map("schedule_events") @@index([driverId]) @@index([vehicleId]) @@index([startTime, endTime]) @@index([status]) } enum EventType { TRANSPORT MEETING EVENT MEAL ACCOMMODATION } enum EventStatus { SCHEDULED IN_PROGRESS COMPLETED CANCELLED } // ============================================ // Signal Messaging // ============================================ model SignalMessage { id String @id @default(uuid()) driverId String driver Driver @relation(fields: [driverId], references: [id], onDelete: Cascade) direction MessageDirection content String @db.Text timestamp DateTime @default(now()) isRead Boolean @default(false) signalTimestamp String? // Signal's message timestamp for deduplication @@map("signal_messages") @@index([driverId]) @@index([driverId, isRead]) @@index([timestamp]) } enum MessageDirection { INBOUND // Message from driver OUTBOUND // Message to driver } // ============================================ // PDF Settings (Singleton) // ============================================ model PdfSettings { id String @id @default(uuid()) // Branding organizationName String @default("VIP Coordinator") logoUrl String? @db.Text // Base64 data URL or external URL accentColor String @default("#2c3e50") // Hex color tagline String? // Contact Info contactEmail String @default("contact@example.com") contactPhone String @default("555-0100") secondaryContactName String? secondaryContactPhone String? contactLabel String @default("Questions or Changes?") // Document Options showDraftWatermark Boolean @default(false) showConfidentialWatermark Boolean @default(false) showTimestamp Boolean @default(true) showAppUrl Boolean @default(false) pageSize PageSize @default(LETTER) // Content Toggles showFlightInfo Boolean @default(true) showDriverNames Boolean @default(true) showVehicleNames Boolean @default(true) showVipNotes Boolean @default(true) showEventDescriptions Boolean @default(true) // Custom Text headerMessage String? @db.Text footerMessage String? @db.Text createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("pdf_settings") } enum PageSize { LETTER A4 }