Implemened verifayda and currency modules

This commit is contained in:
Stephanos A
2026-05-21 10:22:08 +03:00
parent 51bc906792
commit 3f60836e5d
22 changed files with 1032 additions and 220 deletions

View File

@@ -46,6 +46,24 @@ enum ServiceClass {
VIP_BED_UPPER
}
enum PassengerCategory {
ADULT
CHILD
}
enum IdDocumentType {
NATIONAL_ID
PASSPORT
DRIVING_LICENSE
OTHER
}
enum Currency {
ETB
DJF
USD
}
enum BookingStatus {
DRAFT
PENDING_PAYMENT
@@ -142,11 +160,13 @@ model User {
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
passenger Passenger?
@@ -173,6 +193,8 @@ model Session {
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[]
@@ -181,6 +203,7 @@ model Passenger {
notifications Notification[]
travelerProfiles TravelerProfile[]
savedRoutes SavedRoute[]
@@index([userId])
}
model TravelerProfile {
@@ -200,6 +223,8 @@ model Station {
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)
@@ -207,6 +232,7 @@ model Station {
destinationTrips Trip[] @relation("DestinationTrips")
stopTimes TripStopTime[]
crowdSignals StationCrowdSignal[]
@@index([city, countryCode])
}
model TrainService {
@@ -214,12 +240,14 @@ model TrainService {
number String @unique
name String
operatorId String @default("op_edr")
operatorName String?
trips Trip[]
}
model Trip {
id String @id @default(uuid())
serviceId String
routeId String?
originStationId String
destinationStationId String
departureAt DateTime
@@ -227,8 +255,10 @@ model Trip {
durationMinutes Int
status TripStatus @default(SCHEDULED)
stopsCount Int @default(0)
reservedCount Int @default(0)
onTimePercent Int @default(100)
carbonRating String @default("A")
notes String?
service TrainService @relation(fields: [serviceId], references: [id])
originStation Station @relation("OriginTrips", fields: [originStationId], references: [id])
destinationStation Station @relation("DestinationTrips", fields: [destinationStationId], references: [id])
@@ -238,6 +268,7 @@ model Trip {
liveStatus TripLiveStatus?
menuItems MenuItem[]
journeySegments JourneySegment[]
@@index([departureAt, originStationId])
}
model TripStopTime {
@@ -272,6 +303,10 @@ model Coach {
tripId String
label String
serviceClass ServiceClass
capacity Int?
sequence Int?
coachType String?
amenities Json?
trip Trip @relation(fields: [tripId], references: [id])
seats Seat[]
@@unique([tripId, label])
@@ -283,15 +318,19 @@ model Seat {
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)
premiumFeeMinor Int @default(0)
eligibility String?
coach Coach @relation(fields: [coachId], references: [id])
bookingSeats BookingSeat[]
blocks SeatBlock[]
@@unique([coachId, row, col])
@@unique([coachId, seatNumber])
}
model SeatHold {
@@ -300,8 +339,10 @@ model SeatHold {
seatIds String[]
fareQuoteId String?
passengerId String
createdBy String?
expiresAt DateTime
createdAt DateTime @default(now())
@@index([expiresAt])
}
model FareRule {
@@ -318,16 +359,24 @@ model FareRule {
}
model Booking {
id String @id @default(uuid())
bookingRef String @unique
passengerId String
tripId String
status BookingStatus @default(DRAFT)
currency String @default("ETB")
totalMinor Int
bookingType String @default("ONE_WAY")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(uuid())
bookingRef String @unique
passengerId String
tripId 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")
userAgent String?
source String @default("WEB")
promoCode String?
paidAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
passenger Passenger @relation(fields: [passengerId], references: [id])
trip Trip @relation(fields: [tripId], references: [id])
seats BookingSeat[]
@@ -338,15 +387,26 @@ model Booking {
modifications BookingModification[]
cancellation BookingCancellation?
baggage BaggageBooking[]
@@index([passengerId, status])
}
model BookingSeat {
id String @id @default(uuid())
bookingId String
seatId String
passengerName String
idDocumentType String?
idDocumentNumber String?
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?
seatLabelSnapshot String?
fareMinor Int?
displayCurrency Currency?
displayFareMinor Int?
booking Booking @relation(fields: [bookingId], references: [id])
seat Seat @relation(fields: [seatId], references: [id])
}
@@ -357,8 +417,10 @@ model PaymentMethod {
type PaymentMethodType
displayName String
maskedHint String?
providerId String?
isDefault Boolean @default(false)
createdAt DateTime @default(now())
@@index([userId, isDefault])
}
model PaymentIntent {
@@ -367,6 +429,7 @@ model PaymentIntent {
amountMinor Int
currency String @default("ETB")
method PaymentMethodType
provider String?
status PaymentIntentStatus @default(REQUIRES_ACTION)
providerRef String?
clientAction Json?
@@ -375,6 +438,8 @@ model PaymentIntent {
providerTxnId String?
rawInitiation Json?
paidAt DateTime?
refundedAt DateTime?
captureMethod String?
failureCode String?
failureMessage String?
expiresAt DateTime?
@@ -433,7 +498,9 @@ 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[]
@@ -465,10 +532,13 @@ 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])
}
model WalletLedgerEntry {
@@ -516,6 +586,8 @@ model StationCrowdSignal {
level String
label String
statusLabel String
confidence Int?
observedAt DateTime?
updatedAt DateTime @updatedAt
station Station @relation(fields: [stationId], references: [id])
}
@@ -544,6 +616,7 @@ model MenuItem {
priceMinor Int
currency String @default("ETB")
available Boolean @default(true)
availableUntil DateTime?
trip Trip @relation(fields: [tripId], references: [id])
category MenuCategory @relation(fields: [categoryId], references: [id])
}
@@ -554,6 +627,8 @@ model FoodOrder {
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[]
@@ -565,6 +640,7 @@ model FoodOrderItem {
menuItemId String
name String
quantity Int
unitPriceMinor Int?
lineTotalMinor Int
order FoodOrder @relation(fields: [orderId], references: [id])
}
@@ -588,6 +664,7 @@ model FaqArticle {
model SupportConversation {
id String @id @default(uuid())
userId String
assignedAgentId String?
status SupportConversationStatus @default(OPEN)
createdAt DateTime @default(now())
messages SupportMessage[]
@@ -598,6 +675,7 @@ model SupportMessage {
conversationId String
sender SupportSender
text String
attachments Json?
createdAt DateTime @default(now())
conversation SupportConversation @relation(fields: [conversationId], references: [id])
}
@@ -715,17 +793,19 @@ model RouteStop {
}
model RouteFareRule {
id String @id @default(uuid())
id String @id @default(uuid())
routeId String
serviceClass ServiceClass
passengerCategory String @default("ADULT")
passengerCategory PassengerCategory @default(ADULT)
baseFareMinor Int
discountPercent Int?
currency String @default("ETB")
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)
createdAt DateTime @default(now())
route Route @relation(fields: [routeId], references: [id], onDelete: Cascade)
@@index([routeId, serviceClass])
}
@@ -915,3 +995,29 @@ model FraudAlert {
@@index([userId, createdAt])
@@index([acknowledged])
}
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])
}
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])
}