Files
edr-platform/apps/edr-freight-api/src/migrations/1920000000000-AddScheduleWindowRuleSnapshot.ts

59 lines
2.7 KiB
TypeScript

import { MigrationInterface, QueryRunner } from "typeorm";
/**
* Snapshot the booking-window rule onto each train schedule.
*
* A schedule's window (open time + reopen cycles) must be frozen to the rule it
* was created with: a later global-rules edit applies only to FUTURE schedules,
* while an already-open schedule keeps its base rule. Previously the batch board
* recomputed windows from the LIVE global config, so editing the rule redrew the
* board for open schedules (a synthetic grid that no longer matched the window
* the customer was shown). These columns give the board a per-schedule rule to
* derive its display windows from.
*
* Existing rows are backfilled from the current global-rules singleton — the best
* available base, since they never stored one. Their stamped windowOpensAt/
* windowClosesAt are still real, so only projected reopen cycles rely on the
* backfill.
*/
export class AddScheduleWindowRuleSnapshot1920000000000
implements MigrationInterface
{
name = "AddScheduleWindowRuleSnapshot1920000000000";
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE freight.train_schedules
ADD COLUMN IF NOT EXISTS rule_window_open_hour integer,
ADD COLUMN IF NOT EXISTS rule_window_duration_hours numeric(6, 4),
ADD COLUMN IF NOT EXISTS rule_reopen_delay_minutes integer,
ADD COLUMN IF NOT EXISTS rule_import_window_lead_days integer,
ADD COLUMN IF NOT EXISTS rule_export_booking_lead_hours integer;
`);
// Backfill from the global-rules singleton so pre-existing schedules render.
await queryRunner.query(`
UPDATE freight.train_schedules ts
SET
rule_window_open_hour = COALESCE(ts.rule_window_open_hour, r.window_open_hour),
rule_window_duration_hours = COALESCE(ts.rule_window_duration_hours, r.window_duration_hours),
rule_reopen_delay_minutes = COALESCE(ts.rule_reopen_delay_minutes, r.reopen_delay_minutes),
rule_import_window_lead_days = COALESCE(ts.rule_import_window_lead_days, r.import_window_lead_days),
rule_export_booking_lead_hours = COALESCE(ts.rule_export_booking_lead_hours, r.export_booking_lead_hours)
FROM freight.train_scheduling_global_rules r
WHERE ts.rule_window_open_hour IS NULL;
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE freight.train_schedules
DROP COLUMN IF EXISTS rule_window_open_hour,
DROP COLUMN IF EXISTS rule_window_duration_hours,
DROP COLUMN IF EXISTS rule_reopen_delay_minutes,
DROP COLUMN IF EXISTS rule_import_window_lead_days,
DROP COLUMN IF EXISTS rule_export_booking_lead_hours;
`);
}
}