import { MigrationInterface, QueryRunner } from "typeorm"; /** * A station's plan is per station AND per cargo type, not per station. * * The OCC monthly report plans "Nagad–Mojo multimodal container 122,010 t" and * "Nagad–Mojo fertilizer 18,000 t" as separate lines against the same station, * which the single `dimension_key` column cannot express: a station-keyed target * would apply the whole station's plan to each of its cargo types. * * `cargo_category` is nullable, so `cargo_category` and `container_class` * targets are unaffected — they leave it null and stay keyed on * `dimension_key` alone. The uniqueness index moves to include it, since * (station, category) is now the slot. */ export class OperationsTargetCargoCategory3590000000000 implements MigrationInterface { name = "OperationsTargetCargoCategory3590000000000"; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` ALTER TABLE freight.operations_targets ADD COLUMN IF NOT EXISTS cargo_category varchar(60); `); await queryRunner.query(`DROP INDEX IF EXISTS freight.ux_operations_targets_slot;`); // COALESCE rather than a plain column list: a partial unique index treats // NULLs as distinct, which would let the same category target be entered // twice over. await queryRunner.query(` CREATE UNIQUE INDEX IF NOT EXISTS ux_operations_targets_slot ON freight.operations_targets ( period_type, period_start, metric, dimension, dimension_key, COALESCE(cargo_category, '') ) WHERE deleted_at IS NULL; `); } public async down(queryRunner: QueryRunner): Promise { await queryRunner.query(`DROP INDEX IF EXISTS freight.ux_operations_targets_slot;`); await queryRunner.query(` CREATE UNIQUE INDEX IF NOT EXISTS ux_operations_targets_slot ON freight.operations_targets (period_type, period_start, metric, dimension, dimension_key) WHERE deleted_at IS NULL; `); await queryRunner.query(` ALTER TABLE freight.operations_targets DROP COLUMN IF EXISTS cargo_category; `); } }