mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-09 10:58:14 +00:00
Refactored the whole app based on the requirements shared
This commit is contained in:
@@ -9,6 +9,8 @@ datasource db {
|
||||
|
||||
enum UserRole {
|
||||
PASSENGER
|
||||
AGENT
|
||||
SUPERVISOR
|
||||
ADMIN
|
||||
STAFF
|
||||
}
|
||||
@@ -36,9 +38,12 @@ enum SeatStatus {
|
||||
}
|
||||
|
||||
enum ServiceClass {
|
||||
ECONOMY
|
||||
BUSINESS
|
||||
FIRST
|
||||
ECONOMY_REGULAR
|
||||
ECONOMY_BED_LOWER
|
||||
ECONOMY_BED_MIDDLE
|
||||
ECONOMY_BED_UPPER
|
||||
VIP_BED_LOWER
|
||||
VIP_BED_UPPER
|
||||
}
|
||||
|
||||
enum BookingStatus {
|
||||
@@ -48,6 +53,7 @@ enum BookingStatus {
|
||||
CANCELLED
|
||||
COMPLETED
|
||||
NO_SHOW
|
||||
REFUNDED
|
||||
}
|
||||
|
||||
enum PaymentMethodType {
|
||||
@@ -64,6 +70,7 @@ enum PaymentIntentStatus {
|
||||
SUCCEEDED
|
||||
FAILED
|
||||
CANCELLED
|
||||
REFUNDED
|
||||
}
|
||||
|
||||
enum WalletLedgerType {
|
||||
@@ -134,12 +141,21 @@ model User {
|
||||
fullName String
|
||||
passwordHash String
|
||||
role UserRole @default(PASSENGER)
|
||||
nationality String?
|
||||
passportNumber String?
|
||||
nationalId String?
|
||||
failedLoginAttempts Int @default(0)
|
||||
lockedUntil DateTime?
|
||||
blockedUntil DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger?
|
||||
agent Agent?
|
||||
sessions Session[]
|
||||
devices Device[]
|
||||
preferences UserPreferences?
|
||||
auditLogs AuditLog[]
|
||||
fraudAlerts FraudAlert[]
|
||||
}
|
||||
|
||||
model Session {
|
||||
@@ -147,6 +163,9 @@ model Session {
|
||||
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)
|
||||
}
|
||||
@@ -267,8 +286,11 @@ model Seat {
|
||||
kind SeatKind @default(STANDARD)
|
||||
status SeatStatus @default(AVAILABLE)
|
||||
heldUntil DateTime?
|
||||
premiumFeeMinor Int @default(0)
|
||||
eligibility String?
|
||||
coach Coach @relation(fields: [coachId], references: [id])
|
||||
bookingSeats BookingSeat[]
|
||||
blocks SeatBlock[]
|
||||
@@unique([coachId, row, col])
|
||||
}
|
||||
|
||||
@@ -303,6 +325,7 @@ model Booking {
|
||||
status BookingStatus @default(DRAFT)
|
||||
currency String @default("ETB")
|
||||
totalMinor Int
|
||||
bookingType String @default("ONE_WAY")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
passenger Passenger @relation(fields: [passengerId], references: [id])
|
||||
@@ -311,6 +334,10 @@ model Booking {
|
||||
paymentIntent PaymentIntent?
|
||||
ticket Ticket?
|
||||
foodOrders FoodOrder[]
|
||||
agentBooking AgentBooking?
|
||||
modifications BookingModification[]
|
||||
cancellation BookingCancellation?
|
||||
baggage BaggageBooking[]
|
||||
}
|
||||
|
||||
model BookingSeat {
|
||||
@@ -392,10 +419,14 @@ model Ticket {
|
||||
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[]
|
||||
}
|
||||
|
||||
model LoyaltyAccount {
|
||||
@@ -585,6 +616,7 @@ model UserPreferences {
|
||||
dataSharing Boolean @default(false)
|
||||
locale String @default("en")
|
||||
darkMode Boolean @default(false)
|
||||
language String @default("en")
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
}
|
||||
|
||||
@@ -633,3 +665,253 @@ model JourneySegment {
|
||||
journey Journey @relation(fields: [journeyId], references: [id])
|
||||
trip Trip @relation(fields: [tripId], references: [id])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model PasswordResetToken {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
token String @unique
|
||||
expiresAt DateTime
|
||||
used Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
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[]
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model RouteFareRule {
|
||||
id String @id @default(uuid())
|
||||
routeId String
|
||||
serviceClass ServiceClass
|
||||
passengerCategory String @default("ADULT")
|
||||
baseFareMinor Int
|
||||
discountPercent Int?
|
||||
currency String @default("ETB")
|
||||
validFrom DateTime
|
||||
validUntil DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
route Route @relation(fields: [routeId], references: [id], onDelete: Cascade)
|
||||
@@index([routeId, serviceClass])
|
||||
}
|
||||
|
||||
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[]
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model BaggageAllowance {
|
||||
id String @id @default(uuid())
|
||||
serviceClass ServiceClass
|
||||
maxWeightKg Int
|
||||
maxPiecesCount Int
|
||||
excessFeePerKg Int
|
||||
currency String @default("ETB")
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model NotificationTemplate {
|
||||
id String @id @default(uuid())
|
||||
code String @unique
|
||||
channel String
|
||||
subject String?
|
||||
bodyTemplate String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
model OperationalReport {
|
||||
id String @id @default(uuid())
|
||||
reportType String
|
||||
dateFrom DateTime
|
||||
dateTo DateTime
|
||||
data Json
|
||||
generatedBy String?
|
||||
createdAt DateTime @default(now())
|
||||
@@index([reportType, dateFrom])
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user