mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 00:45:41 +00:00
Initial commit of edr-passenger-api alpha version
This commit is contained in:
573
apps/edr-passenger-api/prisma/schema.prisma
Normal file
573
apps/edr-passenger-api/prisma/schema.prisma
Normal file
@@ -0,0 +1,573 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum UserRole {
|
||||
PASSENGER
|
||||
ADMIN
|
||||
STAFF
|
||||
}
|
||||
|
||||
enum TripStatus {
|
||||
SCHEDULED
|
||||
BOARDING
|
||||
EN_ROUTE
|
||||
ARRIVED
|
||||
CANCELLED
|
||||
DELAYED
|
||||
}
|
||||
|
||||
enum SeatKind {
|
||||
STANDARD
|
||||
PREMIUM
|
||||
ACCESSIBLE
|
||||
}
|
||||
|
||||
enum SeatStatus {
|
||||
AVAILABLE
|
||||
HELD
|
||||
BOOKED
|
||||
BLOCKED
|
||||
}
|
||||
|
||||
enum ServiceClass {
|
||||
ECONOMY
|
||||
BUSINESS
|
||||
FIRST
|
||||
}
|
||||
|
||||
enum BookingStatus {
|
||||
DRAFT
|
||||
PENDING_PAYMENT
|
||||
CONFIRMED
|
||||
CANCELLED
|
||||
COMPLETED
|
||||
NO_SHOW
|
||||
}
|
||||
|
||||
enum PaymentMethodType {
|
||||
TELEBIRR
|
||||
CBE_BIRR
|
||||
EBIRR
|
||||
CARD
|
||||
WALLET
|
||||
}
|
||||
|
||||
enum PaymentIntentStatus {
|
||||
REQUIRES_ACTION
|
||||
PROCESSING
|
||||
SUCCEEDED
|
||||
FAILED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum WalletLedgerType {
|
||||
CREDIT
|
||||
DEBIT
|
||||
}
|
||||
|
||||
enum NotificationCategory {
|
||||
BOOKING
|
||||
PAYMENT
|
||||
DISRUPTION
|
||||
PROMOTION
|
||||
SYSTEM
|
||||
}
|
||||
|
||||
enum StopStatus {
|
||||
COMPLETED
|
||||
APPROACHING
|
||||
CURRENT
|
||||
UPCOMING
|
||||
}
|
||||
|
||||
enum SupportConversationStatus {
|
||||
OPEN
|
||||
RESOLVED
|
||||
CLOSED
|
||||
}
|
||||
|
||||
enum SupportSender {
|
||||
USER
|
||||
BOT
|
||||
AGENT
|
||||
}
|
||||
|
||||
enum LoyaltyTier {
|
||||
BRONZE
|
||||
SILVER
|
||||
GOLD
|
||||
PLATINUM
|
||||
}
|
||||
|
||||
enum LoyaltyLedgerReason {
|
||||
TRIP_COMPLETED
|
||||
REWARD_REDEEMED
|
||||
PROMO_BONUS
|
||||
MANUAL_ADJUSTMENT
|
||||
EXPIRY
|
||||
}
|
||||
|
||||
enum FoodOrderStatus {
|
||||
PENDING
|
||||
PREPARING
|
||||
READY
|
||||
DELIVERED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum DevicePlatform {
|
||||
IOS
|
||||
ANDROID
|
||||
WEB
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
email String @unique
|
||||
phone String @unique
|
||||
fullName String
|
||||
passwordHash String
|
||||
role UserRole @default(PASSENGER)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger?
|
||||
sessions Session[]
|
||||
devices Device[]
|
||||
preferences UserPreferences?
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
token String @unique
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model Passenger {
|
||||
id String @id @default(uuid())
|
||||
userId String @unique
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
bookings Booking[]
|
||||
loyalty LoyaltyAccount?
|
||||
wallet WalletAccount?
|
||||
notifications Notification[]
|
||||
travelerProfiles TravelerProfile[]
|
||||
savedRoutes SavedRoute[]
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model Station {
|
||||
id String @id @default(uuid())
|
||||
code String @unique
|
||||
name String
|
||||
city String
|
||||
timezone String @default("Africa/Addis_Ababa")
|
||||
lat Decimal @db.Decimal(9, 6)
|
||||
lng Decimal @db.Decimal(9, 6)
|
||||
originTrips Trip[] @relation("OriginTrips")
|
||||
destinationTrips Trip[] @relation("DestinationTrips")
|
||||
stopTimes TripStopTime[]
|
||||
crowdSignals StationCrowdSignal[]
|
||||
}
|
||||
|
||||
model TrainService {
|
||||
id String @id @default(uuid())
|
||||
number String @unique
|
||||
name String
|
||||
operatorId String @default("op_edr")
|
||||
trips Trip[]
|
||||
}
|
||||
|
||||
model Trip {
|
||||
id String @id @default(uuid())
|
||||
serviceId String
|
||||
originStationId String
|
||||
destinationStationId String
|
||||
departureAt DateTime
|
||||
arrivalAt DateTime
|
||||
durationMinutes Int
|
||||
status TripStatus @default(SCHEDULED)
|
||||
stopsCount Int @default(0)
|
||||
onTimePercent Int @default(100)
|
||||
carbonRating String @default("A")
|
||||
service TrainService @relation(fields: [serviceId], references: [id])
|
||||
originStation Station @relation("OriginTrips", fields: [originStationId], references: [id])
|
||||
destinationStation Station @relation("DestinationTrips", fields: [destinationStationId], references: [id])
|
||||
coaches Coach[]
|
||||
bookings Booking[]
|
||||
stopTimes TripStopTime[]
|
||||
liveStatus TripLiveStatus?
|
||||
menuItems MenuItem[]
|
||||
}
|
||||
|
||||
model TripStopTime {
|
||||
id String @id @default(uuid())
|
||||
tripId String
|
||||
stationId String
|
||||
sequence Int
|
||||
plannedArrivalAt DateTime?
|
||||
plannedDepartureAt DateTime?
|
||||
actualArrivalAt DateTime?
|
||||
status StopStatus @default(UPCOMING)
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
station Station @relation(fields: [stationId], references: [id])
|
||||
@@unique([tripId, sequence])
|
||||
}
|
||||
|
||||
model TripLiveStatus {
|
||||
id String @id @default(uuid())
|
||||
tripId String @unique
|
||||
state String
|
||||
currentLocationLabel String?
|
||||
progressPercent Int @default(0)
|
||||
delayMinutes Int @default(0)
|
||||
currentSpeedKph Int?
|
||||
platformLabel String?
|
||||
updatedAt DateTime @updatedAt
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
}
|
||||
|
||||
model Coach {
|
||||
id String @id @default(uuid())
|
||||
tripId String
|
||||
label String
|
||||
serviceClass ServiceClass
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
seats Seat[]
|
||||
@@unique([tripId, label])
|
||||
}
|
||||
|
||||
model Seat {
|
||||
id String @id @default(uuid())
|
||||
coachId String
|
||||
row Int
|
||||
col String
|
||||
label String
|
||||
kind SeatKind @default(STANDARD)
|
||||
status SeatStatus @default(AVAILABLE)
|
||||
heldUntil DateTime?
|
||||
coach Coach @relation(fields: [coachId], references: [id])
|
||||
bookingSeats BookingSeat[]
|
||||
@@unique([coachId, row, col])
|
||||
}
|
||||
|
||||
model SeatHold {
|
||||
id String @id @default(uuid())
|
||||
tripId String
|
||||
seatIds String[]
|
||||
fareQuoteId String?
|
||||
passengerId String
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model FareRule {
|
||||
id String @id @default(uuid())
|
||||
tripId String?
|
||||
route String?
|
||||
serviceClass ServiceClass
|
||||
baseFareMinor Int
|
||||
currency String @default("ETB")
|
||||
refundable Boolean @default(true)
|
||||
validFrom DateTime
|
||||
validUntil DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Booking {
|
||||
id String @id @default(uuid())
|
||||
bookingRef String @unique
|
||||
passengerId String
|
||||
tripId String
|
||||
status BookingStatus @default(DRAFT)
|
||||
currency String @default("ETB")
|
||||
totalMinor Int
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger @relation(fields: [passengerId], references: [id])
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
seats BookingSeat[]
|
||||
paymentIntent PaymentIntent?
|
||||
ticket Ticket?
|
||||
foodOrders FoodOrder[]
|
||||
}
|
||||
|
||||
model BookingSeat {
|
||||
id String @id @default(uuid())
|
||||
bookingId String
|
||||
seatId String
|
||||
passengerName String
|
||||
idDocumentType String?
|
||||
idDocumentNumber String?
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
seat Seat @relation(fields: [seatId], references: [id])
|
||||
}
|
||||
|
||||
model PaymentMethod {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
type PaymentMethodType
|
||||
displayName String
|
||||
maskedHint String?
|
||||
isDefault Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model PaymentIntent {
|
||||
id String @id @default(uuid())
|
||||
bookingId String @unique
|
||||
amountMinor Int
|
||||
currency String @default("ETB")
|
||||
method PaymentMethodType
|
||||
status PaymentIntentStatus @default(REQUIRES_ACTION)
|
||||
providerRef String?
|
||||
clientAction Json?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
}
|
||||
|
||||
model Ticket {
|
||||
id String @id @default(uuid())
|
||||
bookingId String @unique
|
||||
bookingRef String
|
||||
status String @default("CONFIRMED")
|
||||
qrPayload String
|
||||
issuedAt DateTime @default(now())
|
||||
validatedAt DateTime?
|
||||
validatorId String?
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
}
|
||||
|
||||
model LoyaltyAccount {
|
||||
id String @id @default(uuid())
|
||||
passengerId String @unique
|
||||
pointsBalance Int @default(0)
|
||||
tier LoyaltyTier @default(BRONZE)
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger @relation(fields: [passengerId], references: [id])
|
||||
ledger LoyaltyLedgerEntry[]
|
||||
rewards LoyaltyReward[]
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model WalletAccount {
|
||||
id String @id @default(uuid())
|
||||
passengerId String @unique
|
||||
balanceMinor Int @default(0)
|
||||
currency String @default("ETB")
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger @relation(fields: [passengerId], references: [id])
|
||||
ledger WalletLedgerEntry[]
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
model StationCrowdSignal {
|
||||
id String @id @default(uuid())
|
||||
stationId String
|
||||
level String
|
||||
label String
|
||||
statusLabel String
|
||||
updatedAt DateTime @updatedAt
|
||||
station Station @relation(fields: [stationId], references: [id])
|
||||
}
|
||||
|
||||
model WeatherAlert {
|
||||
id String @id @default(uuid())
|
||||
region String
|
||||
severity String
|
||||
title String
|
||||
message String
|
||||
validUntil DateTime
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model MenuCategory {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
items MenuItem[]
|
||||
}
|
||||
|
||||
model MenuItem {
|
||||
id String @id @default(uuid())
|
||||
tripId String
|
||||
categoryId String
|
||||
name String
|
||||
priceMinor Int
|
||||
currency String @default("ETB")
|
||||
available Boolean @default(true)
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
category MenuCategory @relation(fields: [categoryId], references: [id])
|
||||
}
|
||||
|
||||
model FoodOrder {
|
||||
id String @id @default(uuid())
|
||||
bookingId String
|
||||
status FoodOrderStatus @default(PENDING)
|
||||
totalMinor Int
|
||||
currency String @default("ETB")
|
||||
createdAt DateTime @default(now())
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
items FoodOrderItem[]
|
||||
}
|
||||
|
||||
model FoodOrderItem {
|
||||
id String @id @default(uuid())
|
||||
orderId String
|
||||
menuItemId String
|
||||
name String
|
||||
quantity Int
|
||||
lineTotalMinor Int
|
||||
order FoodOrder @relation(fields: [orderId], references: [id])
|
||||
}
|
||||
|
||||
model FaqCategory {
|
||||
id String @id @default(uuid())
|
||||
title String
|
||||
iconKey String?
|
||||
articles FaqArticle[]
|
||||
}
|
||||
|
||||
model FaqArticle {
|
||||
id String @id @default(uuid())
|
||||
categoryId String
|
||||
question String
|
||||
answerMarkdown String
|
||||
rank Int @default(0)
|
||||
category FaqCategory @relation(fields: [categoryId], references: [id])
|
||||
}
|
||||
|
||||
model SupportConversation {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
status SupportConversationStatus @default(OPEN)
|
||||
createdAt DateTime @default(now())
|
||||
messages SupportMessage[]
|
||||
}
|
||||
|
||||
model SupportMessage {
|
||||
id String @id @default(uuid())
|
||||
conversationId String
|
||||
sender SupportSender
|
||||
text String
|
||||
createdAt DateTime @default(now())
|
||||
conversation SupportConversation @relation(fields: [conversationId], references: [id])
|
||||
}
|
||||
|
||||
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)
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
Reference in New Issue
Block a user