import { Injectable, Logger } from '@nestjs/common'; import { DataSource } from 'typeorm'; /** * EDR's load/unload facilities, mapped onto the yards that already represent them. * * The codes are historical and don't read like the facility names, so map by code * and never by label: Indode is `KALITY` ("Gelan Multi Purpose Port (Indode)") and * Sebeta is `LEGACY_DEST` ("Sebeta"). Creating fresh INDODE/SEBETA yards would * split data that existing routes and bookings already point at. * * Only Indode stores cargo, so it is the only facility with a warehouse — the rest * move cargo on and off the train, which is why they accrue no storage/demurrage. * * Negad is deliberately absent: there are two candidates (`NAGAD` "DCT/SGDT" in * Djibouti and `NEGAD_FY_BCC` in Ethiopia, currently inactive) and it is not yet * settled which is the intercity facility. */ const FACILITY_YARDS: Array<{ code: string; facility: string; hasWarehouse: boolean }> = [ { code: 'KALITY', facility: 'Indode', hasWarehouse: true }, { code: 'LEGACY_DEST', facility: 'Sebeta', hasWarehouse: false }, { code: 'MOJO', facility: 'Modjo', hasWarehouse: false }, { code: 'ADAMA', facility: 'Adama', hasWarehouse: false }, { code: 'DIRE_DAWA', facility: 'Dire Dawa', hasWarehouse: false }, ]; @Injectable() export class YardFacilitiesSeeder { private readonly logger = new Logger(YardFacilitiesSeeder.name); constructor(private readonly dataSource: DataSource) {} /** * Idempotent: flags existing yards and upserts their facility record. Creates no * yards — a missing code is logged and skipped rather than invented. */ async run(): Promise { for (const { code, facility, hasWarehouse } of FACILITY_YARDS) { const [yard]: Array<{ id: string }> = await this.dataSource.query( `SELECT id FROM freight.yards WHERE code = $1 AND deleted_at IS NULL`, [code], ); if (!yard) { this.logger.warn(`Yard ${code} (${facility}) not found — skipping facility flag`); continue; } await this.dataSource.query( `UPDATE freight.yards SET has_facility = true, updated_at = NOW() WHERE id = $1 AND has_facility = false`, [yard.id], ); await this.dataSource.query( `INSERT INTO freight.yard_facilities (yard_id, has_warehouse, equipment_notes) VALUES ($1, $2, $3) ON CONFLICT (yard_id) WHERE deleted_at IS NULL DO UPDATE SET has_warehouse = EXCLUDED.has_warehouse, updated_at = NOW()`, [yard.id, hasWarehouse, `${facility} load/unload facility`], ); } this.logger.log( `Yard facilities seeded: ${FACILITY_YARDS.map((f) => f.facility).join(', ')}`, ); } }