mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 15:30:56 +00:00
SELECT BOX
This commit is contained in:
@@ -69,6 +69,7 @@ import { MarshallingDemoTrainsSeeder } from "./seed/marshalling-demo-trains.seed
|
||||
import { FreightPermissionKeyMigrationSeeder } from "./seed/freight-permission-key-migration.seeder";
|
||||
import { DemoFreightDataSeeder } from "./seed/demo-freight-data.seeder";
|
||||
import { GovCompaniesSeeder } from "./seed/gov-companies.seeder";
|
||||
import { EdrTruckFleetSeeder } from "./seed/edr-truck-fleet.seeder";
|
||||
import { ApprovedFirstLastMileDemoBookingsSeeder } from "./seed/approved-first-lastmile-demo-bookings.seeder";
|
||||
import { PaidImportExportMileDemoSeeder } from "./seed/paid-import-export-mile-demo.seeder";
|
||||
//New Trains, Wagons, Container and Cargo management modules
|
||||
@@ -201,6 +202,7 @@ import { LoggerMiddleware } from "./logger.middleware";
|
||||
FreightPermissionKeyMigrationSeeder,
|
||||
DemoFreightDataSeeder,
|
||||
GovCompaniesSeeder,
|
||||
EdrTruckFleetSeeder,
|
||||
IndodeFacilitySeeder,
|
||||
Batch14TestDataSeeder,
|
||||
Batch5TestDataSeeder,
|
||||
@@ -233,6 +235,7 @@ export class AppModule implements OnApplicationBootstrap {
|
||||
private readonly freightPermissionKeyMigrationSeeder: FreightPermissionKeyMigrationSeeder,
|
||||
private readonly demoFreightDataSeeder: DemoFreightDataSeeder,
|
||||
private readonly govCompaniesSeeder: GovCompaniesSeeder,
|
||||
private readonly edrTruckFleetSeeder: EdrTruckFleetSeeder,
|
||||
) { }
|
||||
|
||||
async onApplicationBootstrap() {
|
||||
@@ -263,6 +266,7 @@ export class AppModule implements OnApplicationBootstrap {
|
||||
// Government entities (with importer/exporter profiles) that government
|
||||
// bookings bill to. Idempotent — keyed by fixed IDs.
|
||||
await this.govCompaniesSeeder.run();
|
||||
await this.edrTruckFleetSeeder.run();
|
||||
}
|
||||
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
/**
|
||||
* Repair migration. `SeparateVehicleAvailability1890000000000` is recorded in
|
||||
* public.migrations but the `availability` column is absent on some databases
|
||||
* (recorded-but-not-applied drift). Because the original is already recorded,
|
||||
* TypeORM will not re-run it, so `vehiclesService.findAll` (a query builder that
|
||||
* selects every entity column) 500s with `column "availability" does not exist`.
|
||||
*
|
||||
* This re-adds the column idempotently and backfills. Safe to run everywhere:
|
||||
* `IF NOT EXISTS` makes it a no-op where the column already exists.
|
||||
*/
|
||||
export class RepairVehicleAvailabilityColumn2110000000000
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = "RepairVehicleAvailabilityColumn2110000000000";
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE freight.vehicles
|
||||
ADD COLUMN IF NOT EXISTS availability varchar DEFAULT 'FREE'
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
UPDATE freight.vehicles SET availability = 'FREE' WHERE availability IS NULL
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(): Promise<void> {
|
||||
// No-op: dropping a column other code now depends on would reintroduce the
|
||||
// drift. The original SeparateVehicleAvailability migration owns the column.
|
||||
}
|
||||
}
|
||||
94
apps/edr-freight-api/src/seed/edr-truck-fleet.seeder.ts
Normal file
94
apps/edr-freight-api/src/seed/edr-truck-fleet.seeder.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
/**
|
||||
* EDR-owned truck fleet used by first-mile / last-mile pickup & delivery.
|
||||
* These 62 trucks used to be a hardcoded list in the truck-arrival UI; the
|
||||
* first/last-mile flows now read the fleet from `freight.vehicles` via
|
||||
* VehiclesService, so the fleet must exist as vehicle rows.
|
||||
*
|
||||
* `[powerPlate, trailerPlate]` in fleet order 1..62. Region code "03-ET" is
|
||||
* shared by every truck. NB: 56 trucks are configured for 40ft containers, 6
|
||||
* for 20ft only — the specific 6 are not yet confirmed, so all default to 40ft.
|
||||
* List `TWENTY_FT_SEQS` when known.
|
||||
*/
|
||||
const EDR_TRUCK_FLEET: ReadonlyArray<readonly [string, string]> = [
|
||||
['A45843', '43495'], ['A45866', '43470'], ['A45853', '43508'], ['A45849', '43414'],
|
||||
['A45845', '43492'], ['A45820', '43487'], ['A45842', '43478'], ['A45841', '43515'],
|
||||
['A45832', '43504'], ['A45856', '43510'], ['A45865', '43490'], ['A45855', '43485'],
|
||||
['A45840', '43499'], ['A45867', '43493'], ['A45833', '43466'], ['A45858', '43496'],
|
||||
['A45819', '43474'], ['A45834', '43502'], ['A45868', '43469'], ['A45831', '43488'],
|
||||
['A45828', '43479'], ['A45850', '43505'], ['A45823', '43480'], ['A45838', '43472'],
|
||||
['A45854', '43500'], ['A45839', '43486'], ['A45861', '43513'], ['A45830', '43501'],
|
||||
['A45826', '43498'], ['A45836', '43467'], ['A45822', '43512'], ['A45821', '43210'],
|
||||
['A45837', '43475'], ['A45860', '43497'], ['A45863', '43477'], ['A45825', '43483'],
|
||||
['A45829', '43473'], ['A45824', '43491'], ['A45857', '43481'], ['A45851', '43509'],
|
||||
['A45827', '43468'], ['A45859', '43887'], ['A45846', '43471'], ['A45847', '43511'],
|
||||
['A45852', '43484'], ['A45844', '43476'], ['A45835', '43482'], ['A45864', '43503'],
|
||||
['A45848', '43494'], ['A45862', '43465'], ['A39105', '41218'], ['A39098', '41220'],
|
||||
['A29900', '41865'], ['A39097', '41226'], ['A39104', '41225'], ['A39103', '41223'],
|
||||
['A39106', '41221'], ['A39107', '41215'], ['A39094', '41222'], ['A39099', '41216'],
|
||||
['A39092', '41224'], ['A31801', '41214'],
|
||||
];
|
||||
|
||||
/** Fleet sequence numbers (1-based) that are 20ft-only. 6 of 62 — fill once confirmed. */
|
||||
const TWENTY_FT_SEQS = new Set<number>();
|
||||
|
||||
@Injectable()
|
||||
export class EdrTruckFleetSeeder {
|
||||
private readonly logger = new Logger(EdrTruckFleetSeeder.name);
|
||||
|
||||
constructor(private readonly dataSource: DataSource) {}
|
||||
|
||||
/**
|
||||
* Idempotent: `ON CONFLICT (plate_number) DO NOTHING`. Uses raw SQL with an
|
||||
* explicit column list on purpose — the `Vehicle` entity declares an
|
||||
* `availability` column that does not exist in the DB (schema drift), so a
|
||||
* repository insert would fail. This inserts only real columns.
|
||||
*/
|
||||
async run(): Promise<void> {
|
||||
const columns = [
|
||||
'code', 'plate_number', 'registration_number', 'power_plate_no', 'trailer_plate_no',
|
||||
'vehicle_type', 'manufacturer', 'model', 'year', 'fuel_type', 'capacity',
|
||||
'status', 'ownership', 'currency', 'description',
|
||||
];
|
||||
|
||||
const rows: unknown[][] = EDR_TRUCK_FLEET.map(([power, trailer], i) => {
|
||||
const seq = i + 1;
|
||||
const ft = TWENTY_FT_SEQS.has(seq) ? '20ft' : '40ft';
|
||||
return [
|
||||
`EDR-TRK-${String(seq).padStart(3, '0')}`,
|
||||
`03-ET ${power}`,
|
||||
trailer,
|
||||
`03-ET ${power}`,
|
||||
trailer,
|
||||
'TRUCK',
|
||||
'EDR',
|
||||
`${ft} Container Truck`,
|
||||
2018,
|
||||
'DIESEL',
|
||||
TWENTY_FT_SEQS.has(seq) ? 1 : 2,
|
||||
'ACTIVE',
|
||||
'EDR',
|
||||
'ETB',
|
||||
`EDR-owned container truck configured for ${ft} containers.`,
|
||||
];
|
||||
});
|
||||
|
||||
const params: unknown[] = [];
|
||||
const valueGroups = rows.map((row, r) => {
|
||||
const placeholders = row.map((_, c) => `$${r * columns.length + c + 1}`);
|
||||
params.push(...row);
|
||||
return `(${placeholders.join(', ')})`;
|
||||
});
|
||||
|
||||
const result = await this.dataSource.query(
|
||||
`INSERT INTO freight.vehicles (${columns.join(', ')}) VALUES ${valueGroups.join(', ')} ` +
|
||||
`ON CONFLICT (plate_number) DO NOTHING`,
|
||||
params,
|
||||
);
|
||||
|
||||
const inserted = Array.isArray(result) ? result.length : (result?.affectedRows ?? 0);
|
||||
this.logger.log(`EDR truck fleet seed: ${EDR_TRUCK_FLEET.length} trucks ensured (new: ${inserted}).`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user