mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix: ( seed ) add try catch
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Prisma, PrismaClient } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { randomUUID as uuidv4 } from 'crypto';
|
||||
|
||||
@@ -224,12 +224,10 @@ async function seedCoaches() {
|
||||
create: coach,
|
||||
});
|
||||
|
||||
// Rebuild the coach's seats from scratch. A plain upsert keyed on
|
||||
// coachId_seatNumber can't reconcile a changed layout (it's blind to the
|
||||
// @@unique([coachId, row, col]) constraint), so stale row/col data collides.
|
||||
await prisma.seat.deleteMany({ where: { coachId: c.id } });
|
||||
|
||||
const seats: Prisma.SeatCreateManyInput[] = [];
|
||||
// Idempotently reconcile the coach's seats. Upsert keyed on the
|
||||
// @@unique([coachId, row, col]) constraint so a re-seed updates existing
|
||||
// rows in place instead of deleting them. Deleting Seats fails with a P2003
|
||||
// FK violation once BookingSeat/SeatBlock/TicketSeat rows reference them.
|
||||
let seatIndex = 1;
|
||||
for (let row = 1; row <= Math.ceil(coach.capacity / 2); row++) {
|
||||
for (const col of ['A', 'B', 'C', 'D']) {
|
||||
@@ -241,19 +239,21 @@ async function seedCoaches() {
|
||||
else bedPosition = 'lower';
|
||||
}
|
||||
|
||||
seats.push({
|
||||
coachId: c.id,
|
||||
const seatData = {
|
||||
seatNumber: seatIndex.toString(),
|
||||
row,
|
||||
col,
|
||||
isWindow: col === 'A' || col === 'D',
|
||||
isAisle: col === 'B' || col === 'C',
|
||||
bedPosition,
|
||||
};
|
||||
|
||||
await prisma.seat.upsert({
|
||||
where: { coachId_row_col: { coachId: c.id, row, col } },
|
||||
update: seatData,
|
||||
create: { coachId: c.id, row, col, ...seatData },
|
||||
});
|
||||
seatIndex++;
|
||||
}
|
||||
}
|
||||
await prisma.seat.createMany({ data: seats });
|
||||
totalSeats += coach.capacity;
|
||||
}
|
||||
console.log(` ✅ ${coaches.length} coaches with ${totalSeats} seats created`);
|
||||
@@ -552,25 +552,49 @@ async function seedFraudRules() {
|
||||
console.log(` ✅ ${rules.length} fraud detection rules created`);
|
||||
}
|
||||
|
||||
// Run a seed step in isolation: if it throws (FK conflict, duplicate row,
|
||||
// missing record, etc.) log the error and keep going so the rest of the seed —
|
||||
// and the API startup that follows it — are never blocked by one bad step.
|
||||
async function runStep(name: string, step: () => Promise<void>): Promise<boolean> {
|
||||
try {
|
||||
await step();
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(`⚠️ Seed step "${name}" failed — skipping and continuing:`, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🌱 Comprehensive EDR Seed Starting...\n');
|
||||
|
||||
await seedSystemUsers();
|
||||
await seedStations();
|
||||
await seedCoachTypesAndClasses();
|
||||
await seedRoute();
|
||||
await seedCoaches();
|
||||
await seedTrips();
|
||||
await seedFareRules();
|
||||
await seedCurrency();
|
||||
await seedPaymentMethods();
|
||||
await seedNotificationTemplates();
|
||||
await seedMenuAndFood();
|
||||
await seedPromotions();
|
||||
await seedFAQ();
|
||||
await seedFraudRules();
|
||||
const steps: Array<[string, () => Promise<void>]> = [
|
||||
['system users', seedSystemUsers],
|
||||
['stations', seedStations],
|
||||
['coach types & classes', seedCoachTypesAndClasses],
|
||||
['route', seedRoute],
|
||||
['coaches', seedCoaches],
|
||||
['trips', seedTrips],
|
||||
['fare rules', seedFareRules],
|
||||
['currency', seedCurrency],
|
||||
['payment methods', seedPaymentMethods],
|
||||
['notification templates', seedNotificationTemplates],
|
||||
['menu & food', seedMenuAndFood],
|
||||
['promotions', seedPromotions],
|
||||
['FAQ', seedFAQ],
|
||||
['fraud rules', seedFraudRules],
|
||||
];
|
||||
|
||||
console.log('\n✅ Seed complete!\n');
|
||||
let failed = 0;
|
||||
for (const [name, step] of steps) {
|
||||
if (!(await runStep(name, step))) failed++;
|
||||
}
|
||||
|
||||
if (failed > 0) {
|
||||
console.warn(`\n⚠️ Seed finished with ${failed}/${steps.length} step(s) failed (see logs above).\n`);
|
||||
} else {
|
||||
console.log('\n✅ Seed complete!\n');
|
||||
}
|
||||
console.log('🔑 System Users:');
|
||||
console.log(' Admin: admin@edr-platform.com / admin123');
|
||||
console.log(' Passenger: kelemu@email.com / password123');
|
||||
@@ -581,8 +605,10 @@ async function main() {
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error('❌ Seed failed:', e);
|
||||
process.exit(1);
|
||||
// Intentionally do NOT process.exit(1): the docker entrypoint runs under
|
||||
// `set -e`, so a non-zero exit here would abort container startup and the
|
||||
// API would never boot. Log and exit cleanly instead.
|
||||
console.error('❌ Seed crashed unexpectedly — continuing so the API can start:', e);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
|
||||
Reference in New Issue
Block a user