Files
edr-platform/apps/edr-freight-api/src/seed/batch7-test-data.seeder.ts
Hagernesh 35c3341baf feat(warehouse): Batch 7 — Import Arrive Queue (arrived import trains, read-only)
- SchedulingReadFacade: importArriveQueue() + importTrainDetail() — read-only SELECTs only,
  direction derived from origin/destination station countries (route-based), so EXPORT/DOMESTIC
  trains are excluded. Per-train booking/container/cargo counts.
- GET /warehouse-inventory/import/arrive-queue + /import/trains/:scheduleId/items
- Import tab restructured into sub-tabs: Arrive Queue (implemented) / Unloaded Queue /
  Dispatch Queue (placeholders for next batch)
- ImportArriveQueueTab: train table (schedule id, train #, route, origin, destination, arrival,
  bookings/containers/cargoes, status) with Open (expandable assigned-items detail) + Auto Unload
  (reuses existing per-booking unload endpoint over the train's bookings)
- Batch7TestDataSeeder: 1 arrived IMPORT train (SEED-IMP-001) + 1 arrived EXPORT train
  (SEED-EXP-001, proves exclusion); idempotent
- Train schedule service logic untouched (facade is SELECT-only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 11:15:31 +00:00

104 lines
4.0 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { Booking } from '../modules/bookings/entities/booking.entity';
import { Locomotive } from '../modules/locomotives/entities/locomotive.entity';
import { TrainSchedule } from '../modules/train-schedules/entities/train-schedule.entity';
import { TrainScheduleBooking } from '../modules/train-schedules/entities/train-schedule-booking.entity';
import { TrainSet } from '../modules/train-sets/entities/train-set.entity';
/**
* Seeds two ARRIVED train schedules so the Import Arrive Queue (Batch 7) is demonstrable:
* - SEED-IMP-TRAIN-01: DJIB_PORT → MOJO (IMPORT) linked to booking SEED-IMP-001 → SHOWS
* - SEED-EXP-TRAIN-01: MOJO → DJIB_PORT (EXPORT) linked to booking SEED-EXP-001 → must NOT show
*
* Read-only train-schedule SERVICE logic is untouched; this only inserts fixture rows.
* Idempotent: guards on the import train number.
*/
@Injectable()
export class Batch7TestDataSeeder {
private readonly logger = new Logger(Batch7TestDataSeeder.name);
constructor(private readonly dataSource: DataSource) {}
async run(): Promise<void> {
const scheduleRepo = this.dataSource.getRepository(TrainSchedule);
const existing = await scheduleRepo.findOne({ where: { trainNumber: 'SEED-IMP-TRAIN-01' } });
if (existing) {
this.logger.log('Batch 7 test data already seeded, skipping');
return;
}
try {
const bookingRepo = this.dataSource.getRepository(Booking);
const locoRepo = this.dataSource.getRepository(Locomotive);
const trainSetRepo = this.dataSource.getRepository(TrainSet);
const scheduleBookingRepo = this.dataSource.getRepository(TrainScheduleBooking);
const importBooking = await bookingRepo.findOne({ where: { reference: 'SEED-IMP-001' } });
const exportBooking = await bookingRepo.findOne({ where: { reference: 'SEED-EXP-001' } });
if (!importBooking) {
this.logger.warn('SEED-IMP-001 booking not found; skipping Batch 7 seed');
return;
}
// One shared locomotive is fine — train_set.locomotive_id is not unique.
const loco =
(await locoRepo.findOne({ where: { code: 'SEED-LOCO-01' } })) ??
(await locoRepo.save(
locoRepo.create({ code: 'SEED-LOCO-01', name: 'Seed Locomotive', maxPullWeightTons: 4000 }),
));
const now = new Date();
const arrival = new Date(now.getTime() - 3600 * 1000);
const departure = new Date(now.getTime() - 6 * 3600 * 1000);
const makeArrivedTrain = async (
trainNumber: string,
booking: Booking,
): Promise<void> => {
const trainSet = await trainSetRepo.save(
trainSetRepo.create({
locomotiveId: loco.id,
totalWeightTons: 500,
totalLengthMeters: 300,
wagonCount: 10,
status: 'COMPLETED',
}),
);
const schedule = await scheduleRepo.save(
scheduleRepo.create({
trainSetId: trainSet.id,
originStationId: booking.originYardId,
destinationStationId: booking.destinationYardId,
scheduledDepartureDate: departure,
scheduledArrivalDate: arrival,
actualArrivalAt: arrival,
status: 'ARRIVED' as TrainSchedule['status'],
trainNumber,
}),
);
await scheduleBookingRepo.save(
scheduleBookingRepo.create({ trainScheduleId: schedule.id, bookingId: booking.id }),
);
this.logger.log(`Seeded arrived train ${trainNumber} → booking ${booking.reference}`);
};
await makeArrivedTrain('SEED-IMP-TRAIN-01', importBooking);
if (exportBooking) {
await makeArrivedTrain('SEED-EXP-TRAIN-01', exportBooking);
}
this.logger.log('✅ Batch 7 arrive-queue test data seeded successfully');
} catch (error) {
this.logger.error(
`Batch7TestDataSeeder failed: ${error instanceof Error ? error.message : String(error)}`,
);
}
}
}