generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") schemas = ["passenger"] } enum UserRole { PASSENGER AGENT SUPERVISOR ADMIN STAFF @@schema("passenger") } enum TripStatus { SCHEDULED BOARDING EN_ROUTE ARRIVED CANCELLED DELAYED @@schema("passenger") } enum SeatKind { STANDARD PREMIUM ACCESSIBLE @@schema("passenger") } enum SeatStatus { AVAILABLE HELD BOOKED BLOCKED @@schema("passenger") } enum PassengerCategory { ADULT CHILD @@schema("passenger") } enum IdDocumentType { NATIONAL_ID PASSPORT DRIVING_LICENSE OTHER @@schema("passenger") } enum Currency { ETB DJF USD @@schema("passenger") } model SeatClass { id String @id @default(uuid()) name String @unique description String? basePrice Int isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt coaches Coach[] fareRules FareRule[] routeFareRules RouteFareRule[] @@schema("passenger") } enum BookingStatus { DRAFT PENDING_PAYMENT CONFIRMED CANCELLED COMPLETED NO_SHOW REFUNDED @@schema("passenger") } enum PaymentRegion { ETHIOPIA DJIBOUTI INTERNATIONAL GLOBAL @@schema("passenger") } enum PaymentMethodType { TELEBIRR CBE_BIRR EBIRR CARD WALLET WAAFI @@schema("passenger") } enum PaymentIntentStatus { REQUIRES_ACTION PROCESSING SUCCEEDED FAILED CANCELLED REFUNDED @@schema("passenger") } enum WalletLedgerType { CREDIT DEBIT @@schema("passenger") } enum NotificationCategory { BOOKING PAYMENT DISRUPTION PROMOTION SYSTEM @@schema("passenger") } enum StopStatus { COMPLETED APPROACHING CURRENT UPCOMING @@schema("passenger") } enum SupportConversationStatus { OPEN RESOLVED CLOSED @@schema("passenger") } enum SupportSender { USER BOT AGENT @@schema("passenger") } enum LoyaltyTier { BRONZE SILVER GOLD PLATINUM @@schema("passenger") } enum LoyaltyLedgerReason { TRIP_COMPLETED REWARD_REDEEMED PROMO_BONUS MANUAL_ADJUSTMENT EXPIRY @@schema("passenger") } enum FoodOrderStatus { PENDING PREPARING READY DELIVERED CANCELLED @@schema("passenger") } enum DevicePlatform { IOS ANDROID WEB @@schema("passenger") } model User { id String @id @default(uuid()) email String @unique phone String @unique fullName String passwordHash String role UserRole @default(PASSENGER) nationality String? nationalityCode String? passportNumber String? nationalId String? failedLoginAttempts Int @default(0) lockedUntil DateTime? blockedUntil DateTime? lastLoginAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt faydaVerified Boolean @default(false) faydaVerifiedAt DateTime? faydaSub String? @unique passenger Passenger? agent Agent? sessions Session[] devices Device[] preferences UserPreferences? auditLogs AuditLog[] fraudAlerts FraudAlert[] faydaVerificationSessions FaydaVerificationSession[] @@schema("passenger") } model Session { id String @id @default(uuid()) userId String token String @unique expiresAt DateTime ipAddress String? userAgent String? lastActivityAt DateTime @default(now()) createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@schema("passenger") } model Passenger { id String @id @default(uuid()) userId String @unique defaultTravelerProfileId String? preferredLanguage String? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) bookings Booking[] loyalty LoyaltyAccount? wallet WalletAccount? notifications Notification[] travelerProfiles TravelerProfile[] savedRoutes SavedRoute[] @@index([userId]) @@schema("passenger") } model TravelerProfile { id String @id @default(uuid()) passengerId String fullName String relationship String dateOfBirth DateTime? nationalId String? notes String? createdAt DateTime @default(now()) passenger Passenger @relation(fields: [passengerId], references: [id]) @@schema("passenger") } model Station { id String @id @default(uuid()) code String @unique name String city String countryCode String? isOperational Boolean @default(true) timezone String @default("Africa/Addis_Ababa") lat Decimal @db.Decimal(9, 6) lng Decimal @db.Decimal(9, 6) originSchedules TrainSchedule[] @relation("OriginTrips") destinationSchedules TrainSchedule[] @relation("DestinationTrips") stopTimes TripStopTime[] crowdSignals StationCrowdSignal[] @@index([city, countryCode]) @@schema("passenger") } model Train { id String @id @default(uuid()) number String @unique name String operatorId String @default("op_edr") operatorName String? description String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt schedules TrainSchedule[] @@schema("passenger") } model TrainSchedule { id String @id @default(uuid()) trainId String routeId String? originStationId String destinationStationId String departureAt DateTime arrivalAt DateTime durationMinutes Int status TripStatus @default(SCHEDULED) stopsCount Int @default(0) reservedCount Int @default(0) onTimePercent Int @default(100) carbonRating String @default("A") notes String? train Train @relation(fields: [trainId], references: [id]) route Route? @relation(fields: [routeId], references: [id]) originStation Station @relation("OriginTrips", fields: [originStationId], references: [id]) destinationStation Station @relation("DestinationTrips", fields: [destinationStationId], references: [id]) coachAssignments CoachAssignment[] bookings Booking[] stopTimes TripStopTime[] liveStatus TripLiveStatus? menuItems MenuItem[] journeySegments JourneySegment[] @@index([departureAt, originStationId]) @@schema("passenger") } model TripStopTime { id String @id @default(uuid()) scheduleId String stationId String sequence Int plannedArrivalAt DateTime? plannedDepartureAt DateTime? actualArrivalAt DateTime? status StopStatus @default(UPCOMING) schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) station Station @relation(fields: [stationId], references: [id]) @@unique([scheduleId, sequence]) @@schema("passenger") } model TripLiveStatus { id String @id @default(uuid()) scheduleId String @unique state String currentLocationLabel String? progressPercent Int @default(0) delayMinutes Int @default(0) currentSpeedKph Int? platformLabel String? updatedAt DateTime @updatedAt schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) @@schema("passenger") } model Coach { id String @id @default(uuid()) coachNumber String @unique label String seatClassId String coachType String? mode String @default("seat") // 'seat', 'bed', 'convertible' seatArrangement String? bedArrangement String? amenities Json? totalUnits Int @default(0) isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt seatClass SeatClass @relation(fields: [seatClassId], references: [id]) seats Seat[] assignments CoachAssignment[] @@schema("passenger") } model CoachAssignment { id String @id @default(uuid()) scheduleId String coachId String positionNumber Int isOperational Boolean @default(true) createdAt DateTime @default(now()) schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) coach Coach @relation(fields: [coachId], references: [id]) @@unique([scheduleId, positionNumber]) @@index([scheduleId]) @@schema("passenger") } model Seat { id String @id @default(uuid()) coachId String row Int col String label String seatNumber String? kind SeatKind @default(STANDARD) status SeatStatus @default(AVAILABLE) heldUntil DateTime? isWindow Boolean @default(false) isAisle Boolean @default(false) bedPosition String? // 'lower', 'middle', 'upper' premiumFeeMinor Int @default(0) eligibility String? coach Coach @relation(fields: [coachId], references: [id]) bookingSeats BookingSeat[] blocks SeatBlock[] @@unique([coachId, row, col]) @@unique([coachId, seatNumber]) @@schema("passenger") } model SeatHold { id String @id @default(uuid()) scheduleId String seatIds String[] fareQuoteId String? passengerId String createdBy String? expiresAt DateTime createdAt DateTime @default(now()) @@index([expiresAt]) @@schema("passenger") } model FareRule { id String @id @default(uuid()) tripId String? route String? nationality String? // Ethiopian, Djiboutian, Other seatClassId String baseFareMinor Int seatClass SeatClass @relation(fields: [seatClassId], references: [id]) currency String @default("ETB") refundable Boolean @default(true) validFrom DateTime validUntil DateTime? createdAt DateTime @default(now()) @@schema("passenger") } model Booking { id String @id @default(uuid()) bookingRef String @unique passengerId String scheduleId String status BookingStatus @default(DRAFT) currency String @default("ETB") totalMinor Int adultCount Int @default(1) childCount Int @default(0) displayCurrency Currency? displayTotalMinor Int? bookingType String @default("ONE_WAY") contactEmail String? contactPhone String? userAgent String? source String @default("WEB") promoCode String? paidAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt passenger Passenger @relation(fields: [passengerId], references: [id]) schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) seats BookingSeat[] paymentIntent PaymentIntent? ticket Ticket? foodOrders FoodOrder[] agentBooking AgentBooking? modifications BookingModification[] cancellation BookingCancellation? baggage BaggageBooking[] @@index([passengerId, status]) @@schema("passenger") } model BookingSeat { id String @id @default(uuid()) bookingId String seatId String passengerName String dateOfBirth DateTime? passengerCategory PassengerCategory @default(ADULT) idDocumentType IdDocumentType? idDocumentNumber String? passportNumber String? passportCountry String? verifaydaVerified Boolean @default(false) verifaydaData Json? faydaVerifiedAt DateTime? faydaSub String? faydaVerifiedName String? seatLabelSnapshot String? fareMinor Int? displayCurrency Currency? displayFareMinor Int? booking Booking @relation(fields: [bookingId], references: [id]) seat Seat @relation(fields: [seatId], references: [id]) @@schema("passenger") } model PaymentMethod { id String @id @default(uuid()) type PaymentMethodType @unique displayName String region PaymentRegion @default(GLOBAL) currency String @default("ETB") providerId String? isDefault Boolean @default(false) enabled Boolean @default(true) sortOrder Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@schema("passenger") } model PaymentIntent { id String @id @default(uuid()) bookingId String @unique amountMinor Int currency String @default("ETB") method PaymentMethodType provider String? status PaymentIntentStatus @default(REQUIRES_ACTION) providerRef String? clientAction Json? merchantOrderId String? @unique providerOrderId String? providerTxnId String? rawInitiation Json? paidAt DateTime? refundedAt DateTime? captureMethod String? failureCode String? failureMessage String? expiresAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt booking Booking @relation(fields: [bookingId], references: [id]) refunds PaymentRefund[] @@index([providerOrderId]) @@index([providerTxnId]) @@schema("passenger") } model PaymentWebhookEvent { id String @id @default(uuid()) provider PaymentMethodType externalEventId String merchantOrderId String? providerTxnId String? signatureValid Boolean status String payload Json receivedAt DateTime @default(now()) processedAt DateTime? processingError String? @@unique([provider, externalEventId]) @@index([merchantOrderId]) @@schema("passenger") } model PaymentRefund { id String @id @default(uuid()) paymentIntentId String amountMinor Int reason String? providerRefundId String? status String createdAt DateTime @default(now()) paymentIntent PaymentIntent @relation(fields: [paymentIntentId], references: [id]) @@schema("passenger") } model Ticket { id String @id @default(uuid()) bookingId String @unique bookingRef String status String @default("CONFIRMED") qrPayload String barcodePayload String? pdfUrl String? deliveryChannel String @default("EMAIL") issuedAt DateTime @default(now()) validatedAt DateTime? validatorId String? booking Booking @relation(fields: [bookingId], references: [id]) validationLogs GateValidationLog[] @@schema("passenger") } model LoyaltyAccount { id String @id @default(uuid()) passengerId String @unique pointsBalance Int @default(0) lifetimePoints Int @default(0) tier LoyaltyTier @default(BRONZE) tierUpdatedAt DateTime? updatedAt DateTime @updatedAt passenger Passenger @relation(fields: [passengerId], references: [id]) ledger LoyaltyLedgerEntry[] rewards LoyaltyReward[] @@schema("passenger") } model LoyaltyLedgerEntry { id String @id @default(uuid()) accountId String delta Int reason LoyaltyLedgerReason bookingId String? balanceAfter Int createdAt DateTime @default(now()) account LoyaltyAccount @relation(fields: [accountId], references: [id]) @@schema("passenger") } model LoyaltyReward { id String @id @default(uuid()) accountId String title String costPoints Int available Boolean @default(true) description String? account LoyaltyAccount @relation(fields: [accountId], references: [id]) @@schema("passenger") } model WalletAccount { id String @id @default(uuid()) passengerId String @unique balanceMinor Int @default(0) status String @default("ACTIVE") holdMinor Int @default(0) currency String @default("ETB") updatedAt DateTime @updatedAt passenger Passenger @relation(fields: [passengerId], references: [id]) ledger WalletLedgerEntry[] @@index([passengerId]) @@schema("passenger") } model WalletLedgerEntry { id String @id @default(uuid()) walletId String type WalletLedgerType amountMinor Int balanceAfterMinor Int description String relatedBookingId String? createdAt DateTime @default(now()) wallet WalletAccount @relation(fields: [walletId], references: [id]) @@schema("passenger") } model Notification { id String @id @default(uuid()) passengerId String title String body String category NotificationCategory read Boolean @default(false) deepLink String? metadata Json? createdAt DateTime @default(now()) passenger Passenger @relation(fields: [passengerId], references: [id]) @@schema("passenger") } model Promotion { id String @id @default(uuid()) title String subtitle String? code String @unique percentOff Int? amountOffMinor Int? validUntil DateTime ctaLabel String? deepLink String? active Boolean @default(true) createdAt DateTime @default(now()) @@schema("passenger") } model StationCrowdSignal { id String @id @default(uuid()) stationId String level String label String statusLabel String confidence Int? observedAt DateTime? updatedAt DateTime @updatedAt station Station @relation(fields: [stationId], references: [id]) @@schema("passenger") } model WeatherAlert { id String @id @default(uuid()) region String severity String title String message String validUntil DateTime createdAt DateTime @default(now()) @@schema("passenger") } model MenuCategory { id String @id @default(uuid()) name String items MenuItem[] @@schema("passenger") } model MenuItem { id String @id @default(uuid()) scheduleId String categoryId String name String priceMinor Int currency String @default("ETB") available Boolean @default(true) availableUntil DateTime? schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) category MenuCategory @relation(fields: [categoryId], references: [id]) @@schema("passenger") } model FoodOrder { id String @id @default(uuid()) bookingId String status FoodOrderStatus @default(PENDING) totalMinor Int currency String @default("ETB") specialInstructions String? estimatedReadyAt DateTime? createdAt DateTime @default(now()) booking Booking @relation(fields: [bookingId], references: [id]) items FoodOrderItem[] @@schema("passenger") } model FoodOrderItem { id String @id @default(uuid()) orderId String menuItemId String name String quantity Int unitPriceMinor Int? lineTotalMinor Int order FoodOrder @relation(fields: [orderId], references: [id]) @@schema("passenger") } model FaqCategory { id String @id @default(uuid()) title String iconKey String? articles FaqArticle[] @@schema("passenger") } model FaqArticle { id String @id @default(uuid()) categoryId String question String answerMarkdown String rank Int @default(0) category FaqCategory @relation(fields: [categoryId], references: [id]) @@schema("passenger") } model SupportConversation { id String @id @default(uuid()) userId String assignedAgentId String? status SupportConversationStatus @default(OPEN) createdAt DateTime @default(now()) messages SupportMessage[] @@schema("passenger") } model SupportMessage { id String @id @default(uuid()) conversationId String sender SupportSender text String attachments Json? createdAt DateTime @default(now()) conversation SupportConversation @relation(fields: [conversationId], references: [id]) @@schema("passenger") } model UserPreferences { id String @id @default(uuid()) userId String @unique pushEnabled Boolean @default(true) emailEnabled Boolean @default(true) smsEnabled Boolean @default(false) promosEnabled Boolean @default(true) biometricEnabled Boolean @default(false) twoFactorEnabled Boolean @default(false) defaultPaymentMethodId String? autoDownloadTickets Boolean @default(true) dataSharing Boolean @default(false) locale String @default("en") darkMode Boolean @default(false) language String @default("en") user User @relation(fields: [userId], references: [id]) @@schema("passenger") } model Device { id String @id @default(uuid()) userId String platform DevicePlatform name String pushToken String? trusted Boolean @default(false) lastSeenAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) @@schema("passenger") } model SavedRoute { id String @id @default(uuid()) passengerId String fromStationId String toStationId String fromName String toName String tripCount Int @default(0) createdAt DateTime @default(now()) passenger Passenger @relation(fields: [passengerId], references: [id]) @@schema("passenger") } model Journey { id String @id @default(uuid()) passengerId String status String totalMinor Int currency String @default("ETB") createdAt DateTime @default(now()) journeySegments JourneySegment[] @@schema("passenger") } model JourneySegment { id String @id @default(uuid()) journeyId String scheduleId String segmentOrder Int seatId String? coachId String? departureStationId String arrivalStationId String journey Journey @relation(fields: [journeyId], references: [id]) schedule TrainSchedule @relation(fields: [scheduleId], references: [id]) @@schema("passenger") } model OtpCode { id String @id @default(uuid()) userId String? email String? phone String? code String purpose String expiresAt DateTime verified Boolean @default(false) createdAt DateTime @default(now()) @@index([email, phone]) @@schema("passenger") } model PasswordResetToken { id String @id @default(uuid()) userId String token String @unique expiresAt DateTime used Boolean @default(false) createdAt DateTime @default(now()) @@index([userId]) @@schema("passenger") } model Route { id String @id @default(uuid()) code String @unique name String description String? effectiveFrom DateTime effectiveUntil DateTime? active Boolean @default(true) createdAt DateTime @default(now()) stops RouteStop[] fareRules RouteFareRule[] schedules TrainSchedule[] @@schema("passenger") } model RouteStop { id String @id @default(uuid()) routeId String stationId String sequence Int distanceKm Int? createdAt DateTime @default(now()) route Route @relation(fields: [routeId], references: [id], onDelete: Cascade) @@unique([routeId, sequence]) @@index([routeId, stationId]) @@schema("passenger") } model RouteFareRule { id String @id @default(uuid()) routeId String seatClassId String passengerCategory PassengerCategory @default(ADULT) baseFareMinor Int discountPercent Int? taxPercent Int? surchargeMinor Int? currency String @default("ETB") validFrom DateTime validUntil DateTime? createdAt DateTime @default(now()) route Route @relation(fields: [routeId], references: [id], onDelete: Cascade) seatClass SeatClass @relation(fields: [seatClassId], references: [id]) @@index([routeId, seatClassId]) @@schema("passenger") } model Agent { id String @id @default(uuid()) userId String @unique agentCode String @unique stationId String? commissionRate Int @default(5) active Boolean @default(true) createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id]) bookings AgentBooking[] shifts AgentShift[] commissions AgentCommission[] @@schema("passenger") } model AgentBooking { id String @id @default(uuid()) agentId String bookingId String @unique paymentMethod String cashReceived Int? changeGiven Int? paperTicket Boolean @default(false) createdAt DateTime @default(now()) agent Agent @relation(fields: [agentId], references: [id]) booking Booking @relation(fields: [bookingId], references: [id]) @@schema("passenger") } model AgentShift { id String @id @default(uuid()) agentId String openedAt DateTime @default(now()) closedAt DateTime? openingBalance Int @default(0) closingBalance Int? reconciled Boolean @default(false) notes String? agent Agent @relation(fields: [agentId], references: [id]) @@index([agentId, openedAt]) @@schema("passenger") } model AgentCommission { id String @id @default(uuid()) agentId String bookingId String amountMinor Int rate Int paidAt DateTime? createdAt DateTime @default(now()) agent Agent @relation(fields: [agentId], references: [id]) @@index([agentId, paidAt]) @@schema("passenger") } model BookingModification { id String @id @default(uuid()) bookingId String modifiedBy String modificationType String oldData Json newData Json fareAdjustment Int @default(0) reason String? createdAt DateTime @default(now()) booking Booking @relation(fields: [bookingId], references: [id]) @@index([bookingId]) @@schema("passenger") } model BookingCancellation { id String @id @default(uuid()) bookingId String @unique cancelledBy String reason String? refundAmount Int refundMethod String refundStatus String processedAt DateTime? createdAt DateTime @default(now()) booking Booking @relation(fields: [bookingId], references: [id]) @@schema("passenger") } model GateValidationLog { id String @id @default(uuid()) ticketId String validatorId String gateId String? status String reason String? validatedAt DateTime @default(now()) ticket Ticket @relation(fields: [ticketId], references: [id]) @@index([ticketId]) @@index([validatorId]) @@schema("passenger") } model BaggageAllowance { id String @id @default(uuid()) seatClassId String maxWeightKg Int maxPiecesCount Int excessFeePerKg Int currency String @default("ETB") createdAt DateTime @default(now()) @@schema("passenger") } model BaggageBooking { id String @id @default(uuid()) bookingId String weightKg Int piecesCount Int excessFeeMinor Int @default(0) paid Boolean @default(false) createdAt DateTime @default(now()) booking Booking @relation(fields: [bookingId], references: [id]) @@index([bookingId]) @@schema("passenger") } model AuditLog { id String @id @default(uuid()) userId String? action String entityType String entityId String? oldData Json? newData Json? ipAddress String? userAgent String? createdAt DateTime @default(now()) user User? @relation(fields: [userId], references: [id]) @@index([userId, createdAt]) @@index([entityType, entityId]) @@schema("passenger") } model NotificationTemplate { id String @id @default(uuid()) code String @unique channel String subject String? bodyTemplate String active Boolean @default(true) createdAt DateTime @default(now()) @@schema("passenger") } model SeatBlock { id String @id @default(uuid()) seatId String reason String blockedBy String approvedBy String? blockedAt DateTime @default(now()) unblockAt DateTime? seat Seat @relation(fields: [seatId], references: [id]) @@index([seatId]) @@schema("passenger") } model OperationalReport { id String @id @default(uuid()) reportType String dateFrom DateTime dateTo DateTime data Json generatedBy String? createdAt DateTime @default(now()) @@index([reportType, dateFrom]) @@schema("passenger") } model FraudRule { id String @id @default(uuid()) type String @unique enabled Boolean @default(true) threshold Float config Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@schema("passenger") } model FraudAlert { id String @id @default(uuid()) userId String eventType String triggeredRules String[] context Json severity String @default("MEDIUM") acknowledged Boolean @default(false) createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId, createdAt]) @@index([acknowledged]) @@schema("passenger") } model CurrencyExchangeRate { id String @id @default(uuid()) fromCurrency Currency toCurrency Currency rate Decimal @db.Decimal(18, 6) effectiveDate DateTime @default(now()) source String @default("MANUAL") createdAt DateTime @default(now()) @@unique([fromCurrency, toCurrency, effectiveDate]) @@index([fromCurrency, toCurrency]) @@schema("passenger") } model VerifaydaVerification { id String @id @default(uuid()) bookingId String? nationalId String requestPayload Json responsePayload Json? verified Boolean @default(false) failureReason String? verifiedAt DateTime? createdAt DateTime @default(now()) @@index([nationalId]) @@index([bookingId]) @@schema("passenger") } model SavedPassengerProfile { id String @id @default(uuid()) userId String? deviceId String? passengerName String dateOfBirth DateTime idDocumentType IdDocumentType passportNumber String? passportCountry String? nationality String? phone String? email String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([deviceId]) @@schema("passenger") } model FaydaVerificationSession { id String @id @default(uuid()) state String @unique codeVerifier String purpose String @default("PURCHASE") platform String @default("WEB") // WEB | MOBILE — recorded for audit saveToAccount Boolean @default(false) status String @default("PENDING") errorCode String? errorDescription String? authCode String? createdAt DateTime @default(now()) expiresAt DateTime completedAt DateTime? userId String? bookingId String? user User? @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([bookingId]) @@index([state]) @@index([expiresAt]) @@schema("passenger") }