import { MigrationInterface, QueryRunner } from 'typeorm'; /** * Multi-locomotive train sets: a train set is now pulled by 2+ locomotives. * * Adds the `freight.train_set_locomotives` link table (train set ⇄ locomotive, * with an order index) and backfills one row per existing train set from its * current `locomotive_id`, so existing read paths keep resolving locomotives. * The `train_sets.locomotive_id` column is retained as the "primary" locomotive. * * NOTE: the shared dev DB has no applied migration history, so this is also * hand-applied there. IF NOT EXISTS keeps that idempotent. */ export class AddTrainSetLocomotives1820000000011 implements MigrationInterface { name = 'AddTrainSetLocomotives1820000000011'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` CREATE TABLE IF NOT EXISTS freight.train_set_locomotives ( id uuid NOT NULL DEFAULT uuid_generate_v4(), train_set_id uuid NOT NULL, locomotive_id uuid NOT NULL, sequence_no int NOT NULL DEFAULT 0, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz, CONSTRAINT "PK_train_set_locomotives" PRIMARY KEY (id), CONSTRAINT "FK_train_set_locomotives_train_set" FOREIGN KEY (train_set_id) REFERENCES freight.train_sets (id) ON DELETE CASCADE, CONSTRAINT "FK_train_set_locomotives_locomotive" FOREIGN KEY (locomotive_id) REFERENCES freight.locomotives (id) ); `); await queryRunner.query(` CREATE UNIQUE INDEX IF NOT EXISTS "UQ_train_set_locomotives_set_loco" ON freight.train_set_locomotives (train_set_id, locomotive_id); `); // Backfill: one link row per existing train set, from its current primary loco. await queryRunner.query(` INSERT INTO freight.train_set_locomotives (train_set_id, locomotive_id, sequence_no) SELECT ts.id, ts.locomotive_id, 0 FROM freight.train_sets ts WHERE ts.locomotive_id IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM freight.train_set_locomotives tsl WHERE tsl.train_set_id = ts.id AND tsl.locomotive_id = ts.locomotive_id ); `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query( `DROP INDEX IF EXISTS freight."UQ_train_set_locomotives_set_loco";`, ); await queryRunner.query(`DROP TABLE IF EXISTS freight.train_set_locomotives;`); } }