Merge branch 'dev' into passenger/feat/iam

This commit is contained in:
Abubeker Yasin
2026-06-22 10:12:39 +03:00
1997 changed files with 435726 additions and 10897 deletions

View File

@@ -1,5 +0,0 @@
-- AlterEnum
ALTER TYPE "PaymentMethodType" ADD VALUE 'WAAFI';
-- AlterTable
ALTER TABLE "FareRule" ADD COLUMN "nationality" TEXT;

View File

@@ -1,28 +0,0 @@
-- AlterTable
ALTER TABLE "Booking" ADD COLUMN "contactEmail" TEXT,
ADD COLUMN "contactPhone" TEXT;
-- CreateTable
CREATE TABLE "SavedPassengerProfile" (
"id" TEXT NOT NULL,
"userId" TEXT,
"deviceId" TEXT,
"passengerName" TEXT NOT NULL,
"dateOfBirth" TIMESTAMP(3) NOT NULL,
"idDocumentType" "IdDocumentType" NOT NULL,
"passportNumber" TEXT,
"passportCountry" TEXT,
"nationality" TEXT,
"phone" TEXT,
"email" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "SavedPassengerProfile_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "SavedPassengerProfile_userId_idx" ON "SavedPassengerProfile"("userId");
-- CreateIndex
CREATE INDEX "SavedPassengerProfile_deviceId_idx" ON "SavedPassengerProfile"("deviceId");

View File

@@ -1,55 +0,0 @@
/*
Warnings:
- A unique constraint covering the columns `[faydaSub]` on the table `User` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE "passenger"."BookingSeat" ADD COLUMN "faydaSub" TEXT,
ADD COLUMN "faydaVerifiedAt" TIMESTAMP(3),
ADD COLUMN "faydaVerifiedName" TEXT;
-- AlterTable
ALTER TABLE "passenger"."User" ADD COLUMN "faydaSub" TEXT,
ADD COLUMN "faydaVerified" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "faydaVerifiedAt" TIMESTAMP(3);
-- CreateTable
CREATE TABLE "passenger"."FaydaVerificationSession" (
"id" TEXT NOT NULL,
"state" TEXT NOT NULL,
"codeVerifier" TEXT NOT NULL,
"purpose" TEXT NOT NULL DEFAULT 'PURCHASE',
"saveToAccount" BOOLEAN NOT NULL DEFAULT false,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"errorCode" TEXT,
"errorDescription" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expiresAt" TIMESTAMP(3) NOT NULL,
"completedAt" TIMESTAMP(3),
"userId" TEXT,
"bookingId" TEXT,
CONSTRAINT "FaydaVerificationSession_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "FaydaVerificationSession_state_key" ON "passenger"."FaydaVerificationSession"("state");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_userId_idx" ON "passenger"."FaydaVerificationSession"("userId");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_bookingId_idx" ON "passenger"."FaydaVerificationSession"("bookingId");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_state_idx" ON "passenger"."FaydaVerificationSession"("state");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_expiresAt_idx" ON "passenger"."FaydaVerificationSession"("expiresAt");
-- CreateIndex
CREATE UNIQUE INDEX "User_faydaSub_key" ON "passenger"."User"("faydaSub");
-- AddForeignKey
ALTER TABLE "passenger"."FaydaVerificationSession" ADD CONSTRAINT "FaydaVerificationSession_userId_fkey" FOREIGN KEY ("userId") REFERENCES "passenger"."User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -1,26 +0,0 @@
/*
Warnings:
- You are about to drop the column `maskedHint` on the `PaymentMethod` table. All the data in the column will be lost.
- You are about to drop the column `userId` on the `PaymentMethod` table. All the data in the column will be lost.
- A unique constraint covering the columns `[type]` on the table `PaymentMethod` will be added. If there are existing duplicate values, this will fail.
- Added the required column `updatedAt` to the `PaymentMethod` table without a default value. This is not possible if the table is not empty.
*/
-- CreateEnum
CREATE TYPE "PaymentRegion" AS ENUM ('ETHIOPIA', 'DJIBOUTI', 'INTERNATIONAL', 'GLOBAL');
-- DropIndex
DROP INDEX "PaymentMethod_userId_isDefault_idx";
-- AlterTable
ALTER TABLE "PaymentMethod" DROP COLUMN "maskedHint",
DROP COLUMN "userId",
ADD COLUMN "currency" TEXT NOT NULL DEFAULT 'ETB',
ADD COLUMN "enabled" BOOLEAN NOT NULL DEFAULT true,
ADD COLUMN "region" "PaymentRegion" NOT NULL DEFAULT 'GLOBAL',
ADD COLUMN "sortOrder" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL;
-- CreateIndex
CREATE UNIQUE INDEX "PaymentMethod_type_key" ON "PaymentMethod"("type");

View File

@@ -1,3 +0,0 @@
-- AlterTable
ALTER TABLE "FaydaVerificationSession" ADD COLUMN "authCode" TEXT,
ADD COLUMN "platform" TEXT NOT NULL DEFAULT 'WEB';

View File

@@ -1,2 +0,0 @@
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_routeId_fkey" FOREIGN KEY ("routeId") REFERENCES "Route"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -23,7 +23,10 @@ CREATE TYPE "Currency" AS ENUM ('ETB', 'DJF', 'USD');
CREATE TYPE "BookingStatus" AS ENUM ('DRAFT', 'PENDING_PAYMENT', 'CONFIRMED', 'CANCELLED', 'COMPLETED', 'NO_SHOW', 'REFUNDED');
-- CreateEnum
CREATE TYPE "PaymentMethodType" AS ENUM ('TELEBIRR', 'CBE_BIRR', 'EBIRR', 'CARD', 'WALLET');
CREATE TYPE "PaymentRegion" AS ENUM ('ETHIOPIA', 'DJIBOUTI', 'INTERNATIONAL', 'GLOBAL');
-- CreateEnum
CREATE TYPE "PaymentMethodType" AS ENUM ('TELEBIRR', 'CBE_BIRR', 'EBIRR', 'CARD', 'WALLET', 'WAAFI');
-- CreateEnum
CREATE TYPE "PaymentIntentStatus" AS ENUM ('REQUIRES_ACTION', 'PROCESSING', 'SUCCEEDED', 'FAILED', 'CANCELLED', 'REFUNDED');
@@ -55,12 +58,25 @@ CREATE TYPE "FoodOrderStatus" AS ENUM ('PENDING', 'PREPARING', 'READY', 'DELIVER
-- CreateEnum
CREATE TYPE "DevicePlatform" AS ENUM ('IOS', 'ANDROID', 'WEB');
-- CreateTable
CREATE TABLE "CoachType" (
"id" TEXT NOT NULL,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"type" TEXT NOT NULL DEFAULT 'passenger',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "CoachType_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "SeatClass" (
"id" TEXT NOT NULL,
"coachTypeId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"basePrice" INTEGER NOT NULL,
"baseFareMinor" INTEGER NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
@@ -86,6 +102,9 @@ CREATE TABLE "User" (
"lastLoginAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"faydaVerified" BOOLEAN NOT NULL DEFAULT false,
"faydaVerifiedAt" TIMESTAMP(3),
"faydaSub" TEXT,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
@@ -211,16 +230,11 @@ CREATE TABLE "TripLiveStatus" (
-- CreateTable
CREATE TABLE "Coach" (
"id" TEXT NOT NULL,
"coachNumber" TEXT NOT NULL,
"label" TEXT NOT NULL,
"seatClassId" TEXT NOT NULL,
"coachType" TEXT,
"mode" TEXT NOT NULL DEFAULT 'seat',
"seatArrangement" TEXT,
"bedArrangement" TEXT,
"amenities" JSONB,
"totalUnits" INTEGER NOT NULL DEFAULT 0,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"coachTypeId" TEXT NOT NULL,
"number" TEXT NOT NULL,
"arrangement" TEXT NOT NULL DEFAULT '2+2',
"capacity" INTEGER NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'ACTIVE',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
@@ -243,10 +257,9 @@ CREATE TABLE "CoachAssignment" (
CREATE TABLE "Seat" (
"id" TEXT NOT NULL,
"coachId" TEXT NOT NULL,
"seatNumber" TEXT NOT NULL,
"row" INTEGER NOT NULL,
"col" TEXT NOT NULL,
"label" TEXT NOT NULL,
"seatNumber" TEXT,
"kind" "SeatKind" NOT NULL DEFAULT 'STANDARD',
"status" "SeatStatus" NOT NULL DEFAULT 'AVAILABLE',
"heldUntil" TIMESTAMP(3),
@@ -254,7 +267,6 @@ CREATE TABLE "Seat" (
"isAisle" BOOLEAN NOT NULL DEFAULT false,
"bedPosition" TEXT,
"premiumFeeMinor" INTEGER NOT NULL DEFAULT 0,
"eligibility" TEXT,
CONSTRAINT "Seat_pkey" PRIMARY KEY ("id")
);
@@ -278,6 +290,7 @@ CREATE TABLE "FareRule" (
"id" TEXT NOT NULL,
"tripId" TEXT,
"route" TEXT,
"nationality" TEXT,
"seatClassId" TEXT NOT NULL,
"baseFareMinor" INTEGER NOT NULL,
"currency" TEXT NOT NULL DEFAULT 'ETB',
@@ -303,6 +316,8 @@ CREATE TABLE "Booking" (
"displayCurrency" "Currency",
"displayTotalMinor" INTEGER,
"bookingType" TEXT NOT NULL DEFAULT 'ONE_WAY',
"contactEmail" TEXT,
"contactPhone" TEXT,
"userAgent" TEXT,
"source" TEXT NOT NULL DEFAULT 'WEB',
"promoCode" TEXT,
@@ -327,6 +342,9 @@ CREATE TABLE "BookingSeat" (
"passportCountry" TEXT,
"verifaydaVerified" BOOLEAN NOT NULL DEFAULT false,
"verifaydaData" JSONB,
"faydaVerifiedAt" TIMESTAMP(3),
"faydaSub" TEXT,
"faydaVerifiedName" TEXT,
"seatLabelSnapshot" TEXT,
"fareMinor" INTEGER,
"displayCurrency" "Currency",
@@ -338,13 +356,16 @@ CREATE TABLE "BookingSeat" (
-- CreateTable
CREATE TABLE "PaymentMethod" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"type" "PaymentMethodType" NOT NULL,
"displayName" TEXT NOT NULL,
"maskedHint" TEXT,
"region" "PaymentRegion" NOT NULL DEFAULT 'GLOBAL',
"currency" TEXT NOT NULL DEFAULT 'ETB',
"providerId" TEXT,
"isDefault" BOOLEAN NOT NULL DEFAULT false,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PaymentMethod_pkey" PRIMARY KEY ("id")
);
@@ -423,6 +444,16 @@ CREATE TABLE "Ticket" (
CONSTRAINT "Ticket_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TicketSeat" (
"id" TEXT NOT NULL,
"ticketId" TEXT NOT NULL,
"seatId" TEXT NOT NULL,
"seatIndex" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "TicketSeat_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "LoyaltyAccount" (
"id" TEXT NOT NULL,
@@ -1016,8 +1047,51 @@ CREATE TABLE "VerifaydaVerification" (
CONSTRAINT "VerifaydaVerification_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "SavedPassengerProfile" (
"id" TEXT NOT NULL,
"userId" TEXT,
"deviceId" TEXT,
"passengerName" TEXT NOT NULL,
"dateOfBirth" TIMESTAMP(3) NOT NULL,
"idDocumentType" "IdDocumentType" NOT NULL,
"passportNumber" TEXT,
"passportCountry" TEXT,
"nationality" TEXT,
"phone" TEXT,
"email" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "SavedPassengerProfile_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "FaydaVerificationSession" (
"id" TEXT NOT NULL,
"state" TEXT NOT NULL,
"codeVerifier" TEXT NOT NULL,
"purpose" TEXT NOT NULL DEFAULT 'PURCHASE',
"platform" TEXT NOT NULL DEFAULT 'WEB',
"saveToAccount" BOOLEAN NOT NULL DEFAULT false,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"errorCode" TEXT,
"errorDescription" TEXT,
"authCode" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"expiresAt" TIMESTAMP(3) NOT NULL,
"completedAt" TIMESTAMP(3),
"userId" TEXT,
"bookingId" TEXT,
CONSTRAINT "FaydaVerificationSession_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "SeatClass_name_key" ON "SeatClass"("name");
CREATE INDEX "SeatClass_coachTypeId_idx" ON "SeatClass"("coachTypeId");
-- CreateIndex
CREATE UNIQUE INDEX "SeatClass_coachTypeId_name_key" ON "SeatClass"("coachTypeId", "name");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
@@ -1025,6 +1099,9 @@ CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "User_phone_key" ON "User"("phone");
-- CreateIndex
CREATE UNIQUE INDEX "User_faydaSub_key" ON "User"("faydaSub");
-- CreateIndex
CREATE UNIQUE INDEX "Session_token_key" ON "Session"("token");
@@ -1053,7 +1130,10 @@ CREATE UNIQUE INDEX "TripStopTime_scheduleId_sequence_key" ON "TripStopTime"("sc
CREATE UNIQUE INDEX "TripLiveStatus_scheduleId_key" ON "TripLiveStatus"("scheduleId");
-- CreateIndex
CREATE UNIQUE INDEX "Coach_coachNumber_key" ON "Coach"("coachNumber");
CREATE UNIQUE INDEX "Coach_number_key" ON "Coach"("number");
-- CreateIndex
CREATE INDEX "Coach_coachTypeId_idx" ON "Coach"("coachTypeId");
-- CreateIndex
CREATE INDEX "CoachAssignment_scheduleId_idx" ON "CoachAssignment"("scheduleId");
@@ -1062,11 +1142,14 @@ CREATE INDEX "CoachAssignment_scheduleId_idx" ON "CoachAssignment"("scheduleId")
CREATE UNIQUE INDEX "CoachAssignment_scheduleId_positionNumber_key" ON "CoachAssignment"("scheduleId", "positionNumber");
-- CreateIndex
CREATE UNIQUE INDEX "Seat_coachId_row_col_key" ON "Seat"("coachId", "row", "col");
CREATE INDEX "Seat_coachId_idx" ON "Seat"("coachId");
-- CreateIndex
CREATE UNIQUE INDEX "Seat_coachId_seatNumber_key" ON "Seat"("coachId", "seatNumber");
-- CreateIndex
CREATE UNIQUE INDEX "Seat_coachId_row_col_key" ON "Seat"("coachId", "row", "col");
-- CreateIndex
CREATE INDEX "SeatHold_expiresAt_idx" ON "SeatHold"("expiresAt");
@@ -1077,7 +1160,7 @@ CREATE UNIQUE INDEX "Booking_bookingRef_key" ON "Booking"("bookingRef");
CREATE INDEX "Booking_passengerId_status_idx" ON "Booking"("passengerId", "status");
-- CreateIndex
CREATE INDEX "PaymentMethod_userId_isDefault_idx" ON "PaymentMethod"("userId", "isDefault");
CREATE UNIQUE INDEX "PaymentMethod_type_key" ON "PaymentMethod"("type");
-- CreateIndex
CREATE UNIQUE INDEX "PaymentIntent_bookingId_key" ON "PaymentIntent"("bookingId");
@@ -1100,6 +1183,12 @@ CREATE UNIQUE INDEX "PaymentWebhookEvent_provider_externalEventId_key" ON "Payme
-- CreateIndex
CREATE UNIQUE INDEX "Ticket_bookingId_key" ON "Ticket"("bookingId");
-- CreateIndex
CREATE INDEX "TicketSeat_ticketId_idx" ON "TicketSeat"("ticketId");
-- CreateIndex
CREATE INDEX "TicketSeat_seatId_idx" ON "TicketSeat"("seatId");
-- CreateIndex
CREATE UNIQUE INDEX "LoyaltyAccount_passengerId_key" ON "LoyaltyAccount"("passengerId");
@@ -1202,6 +1291,30 @@ CREATE INDEX "VerifaydaVerification_nationalId_idx" ON "VerifaydaVerification"("
-- CreateIndex
CREATE INDEX "VerifaydaVerification_bookingId_idx" ON "VerifaydaVerification"("bookingId");
-- CreateIndex
CREATE INDEX "SavedPassengerProfile_userId_idx" ON "SavedPassengerProfile"("userId");
-- CreateIndex
CREATE INDEX "SavedPassengerProfile_deviceId_idx" ON "SavedPassengerProfile"("deviceId");
-- CreateIndex
CREATE UNIQUE INDEX "FaydaVerificationSession_state_key" ON "FaydaVerificationSession"("state");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_userId_idx" ON "FaydaVerificationSession"("userId");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_bookingId_idx" ON "FaydaVerificationSession"("bookingId");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_state_idx" ON "FaydaVerificationSession"("state");
-- CreateIndex
CREATE INDEX "FaydaVerificationSession_expiresAt_idx" ON "FaydaVerificationSession"("expiresAt");
-- AddForeignKey
ALTER TABLE "SeatClass" ADD CONSTRAINT "SeatClass_coachTypeId_fkey" FOREIGN KEY ("coachTypeId") REFERENCES "CoachType"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -1214,6 +1327,9 @@ ALTER TABLE "TravelerProfile" ADD CONSTRAINT "TravelerProfile_passengerId_fkey"
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_trainId_fkey" FOREIGN KEY ("trainId") REFERENCES "Train"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_routeId_fkey" FOREIGN KEY ("routeId") REFERENCES "Route"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_originStationId_fkey" FOREIGN KEY ("originStationId") REFERENCES "Station"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -1230,7 +1346,7 @@ ALTER TABLE "TripStopTime" ADD CONSTRAINT "TripStopTime_stationId_fkey" FOREIGN
ALTER TABLE "TripLiveStatus" ADD CONSTRAINT "TripLiveStatus_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Coach" ADD CONSTRAINT "Coach_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "SeatClass"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "Coach" ADD CONSTRAINT "Coach_coachTypeId_fkey" FOREIGN KEY ("coachTypeId") REFERENCES "CoachType"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CoachAssignment" ADD CONSTRAINT "CoachAssignment_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -1265,6 +1381,12 @@ ALTER TABLE "PaymentRefund" ADD CONSTRAINT "PaymentRefund_paymentIntentId_fkey"
-- AddForeignKey
ALTER TABLE "Ticket" ADD CONSTRAINT "Ticket_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TicketSeat" ADD CONSTRAINT "TicketSeat_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "Ticket"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TicketSeat" ADD CONSTRAINT "TicketSeat_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "Seat"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LoyaltyAccount" ADD CONSTRAINT "LoyaltyAccount_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "Passenger"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -1363,3 +1485,6 @@ ALTER TABLE "SeatBlock" ADD CONSTRAINT "SeatBlock_seatId_fkey" FOREIGN KEY ("sea
-- AddForeignKey
ALTER TABLE "FraudAlert" ADD CONSTRAINT "FraudAlert_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FaydaVerificationSession" ADD CONSTRAINT "FaydaVerificationSession_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,28 @@
-- CreateTable
CREATE TABLE "SegmentFareRule" (
"id" TEXT NOT NULL,
"routeId" TEXT NOT NULL,
"originStopSequence" INTEGER NOT NULL,
"destinationStopSequence" INTEGER NOT NULL,
"seatClassId" TEXT NOT NULL,
"baseFareMinor" INTEGER NOT NULL,
"nationality" TEXT,
"currency" TEXT NOT NULL DEFAULT 'ETB',
"validFrom" TIMESTAMP(3) NOT NULL,
"validUntil" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SegmentFareRule_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "SegmentFareRule_routeId_seatClassId_idx" ON "SegmentFareRule"("routeId", "seatClassId");
-- CreateIndex
CREATE UNIQUE INDEX "SegmentFareRule_routeId_originStopSequence_destinationStopS_key" ON "SegmentFareRule"("routeId", "originStopSequence", "destinationStopSequence", "seatClassId", "nationality");
-- AddForeignKey
ALTER TABLE "SegmentFareRule" ADD CONSTRAINT "SegmentFareRule_routeId_fkey" FOREIGN KEY ("routeId") REFERENCES "Route"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SegmentFareRule" ADD CONSTRAINT "SegmentFareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "SeatClass"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "PaymentMethodType" ADD VALUE 'DMONEY';

View File

@@ -0,0 +1,279 @@
-- DropForeignKey
ALTER TABLE "AgentBooking" DROP CONSTRAINT "AgentBooking_agentId_fkey";
-- DropForeignKey
ALTER TABLE "AgentBooking" DROP CONSTRAINT "AgentBooking_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "AgentCommission" DROP CONSTRAINT "AgentCommission_agentId_fkey";
-- DropForeignKey
ALTER TABLE "AgentShift" DROP CONSTRAINT "AgentShift_agentId_fkey";
-- DropForeignKey
ALTER TABLE "BaggageBooking" DROP CONSTRAINT "BaggageBooking_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "Booking" DROP CONSTRAINT "Booking_passengerId_fkey";
-- DropForeignKey
ALTER TABLE "Booking" DROP CONSTRAINT "Booking_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "BookingCancellation" DROP CONSTRAINT "BookingCancellation_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "BookingModification" DROP CONSTRAINT "BookingModification_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "BookingSeat" DROP CONSTRAINT "BookingSeat_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "BookingSeat" DROP CONSTRAINT "BookingSeat_seatId_fkey";
-- DropForeignKey
ALTER TABLE "Coach" DROP CONSTRAINT "Coach_coachTypeId_fkey";
-- DropForeignKey
ALTER TABLE "CoachAssignment" DROP CONSTRAINT "CoachAssignment_coachId_fkey";
-- DropForeignKey
ALTER TABLE "CoachAssignment" DROP CONSTRAINT "CoachAssignment_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "FaqArticle" DROP CONSTRAINT "FaqArticle_categoryId_fkey";
-- DropForeignKey
ALTER TABLE "FareRule" DROP CONSTRAINT "FareRule_seatClassId_fkey";
-- DropForeignKey
ALTER TABLE "FoodOrder" DROP CONSTRAINT "FoodOrder_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "FoodOrderItem" DROP CONSTRAINT "FoodOrderItem_orderId_fkey";
-- DropForeignKey
ALTER TABLE "GateValidationLog" DROP CONSTRAINT "GateValidationLog_ticketId_fkey";
-- DropForeignKey
ALTER TABLE "JourneySegment" DROP CONSTRAINT "JourneySegment_journeyId_fkey";
-- DropForeignKey
ALTER TABLE "JourneySegment" DROP CONSTRAINT "JourneySegment_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "LoyaltyLedgerEntry" DROP CONSTRAINT "LoyaltyLedgerEntry_accountId_fkey";
-- DropForeignKey
ALTER TABLE "LoyaltyReward" DROP CONSTRAINT "LoyaltyReward_accountId_fkey";
-- DropForeignKey
ALTER TABLE "MenuItem" DROP CONSTRAINT "MenuItem_categoryId_fkey";
-- DropForeignKey
ALTER TABLE "MenuItem" DROP CONSTRAINT "MenuItem_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "Notification" DROP CONSTRAINT "Notification_passengerId_fkey";
-- DropForeignKey
ALTER TABLE "PaymentIntent" DROP CONSTRAINT "PaymentIntent_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "PaymentRefund" DROP CONSTRAINT "PaymentRefund_paymentIntentId_fkey";
-- DropForeignKey
ALTER TABLE "RouteFareRule" DROP CONSTRAINT "RouteFareRule_seatClassId_fkey";
-- DropForeignKey
ALTER TABLE "SavedRoute" DROP CONSTRAINT "SavedRoute_passengerId_fkey";
-- DropForeignKey
ALTER TABLE "SeatBlock" DROP CONSTRAINT "SeatBlock_seatId_fkey";
-- DropForeignKey
ALTER TABLE "SegmentFareRule" DROP CONSTRAINT "SegmentFareRule_seatClassId_fkey";
-- DropForeignKey
ALTER TABLE "StationCrowdSignal" DROP CONSTRAINT "StationCrowdSignal_stationId_fkey";
-- DropForeignKey
ALTER TABLE "SupportMessage" DROP CONSTRAINT "SupportMessage_conversationId_fkey";
-- DropForeignKey
ALTER TABLE "Ticket" DROP CONSTRAINT "Ticket_bookingId_fkey";
-- DropForeignKey
ALTER TABLE "TicketSeat" DROP CONSTRAINT "TicketSeat_seatId_fkey";
-- DropForeignKey
ALTER TABLE "TrainSchedule" DROP CONSTRAINT "TrainSchedule_destinationStationId_fkey";
-- DropForeignKey
ALTER TABLE "TrainSchedule" DROP CONSTRAINT "TrainSchedule_originStationId_fkey";
-- DropForeignKey
ALTER TABLE "TrainSchedule" DROP CONSTRAINT "TrainSchedule_routeId_fkey";
-- DropForeignKey
ALTER TABLE "TrainSchedule" DROP CONSTRAINT "TrainSchedule_trainId_fkey";
-- DropForeignKey
ALTER TABLE "TripLiveStatus" DROP CONSTRAINT "TripLiveStatus_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "TripStopTime" DROP CONSTRAINT "TripStopTime_scheduleId_fkey";
-- DropForeignKey
ALTER TABLE "WalletLedgerEntry" DROP CONSTRAINT "WalletLedgerEntry_walletId_fkey";
-- AlterTable
ALTER TABLE "Booking" ADD COLUMN "returnDestinationStationId" TEXT,
ADD COLUMN "returnHoldId" TEXT,
ADD COLUMN "returnOriginStationId" TEXT,
ADD COLUMN "returnScheduleId" TEXT,
ADD COLUMN "returnSeatClassId" TEXT;
-- AlterTable
ALTER TABLE "SeatClass" ALTER COLUMN "baseFareMinor" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "Ticket" ALTER COLUMN "status" SET DEFAULT 'ACTIVE';
-- AlterTable
-- gender is created here on a clean migration history (no prior migration adds it);
-- on an already-drifted DB where it exists as varchar, normalize it to TEXT.
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "gender" TEXT;
ALTER TABLE "User" ALTER COLUMN "gender" SET DATA TYPE TEXT;
-- CreateIndex
CREATE INDEX "Booking_bookingType_idx" ON "Booking"("bookingType");
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_trainId_fkey" FOREIGN KEY ("trainId") REFERENCES "Train"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_routeId_fkey" FOREIGN KEY ("routeId") REFERENCES "Route"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_originStationId_fkey" FOREIGN KEY ("originStationId") REFERENCES "Station"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TrainSchedule" ADD CONSTRAINT "TrainSchedule_destinationStationId_fkey" FOREIGN KEY ("destinationStationId") REFERENCES "Station"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TripStopTime" ADD CONSTRAINT "TripStopTime_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TripLiveStatus" ADD CONSTRAINT "TripLiveStatus_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Coach" ADD CONSTRAINT "Coach_coachTypeId_fkey" FOREIGN KEY ("coachTypeId") REFERENCES "CoachType"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CoachAssignment" ADD CONSTRAINT "CoachAssignment_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "CoachAssignment" ADD CONSTRAINT "CoachAssignment_coachId_fkey" FOREIGN KEY ("coachId") REFERENCES "Coach"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FareRule" ADD CONSTRAINT "FareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "SeatClass"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "Passenger"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Booking" ADD CONSTRAINT "Booking_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BookingSeat" ADD CONSTRAINT "BookingSeat_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BookingSeat" ADD CONSTRAINT "BookingSeat_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "Seat"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentIntent" ADD CONSTRAINT "PaymentIntent_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentRefund" ADD CONSTRAINT "PaymentRefund_paymentIntentId_fkey" FOREIGN KEY ("paymentIntentId") REFERENCES "PaymentIntent"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Ticket" ADD CONSTRAINT "Ticket_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TicketSeat" ADD CONSTRAINT "TicketSeat_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "Seat"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LoyaltyLedgerEntry" ADD CONSTRAINT "LoyaltyLedgerEntry_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "LoyaltyAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LoyaltyReward" ADD CONSTRAINT "LoyaltyReward_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "LoyaltyAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WalletLedgerEntry" ADD CONSTRAINT "WalletLedgerEntry_walletId_fkey" FOREIGN KEY ("walletId") REFERENCES "WalletAccount"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Notification" ADD CONSTRAINT "Notification_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "Passenger"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "StationCrowdSignal" ADD CONSTRAINT "StationCrowdSignal_stationId_fkey" FOREIGN KEY ("stationId") REFERENCES "Station"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MenuItem" ADD CONSTRAINT "MenuItem_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MenuItem" ADD CONSTRAINT "MenuItem_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "MenuCategory"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FoodOrder" ADD CONSTRAINT "FoodOrder_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FoodOrderItem" ADD CONSTRAINT "FoodOrderItem_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "FoodOrder"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "FaqArticle" ADD CONSTRAINT "FaqArticle_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "FaqCategory"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SupportMessage" ADD CONSTRAINT "SupportMessage_conversationId_fkey" FOREIGN KEY ("conversationId") REFERENCES "SupportConversation"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SavedRoute" ADD CONSTRAINT "SavedRoute_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "Passenger"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "JourneySegment" ADD CONSTRAINT "JourneySegment_journeyId_fkey" FOREIGN KEY ("journeyId") REFERENCES "Journey"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "JourneySegment" ADD CONSTRAINT "JourneySegment_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "TrainSchedule"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RouteFareRule" ADD CONSTRAINT "RouteFareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "SeatClass"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SegmentFareRule" ADD CONSTRAINT "SegmentFareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "SeatClass"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "AgentBooking" ADD CONSTRAINT "AgentBooking_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "AgentBooking" ADD CONSTRAINT "AgentBooking_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "AgentShift" ADD CONSTRAINT "AgentShift_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "AgentCommission" ADD CONSTRAINT "AgentCommission_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agent"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BookingModification" ADD CONSTRAINT "BookingModification_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BookingCancellation" ADD CONSTRAINT "BookingCancellation_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "GateValidationLog" ADD CONSTRAINT "GateValidationLog_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "Ticket"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BaggageBooking" ADD CONSTRAINT "BaggageBooking_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "Booking"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "SeatBlock" ADD CONSTRAINT "SeatBlock_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "Seat"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,36 @@
-- Add sequence column to Station table if it doesn't exist
ALTER TABLE "passenger"."Station" ADD COLUMN IF NOT EXISTS "sequence" INTEGER NOT NULL DEFAULT 0;
-- Add index on sequence for Station
CREATE INDEX IF NOT EXISTS "Station_sequence_idx" ON "passenger"."Station"("sequence");
-- Add sequence column to Coach table if it doesn't exist
ALTER TABLE "passenger"."Coach" ADD COLUMN IF NOT EXISTS "sequence" INTEGER NOT NULL DEFAULT 0;
-- Add index on sequence for Coach
CREATE INDEX IF NOT EXISTS "Coach_sequence_idx" ON "passenger"."Coach"("sequence");
-- Add missing columns to SeatClass if they don't exist
ALTER TABLE "passenger"."SeatClass" ADD COLUMN IF NOT EXISTS "premiumMinor" INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "passenger"."SeatClass" ADD COLUMN IF NOT EXISTS "insuranceFeeMinor" INTEGER NOT NULL DEFAULT 0;
-- Add missing columns to User if they don't exist
ALTER TABLE "passenger"."User" ADD COLUMN IF NOT EXISTS "gender" VARCHAR(255);
ALTER TABLE "passenger"."User" ADD COLUMN IF NOT EXISTS "dateOfBirth" TIMESTAMP(3);
ALTER TABLE "passenger"."User" ADD COLUMN IF NOT EXISTS "passportNumber" VARCHAR(255);
ALTER TABLE "passenger"."User" ADD COLUMN IF NOT EXISTS "nationalId" VARCHAR(255);
-- Ensure Ticket has all required columns
ALTER TABLE "passenger"."Ticket" ADD COLUMN IF NOT EXISTS "validatedAt" TIMESTAMP(3);
ALTER TABLE "passenger"."Ticket" ADD COLUMN IF NOT EXISTS "boardedAt" TIMESTAMP(3);
-- Add missing columns to Booking if they don't exist
ALTER TABLE "passenger"."Booking" ADD COLUMN IF NOT EXISTS "bookingType" VARCHAR(255) NOT NULL DEFAULT 'ONE_WAY';
ALTER TABLE "passenger"."Booking" ADD COLUMN IF NOT EXISTS "displayCurrency" VARCHAR(255);
ALTER TABLE "passenger"."Booking" ADD COLUMN IF NOT EXISTS "displayTotalMinor" INTEGER;
-- Ensure all indexes exist
CREATE INDEX IF NOT EXISTS "Station_city_countryCode_idx" ON "passenger"."Station"("city", "countryCode");
CREATE INDEX IF NOT EXISTS "Coach_coachTypeId_idx" ON "passenger"."Coach"("coachTypeId");
CREATE INDEX IF NOT EXISTS "TrainSchedule_departureAt_originStationId_idx" ON "passenger"."TrainSchedule"("departureAt", "originStationId");
CREATE INDEX IF NOT EXISTS "Booking_passengerId_status_idx" ON "passenger"."Booking"("passengerId", "status");

View File

@@ -0,0 +1,164 @@
-- Add CASCADE delete to all foreign key constraints that are missing it
-- TrainSchedule relations
ALTER TABLE "passenger"."TrainSchedule" DROP CONSTRAINT IF EXISTS "TrainSchedule_trainId_fkey";
ALTER TABLE "passenger"."TrainSchedule" ADD CONSTRAINT "TrainSchedule_trainId_fkey" FOREIGN KEY ("trainId") REFERENCES "passenger"."Train"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."TrainSchedule" DROP CONSTRAINT IF EXISTS "TrainSchedule_routeId_fkey";
ALTER TABLE "passenger"."TrainSchedule" ADD CONSTRAINT "TrainSchedule_routeId_fkey" FOREIGN KEY ("routeId") REFERENCES "passenger"."Route"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."TrainSchedule" DROP CONSTRAINT IF EXISTS "TrainSchedule_originStationId_fkey";
ALTER TABLE "passenger"."TrainSchedule" ADD CONSTRAINT "TrainSchedule_originStationId_fkey" FOREIGN KEY ("originStationId") REFERENCES "passenger"."Station"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."TrainSchedule" DROP CONSTRAINT IF EXISTS "TrainSchedule_destinationStationId_fkey";
ALTER TABLE "passenger"."TrainSchedule" ADD CONSTRAINT "TrainSchedule_destinationStationId_fkey" FOREIGN KEY ("destinationStationId") REFERENCES "passenger"."Station"("id") ON DELETE CASCADE;
-- Coach relation
ALTER TABLE "passenger"."Coach" DROP CONSTRAINT IF EXISTS "Coach_coachTypeId_fkey";
ALTER TABLE "passenger"."Coach" ADD CONSTRAINT "Coach_coachTypeId_fkey" FOREIGN KEY ("coachTypeId") REFERENCES "passenger"."CoachType"("id") ON DELETE CASCADE;
-- CoachAssignment relations
ALTER TABLE "passenger"."CoachAssignment" DROP CONSTRAINT IF EXISTS "CoachAssignment_scheduleId_fkey";
ALTER TABLE "passenger"."CoachAssignment" ADD CONSTRAINT "CoachAssignment_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."CoachAssignment" DROP CONSTRAINT IF EXISTS "CoachAssignment_coachId_fkey";
ALTER TABLE "passenger"."CoachAssignment" ADD CONSTRAINT "CoachAssignment_coachId_fkey" FOREIGN KEY ("coachId") REFERENCES "passenger"."Coach"("id") ON DELETE CASCADE;
-- Booking relations
ALTER TABLE "passenger"."Booking" DROP CONSTRAINT IF EXISTS "Booking_passengerId_fkey";
ALTER TABLE "passenger"."Booking" ADD CONSTRAINT "Booking_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "passenger"."Passenger"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."Booking" DROP CONSTRAINT IF EXISTS "Booking_scheduleId_fkey";
ALTER TABLE "passenger"."Booking" ADD CONSTRAINT "Booking_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
-- BookingSeat relations
ALTER TABLE "passenger"."BookingSeat" DROP CONSTRAINT IF EXISTS "BookingSeat_bookingId_fkey";
ALTER TABLE "passenger"."BookingSeat" ADD CONSTRAINT "BookingSeat_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."BookingSeat" DROP CONSTRAINT IF EXISTS "BookingSeat_seatId_fkey";
ALTER TABLE "passenger"."BookingSeat" ADD CONSTRAINT "BookingSeat_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "passenger"."Seat"("id") ON DELETE CASCADE;
-- PaymentIntent
ALTER TABLE "passenger"."PaymentIntent" DROP CONSTRAINT IF EXISTS "PaymentIntent_bookingId_fkey";
ALTER TABLE "passenger"."PaymentIntent" ADD CONSTRAINT "PaymentIntent_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- PaymentRefund
ALTER TABLE "passenger"."PaymentRefund" DROP CONSTRAINT IF EXISTS "PaymentRefund_paymentIntentId_fkey";
ALTER TABLE "passenger"."PaymentRefund" ADD CONSTRAINT "PaymentRefund_paymentIntentId_fkey" FOREIGN KEY ("paymentIntentId") REFERENCES "passenger"."PaymentIntent"("id") ON DELETE CASCADE;
-- Ticket
ALTER TABLE "passenger"."Ticket" DROP CONSTRAINT IF EXISTS "Ticket_bookingId_fkey";
ALTER TABLE "passenger"."Ticket" ADD CONSTRAINT "Ticket_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- TicketSeat
ALTER TABLE "passenger"."TicketSeat" DROP CONSTRAINT IF EXISTS "TicketSeat_seatId_fkey";
ALTER TABLE "passenger"."TicketSeat" ADD CONSTRAINT "TicketSeat_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "passenger"."Seat"("id") ON DELETE CASCADE;
-- WalletLedgerEntry
ALTER TABLE "passenger"."WalletLedgerEntry" DROP CONSTRAINT IF EXISTS "WalletLedgerEntry_walletId_fkey";
ALTER TABLE "passenger"."WalletLedgerEntry" ADD CONSTRAINT "WalletLedgerEntry_walletId_fkey" FOREIGN KEY ("walletId") REFERENCES "passenger"."WalletAccount"("id") ON DELETE CASCADE;
-- Notification
ALTER TABLE "passenger"."Notification" DROP CONSTRAINT IF EXISTS "Notification_passengerId_fkey";
ALTER TABLE "passenger"."Notification" ADD CONSTRAINT "Notification_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "passenger"."Passenger"("id") ON DELETE CASCADE;
-- MenuItem
ALTER TABLE "passenger"."MenuItem" DROP CONSTRAINT IF EXISTS "MenuItem_scheduleId_fkey";
ALTER TABLE "passenger"."MenuItem" ADD CONSTRAINT "MenuItem_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."MenuItem" DROP CONSTRAINT IF EXISTS "MenuItem_categoryId_fkey";
ALTER TABLE "passenger"."MenuItem" ADD CONSTRAINT "MenuItem_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "passenger"."MenuCategory"("id") ON DELETE CASCADE;
-- FoodOrder
ALTER TABLE "passenger"."FoodOrder" DROP CONSTRAINT IF EXISTS "FoodOrder_bookingId_fkey";
ALTER TABLE "passenger"."FoodOrder" ADD CONSTRAINT "FoodOrder_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- FoodOrderItem
ALTER TABLE "passenger"."FoodOrderItem" DROP CONSTRAINT IF EXISTS "FoodOrderItem_orderId_fkey";
ALTER TABLE "passenger"."FoodOrderItem" ADD CONSTRAINT "FoodOrderItem_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "passenger"."FoodOrder"("id") ON DELETE CASCADE;
-- FaqArticle
ALTER TABLE "passenger"."FaqArticle" DROP CONSTRAINT IF EXISTS "FaqArticle_categoryId_fkey";
ALTER TABLE "passenger"."FaqArticle" ADD CONSTRAINT "FaqArticle_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "passenger"."FaqCategory"("id") ON DELETE CASCADE;
-- SupportMessage
ALTER TABLE "passenger"."SupportMessage" DROP CONSTRAINT IF EXISTS "SupportMessage_conversationId_fkey";
ALTER TABLE "passenger"."SupportMessage" ADD CONSTRAINT "SupportMessage_conversationId_fkey" FOREIGN KEY ("conversationId") REFERENCES "passenger"."SupportConversation"("id") ON DELETE CASCADE;
-- TripStopTime
ALTER TABLE "passenger"."TripStopTime" DROP CONSTRAINT IF EXISTS "TripStopTime_scheduleId_fkey";
ALTER TABLE "passenger"."TripStopTime" ADD CONSTRAINT "TripStopTime_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
-- TripLiveStatus
ALTER TABLE "passenger"."TripLiveStatus" DROP CONSTRAINT IF EXISTS "TripLiveStatus_scheduleId_fkey";
ALTER TABLE "passenger"."TripLiveStatus" ADD CONSTRAINT "TripLiveStatus_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
-- JourneySegment
ALTER TABLE "passenger"."JourneySegment" DROP CONSTRAINT IF EXISTS "JourneySegment_journeyId_fkey";
ALTER TABLE "passenger"."JourneySegment" ADD CONSTRAINT "JourneySegment_journeyId_fkey" FOREIGN KEY ("journeyId") REFERENCES "passenger"."Journey"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."JourneySegment" DROP CONSTRAINT IF EXISTS "JourneySegment_scheduleId_fkey";
ALTER TABLE "passenger"."JourneySegment" ADD CONSTRAINT "JourneySegment_scheduleId_fkey" FOREIGN KEY ("scheduleId") REFERENCES "passenger"."TrainSchedule"("id") ON DELETE CASCADE;
-- AgentBooking
ALTER TABLE "passenger"."AgentBooking" DROP CONSTRAINT IF EXISTS "AgentBooking_agentId_fkey";
ALTER TABLE "passenger"."AgentBooking" ADD CONSTRAINT "AgentBooking_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "passenger"."Agent"("id") ON DELETE CASCADE;
ALTER TABLE "passenger"."AgentBooking" DROP CONSTRAINT IF EXISTS "AgentBooking_bookingId_fkey";
ALTER TABLE "passenger"."AgentBooking" ADD CONSTRAINT "AgentBooking_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- AgentShift
ALTER TABLE "passenger"."AgentShift" DROP CONSTRAINT IF EXISTS "AgentShift_agentId_fkey";
ALTER TABLE "passenger"."AgentShift" ADD CONSTRAINT "AgentShift_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "passenger"."Agent"("id") ON DELETE CASCADE;
-- AgentCommission
ALTER TABLE "passenger"."AgentCommission" DROP CONSTRAINT IF EXISTS "AgentCommission_agentId_fkey";
ALTER TABLE "passenger"."AgentCommission" ADD CONSTRAINT "AgentCommission_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "passenger"."Agent"("id") ON DELETE CASCADE;
-- BookingModification
ALTER TABLE "passenger"."BookingModification" DROP CONSTRAINT IF EXISTS "BookingModification_bookingId_fkey";
ALTER TABLE "passenger"."BookingModification" ADD CONSTRAINT "BookingModification_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- BookingCancellation
ALTER TABLE "passenger"."BookingCancellation" DROP CONSTRAINT IF EXISTS "BookingCancellation_bookingId_fkey";
ALTER TABLE "passenger"."BookingCancellation" ADD CONSTRAINT "BookingCancellation_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- GateValidationLog
ALTER TABLE "passenger"."GateValidationLog" DROP CONSTRAINT IF EXISTS "GateValidationLog_ticketId_fkey";
ALTER TABLE "passenger"."GateValidationLog" ADD CONSTRAINT "GateValidationLog_ticketId_fkey" FOREIGN KEY ("ticketId") REFERENCES "passenger"."Ticket"("id") ON DELETE CASCADE;
-- BaggageBooking
ALTER TABLE "passenger"."BaggageBooking" DROP CONSTRAINT IF EXISTS "BaggageBooking_bookingId_fkey";
ALTER TABLE "passenger"."BaggageBooking" ADD CONSTRAINT "BaggageBooking_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "passenger"."Booking"("id") ON DELETE CASCADE;
-- RouteFareRule
ALTER TABLE "passenger"."RouteFareRule" DROP CONSTRAINT IF EXISTS "RouteFareRule_seatClassId_fkey";
ALTER TABLE "passenger"."RouteFareRule" ADD CONSTRAINT "RouteFareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "passenger"."SeatClass"("id") ON DELETE CASCADE;
-- SegmentFareRule
ALTER TABLE "passenger"."SegmentFareRule" DROP CONSTRAINT IF EXISTS "SegmentFareRule_seatClassId_fkey";
ALTER TABLE "passenger"."SegmentFareRule" ADD CONSTRAINT "SegmentFareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "passenger"."SeatClass"("id") ON DELETE CASCADE;
-- StationCrowdSignal
ALTER TABLE "passenger"."StationCrowdSignal" DROP CONSTRAINT IF EXISTS "StationCrowdSignal_stationId_fkey";
ALTER TABLE "passenger"."StationCrowdSignal" ADD CONSTRAINT "StationCrowdSignal_stationId_fkey" FOREIGN KEY ("stationId") REFERENCES "passenger"."Station"("id") ON DELETE CASCADE;
-- SeatBlock
ALTER TABLE "passenger"."SeatBlock" DROP CONSTRAINT IF EXISTS "SeatBlock_seatId_fkey";
ALTER TABLE "passenger"."SeatBlock" ADD CONSTRAINT "SeatBlock_seatId_fkey" FOREIGN KEY ("seatId") REFERENCES "passenger"."Seat"("id") ON DELETE CASCADE;
-- SavedRoute
ALTER TABLE "passenger"."SavedRoute" DROP CONSTRAINT IF EXISTS "SavedRoute_passengerId_fkey";
ALTER TABLE "passenger"."SavedRoute" ADD CONSTRAINT "SavedRoute_passengerId_fkey" FOREIGN KEY ("passengerId") REFERENCES "passenger"."Passenger"("id") ON DELETE CASCADE;
-- LoyaltyLedgerEntry
ALTER TABLE "passenger"."LoyaltyLedgerEntry" DROP CONSTRAINT IF EXISTS "LoyaltyLedgerEntry_accountId_fkey";
ALTER TABLE "passenger"."LoyaltyLedgerEntry" ADD CONSTRAINT "LoyaltyLedgerEntry_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "passenger"."LoyaltyAccount"("id") ON DELETE CASCADE;
-- LoyaltyReward
ALTER TABLE "passenger"."LoyaltyReward" DROP CONSTRAINT IF EXISTS "LoyaltyReward_accountId_fkey";
ALTER TABLE "passenger"."LoyaltyReward" ADD CONSTRAINT "LoyaltyReward_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "passenger"."LoyaltyAccount"("id") ON DELETE CASCADE;
-- FareRule
ALTER TABLE "passenger"."FareRule" DROP CONSTRAINT IF EXISTS "FareRule_seatClassId_fkey";
ALTER TABLE "passenger"."FareRule" ADD CONSTRAINT "FareRule_seatClassId_fkey" FOREIGN KEY ("seatClassId") REFERENCES "passenger"."SeatClass"("id") ON DELETE CASCADE;

View File

@@ -0,0 +1,18 @@
-- CreateEnum
CREATE TYPE "passenger"."ReturnLegStatus" AS ENUM ('NOT_APPLICABLE', 'BOTH_USED', 'OUTBOUND_ONLY', 'INBOUND_ONLY', 'NEITHER_USED');
-- AlterTable: add return leg tracking columns to Booking
ALTER TABLE "passenger"."Booking"
ADD COLUMN "returnLegStatus" "passenger"."ReturnLegStatus" NOT NULL DEFAULT 'NOT_APPLICABLE',
ADD COLUMN "outboundBoardedAt" TIMESTAMP(3),
ADD COLUMN "returnBoardedAt" TIMESTAMP(3);
-- Set NEITHER_USED for existing confirmed round-trip bookings
UPDATE "passenger"."Booking"
SET "returnLegStatus" = 'NEITHER_USED'
WHERE "bookingType" = 'ROUND_TRIP'
AND "status" IN ('CONFIRMED', 'COMPLETED');
-- AlterTable: add leg column to GateValidationLog
ALTER TABLE "passenger"."GateValidationLog"
ADD COLUMN "leg" TEXT;

View File

@@ -0,0 +1,68 @@
-- Create passenger schema if it doesn't exist
CREATE SCHEMA IF NOT EXISTS passenger;
-- Move all enums from public to passenger schema
DO $$
DECLARE
e text;
BEGIN
FOR e IN
SELECT typname FROM pg_type
JOIN pg_namespace ON pg_namespace.oid = pg_type.typnamespace
WHERE pg_namespace.nspname = 'public' AND pg_type.typtype = 'e'
LOOP
EXECUTE format('ALTER TYPE public.%I SET SCHEMA passenger', e);
END LOOP;
END $$;
-- Move all tables from public to passenger schema
DO $$
DECLARE
t text;
BEGIN
FOR t IN
SELECT tablename FROM pg_tables
WHERE schemaname = 'public' AND tablename NOT IN ('_prisma_migrations')
LOOP
EXECUTE format('ALTER TABLE public.%I SET SCHEMA passenger', t);
END LOOP;
END $$;
-- Add missing columns to Booking
ALTER TABLE "passenger"."Booking"
ADD COLUMN IF NOT EXISTS "returnScheduleId" TEXT,
ADD COLUMN IF NOT EXISTS "returnOriginStationId" TEXT,
ADD COLUMN IF NOT EXISTS "returnDestinationStationId" TEXT,
ADD COLUMN IF NOT EXISTS "returnHoldId" TEXT,
ADD COLUMN IF NOT EXISTS "returnSeatClassId" TEXT,
ADD COLUMN IF NOT EXISTS "leg2ScheduleId" TEXT,
ADD COLUMN IF NOT EXISTS "leg2OriginStationId" TEXT,
ADD COLUMN IF NOT EXISTS "leg2DestinationStationId" TEXT,
ADD COLUMN IF NOT EXISTS "leg2SeatClassId" TEXT,
ADD COLUMN IF NOT EXISTS "returnLeg2ScheduleId" TEXT,
ADD COLUMN IF NOT EXISTS "returnLeg2OriginStationId" TEXT,
ADD COLUMN IF NOT EXISTS "returnLeg2DestStationId" TEXT,
ADD COLUMN IF NOT EXISTS "returnLeg2SeatClassId" TEXT,
ADD COLUMN IF NOT EXISTS "outboundBoardedAt" TIMESTAMP(3),
ADD COLUMN IF NOT EXISTS "returnBoardedAt" TIMESTAMP(3);
-- Add ReturnLegStatus enum and column
DO $$ BEGIN
CREATE TYPE "passenger"."ReturnLegStatus" AS ENUM (
'NOT_APPLICABLE', 'BOTH_USED', 'OUTBOUND_ONLY', 'INBOUND_ONLY', 'NEITHER_USED'
);
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
ALTER TABLE "passenger"."Booking"
ADD COLUMN IF NOT EXISTS "returnLegStatus" "passenger"."ReturnLegStatus" NOT NULL DEFAULT 'NOT_APPLICABLE';
-- Add missing columns to other tables
ALTER TABLE "passenger"."GateValidationLog" ADD COLUMN IF NOT EXISTS "leg" TEXT;
ALTER TABLE "passenger"."BookingSeat" ADD COLUMN IF NOT EXISTS "leg" INTEGER NOT NULL DEFAULT 1;
ALTER TABLE "passenger"."BookingSeat" ADD COLUMN IF NOT EXISTS "scheduleId" TEXT;
ALTER TABLE "passenger"."Ticket" ADD COLUMN IF NOT EXISTS "boardedAt" TIMESTAMP(3);
ALTER TABLE "passenger"."SeatClass" ALTER COLUMN "baseFareMinor" SET DEFAULT 0;
ALTER TABLE "passenger"."Ticket" ALTER COLUMN "status" SET DEFAULT 'ACTIVE';
CREATE INDEX IF NOT EXISTS "Booking_bookingType_idx" ON "passenger"."Booking"("bookingType");

View File

@@ -1,30 +0,0 @@
-- Add contact fields to Booking table
ALTER TABLE "passenger"."Booking"
ADD COLUMN "contactEmail" TEXT,
ADD COLUMN "contactPhone" TEXT;
-- Create SavedPassengerProfile table
CREATE TABLE "passenger"."SavedPassengerProfile" (
"id" TEXT NOT NULL,
"userId" TEXT,
"deviceId" TEXT,
"passengerName" TEXT NOT NULL,
"dateOfBirth" TIMESTAMP(3) NOT NULL,
"idDocumentType" "passenger"."IdDocumentType" NOT NULL,
"passportNumber" TEXT,
"passportCountry" TEXT,
"nationality" TEXT,
"phone" TEXT,
"email" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "SavedPassengerProfile_pkey" PRIMARY KEY ("id")
);
-- Create indexes
CREATE INDEX "SavedPassengerProfile_userId_idx" ON "passenger"."SavedPassengerProfile"("userId");
CREATE INDEX "SavedPassengerProfile_deviceId_idx" ON "passenger"."SavedPassengerProfile"("deviceId");
-- Add comment
COMMENT ON TABLE "passenger"."SavedPassengerProfile" IS 'Stores passenger details for quick rebooking (by userId or deviceId)';

File diff suppressed because it is too large Load Diff

View File

@@ -1,231 +0,0 @@
import { PrismaClient, SeatKind } from '@prisma/client';
import * as bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function main() {
console.log('🌱 Starting complete seed...\n');
// 1. STATIONS
console.log('📍 Seeding stations...');
const stationData = [
{ code: 'SBT', name: 'Sebeta', city: 'Sebeta', countryCode: 'ET', lat: 8.9167, lng: 38.6167 },
{ code: 'LBU', name: 'Labu', city: 'Labu', countryCode: 'ET', lat: 8.8500, lng: 38.7000 },
{ code: 'IND', name: 'Indode', city: 'Indode', countryCode: 'ET', lat: 8.7800, lng: 38.8200 },
{ code: 'BSH', name: 'Bishoftu', city: 'Bishoftu', countryCode: 'ET', lat: 8.7500, lng: 38.9833 },
{ code: 'MJO', name: 'Mojo', city: 'Mojo', countryCode: 'ET', lat: 8.6000, lng: 39.1200 },
{ code: 'ADM', name: 'Adama', city: 'Adama', countryCode: 'ET', lat: 8.5400, lng: 39.2675 },
{ code: 'DDW', name: 'Diredawa', city: 'Diredawa', countryCode: 'ET', lat: 9.5931, lng: 41.8661 },
{ code: 'NGD', name: 'Nagad', city: 'Nagad', countryCode: 'DJ', timezone: 'Africa/Djibouti', lat: 11.5720, lng: 43.1456 },
];
const stations = [];
for (const s of stationData) {
stations.push(await prisma.station.upsert({ where: { code: s.code }, update: {}, create: s }));
}
console.log(`${stations.length} stations\n`);
// 2. SEAT CLASSES
console.log('💺 Seeding seat classes...');
const scEconomy = await prisma.seatClass.upsert({
where: { name: 'Economy Regular' },
update: {},
create: { name: 'Economy Regular', description: 'Standard economy', basePrice: 25000, isActive: true },
});
const scBed = await prisma.seatClass.upsert({
where: { name: 'Economy Bed' },
update: {},
create: { name: 'Economy Bed', description: 'Economy bed', basePrice: 35000, isActive: true },
});
console.log(`✅ 2 seat classes\n`);
// 3. ROUTES
console.log('🛤️ Seeding routes...');
const route1 = await prisma.route.upsert({
where: { code: 'SBT-NGD' },
update: {},
create: { code: 'SBT-NGD', name: 'Sebeta-Nagad Express', effectiveFrom: new Date('2026-01-01'), active: true },
});
await prisma.routeStop.createMany({
data: [
{ routeId: route1.id, stationId: stations[0].id, sequence: 1, distanceKm: 0 },
{ routeId: route1.id, stationId: stations[1].id, sequence: 2, distanceKm: 15 },
{ routeId: route1.id, stationId: stations[2].id, sequence: 3, distanceKm: 28 },
{ routeId: route1.id, stationId: stations[3].id, sequence: 4, distanceKm: 45 },
{ routeId: route1.id, stationId: stations[4].id, sequence: 5, distanceKm: 73 },
{ routeId: route1.id, stationId: stations[5].id, sequence: 6, distanceKm: 99 },
{ routeId: route1.id, stationId: stations[6].id, sequence: 7, distanceKm: 378 },
{ routeId: route1.id, stationId: stations[7].id, sequence: 8, distanceKm: 756 },
],
skipDuplicates: true,
});
await prisma.routeFareRule.createMany({
data: [
{ routeId: route1.id, seatClassId: scEconomy.id, passengerCategory: 'ADULT', baseFareMinor: 65000, validFrom: new Date('2026-01-01') },
{ routeId: route1.id, seatClassId: scEconomy.id, passengerCategory: 'CHILD', baseFareMinor: 65000, validFrom: new Date('2026-01-01') },
{ routeId: route1.id, seatClassId: scBed.id, passengerCategory: 'ADULT', baseFareMinor: 91000, validFrom: new Date('2026-01-01') },
{ routeId: route1.id, seatClassId: scBed.id, passengerCategory: 'CHILD', baseFareMinor: 91000, validFrom: new Date('2026-01-01') },
],
skipDuplicates: true,
});
console.log(`✅ 1 route with stops and fares\n`);
// 4. TRAINS
console.log('🚂 Seeding trains...');
const train = await prisma.train.upsert({
where: { number: '301' },
update: {},
create: { number: '301', name: 'Express 301', description: 'Main Express' },
});
console.log(`✅ 1 train\n`);
// 5. COACHES & SEATS
console.log('🚃 Seeding coaches...');
const coach1 = await prisma.coach.upsert({
where: { coachNumber: 'C-A1' },
update: {},
create: { coachNumber: 'C-A1', label: 'A', seatClassId: scEconomy.id, mode: 'seat', totalUnits: 20 },
});
const existingSeats = await prisma.seat.count({ where: { coachId: coach1.id } });
if (existingSeats === 0) {
const seats = [];
for (let row = 1; row <= 5; row++) {
for (const col of ['A', 'B', 'C', 'D']) {
seats.push({
coachId: coach1.id,
row,
col,
label: `${row}${col}`,
seatNumber: `A${row}${col}`,
kind: 'STANDARD' as SeatKind,
});
}
}
await prisma.seat.createMany({ data: seats });
}
console.log(`✅ 1 coach with 20 seats\n`);
// 6. SCHEDULE
console.log('📅 Seeding schedule...');
const existingSchedules = await prisma.trainSchedule.findMany({ where: { trainId: train.id }, select: { id: true } });
if (existingSchedules.length > 0) {
const scheduleIds = existingSchedules.map(s => s.id);
const bookingIds = (
await prisma.booking.findMany({ where: { scheduleId: { in: scheduleIds } }, select: { id: true } })
).map(b => b.id);
// Delete booking children in FK-safe order before deleting the bookings themselves
await prisma.foodOrderItem.deleteMany({ where: { order: { bookingId: { in: bookingIds } } } });
await prisma.foodOrder.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.paymentIntent.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.ticket.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.agentBooking.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.bookingModification.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.bookingCancellation.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.baggageBooking.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.bookingSeat.deleteMany({ where: { bookingId: { in: bookingIds } } });
await prisma.booking.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
await prisma.fareRule.deleteMany({ where: { tripId: { in: scheduleIds } } });
await prisma.tripStopTime.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
await prisma.coachAssignment.deleteMany({ where: { scheduleId: { in: scheduleIds } } });
await prisma.trainSchedule.deleteMany({ where: { trainId: train.id } });
}
const schedule = await prisma.trainSchedule.create({
data: {
trainId: train.id,
routeId: route1.id,
originStationId: stations[0].id,
destinationStationId: stations[7].id,
departureAt: new Date('2026-06-15T06:00:00Z'),
arrivalAt: new Date('2026-06-15T22:00:00Z'),
durationMinutes: 960,
stopsCount: 8,
},
});
await prisma.coachAssignment.create({
data: { scheduleId: schedule.id, coachId: coach1.id, positionNumber: 1 },
});
await prisma.tripStopTime.createMany({
data: [
{ scheduleId: schedule.id, stationId: stations[0].id, sequence: 1, plannedDepartureAt: new Date('2026-06-15T06:00:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[1].id, sequence: 2, plannedArrivalAt: new Date('2026-06-15T07:00:00Z'), plannedDepartureAt: new Date('2026-06-15T07:05:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[2].id, sequence: 3, plannedArrivalAt: new Date('2026-06-15T08:00:00Z'), plannedDepartureAt: new Date('2026-06-15T08:05:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[3].id, sequence: 4, plannedArrivalAt: new Date('2026-06-15T09:00:00Z'), plannedDepartureAt: new Date('2026-06-15T09:10:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[4].id, sequence: 5, plannedArrivalAt: new Date('2026-06-15T10:00:00Z'), plannedDepartureAt: new Date('2026-06-15T10:10:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[5].id, sequence: 6, plannedArrivalAt: new Date('2026-06-15T11:00:00Z'), plannedDepartureAt: new Date('2026-06-15T11:15:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[6].id, sequence: 7, plannedArrivalAt: new Date('2026-06-15T15:00:00Z'), plannedDepartureAt: new Date('2026-06-15T15:20:00Z'), status: 'UPCOMING' },
{ scheduleId: schedule.id, stationId: stations[7].id, sequence: 8, plannedArrivalAt: new Date('2026-06-15T22:00:00Z'), status: 'UPCOMING' },
],
});
console.log(`✅ 1 schedule with stops\n`);
// 7. USERS
console.log('👥 Seeding users...');
const adminHash = await bcrypt.hash('admin123', 10);
const userHash = await bcrypt.hash('password123', 10);
await prisma.user.upsert({
where: { email: 'admin@edr-platform.com' },
update: {},
create: { fullName: 'Admin', email: 'admin@edr-platform.com', phone: '+251900000000', passwordHash: adminHash, role: 'ADMIN' },
});
const user = await prisma.user.upsert({
where: { email: 'abebe@email.com' },
update: {},
create: { fullName: 'Abebe Kebede', email: 'abebe@email.com', phone: '+251912345678', passwordHash: userHash, nationality: 'Ethiopian' },
});
let passenger = await prisma.passenger.findUnique({ where: { userId: user.id } });
if (!passenger) {
passenger = await prisma.passenger.create({ data: { userId: user.id } });
await prisma.loyaltyAccount.create({ data: { passengerId: passenger.id, pointsBalance: 1000, tier: 'BRONZE' } });
await prisma.walletAccount.create({ data: { passengerId: passenger.id, balanceMinor: 100000 } });
}
console.log(`✅ 2 users\n`);
// 8. SUPPORTING DATA
console.log('📦 Seeding supporting data...');
await prisma.paymentMethod.upsert({
where: { type: 'TELEBIRR' },
update: {},
create: { type: 'TELEBIRR', displayName: 'Telebirr', region: 'ETHIOPIA', currency: 'ETB', enabled: true, sortOrder: 1 },
});
await prisma.currencyExchangeRate.deleteMany({});
await prisma.currencyExchangeRate.createMany({
data: [
{ fromCurrency: 'ETB', toCurrency: 'ETB', rate: 1.0, effectiveDate: new Date() },
{ fromCurrency: 'ETB', toCurrency: 'USD', rate: 0.018, effectiveDate: new Date() },
{ fromCurrency: 'ETB', toCurrency: 'DJF', rate: 3.2, effectiveDate: new Date() },
],
});
console.log(`✅ Payment methods and currencies\n`);
console.log('✅ SEED COMPLETE!\n');
console.log('📋 Summary:');
console.log(' - 8 Stations');
console.log(' - 2 Seat Classes');
console.log(' - 1 Route with 8 stops');
console.log(' - 1 Train with 1 schedule');
console.log(' - 1 Coach with 20 seats');
console.log(' - 2 Users (Admin + Passenger)');
console.log('\n🔑 Credentials:');
console.log(' Admin: admin@edr-platform.com / admin123');
console.log(' User: abebe@email.com / password123');
}
main()
.catch((e) => {
console.error('❌ Error:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

File diff suppressed because it is too large Load Diff