mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-09 10:58:14 +00:00
71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
|
|
/**
|
|
* Wagons are now soft-deleted (deleted_at) instead of hard-deleted. The plain
|
|
* UNIQUE on wagon_number would keep a retired wagon's number reserved forever
|
|
* and block ever re-registering that number. Swap it for a PARTIAL unique index
|
|
* that only constrains live rows (deleted_at IS NULL); soft-deleted wagons no
|
|
* longer occupy their number.
|
|
*
|
|
* NOTE: the shared dev DB has no applied migration history, so this is also
|
|
* hand-applied there. The DO blocks + IF EXISTS/IF NOT EXISTS keep it
|
|
* idempotent whether the original uniqueness is the auto-named column
|
|
* constraint (wagons_wagon_number_key) or a TypeORM-named UQ_* constraint/index.
|
|
*/
|
|
export class WagonNumberPartialUnique2280000000000 implements MigrationInterface {
|
|
name = 'WagonNumberPartialUnique2280000000000';
|
|
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
// Drop any UNIQUE constraint on freight.wagons(wagon_number), whatever it is
|
|
// named (dropping the constraint also drops its backing index).
|
|
await queryRunner.query(`
|
|
DO $$
|
|
DECLARE con_name text;
|
|
BEGIN
|
|
FOR con_name IN
|
|
SELECT conname
|
|
FROM pg_constraint
|
|
WHERE conrelid = 'freight.wagons'::regclass
|
|
AND contype = 'u'
|
|
AND pg_get_constraintdef(oid) ILIKE '%(wagon_number)%'
|
|
LOOP
|
|
EXECUTE format('ALTER TABLE freight.wagons DROP CONSTRAINT IF EXISTS %I', con_name);
|
|
END LOOP;
|
|
END $$;
|
|
`);
|
|
|
|
// Drop any standalone (non-partial) unique index on wagon_number too.
|
|
await queryRunner.query(`
|
|
DO $$
|
|
DECLARE idx_name text;
|
|
BEGIN
|
|
FOR idx_name IN
|
|
SELECT c.relname
|
|
FROM pg_index i
|
|
JOIN pg_class c ON c.oid = i.indexrelid
|
|
WHERE i.indrelid = 'freight.wagons'::regclass
|
|
AND i.indisunique
|
|
AND i.indpred IS NULL
|
|
AND c.relname <> 'UQ_wagons_wagon_number_active'
|
|
AND pg_get_indexdef(i.indexrelid) ILIKE '%(wagon_number)%'
|
|
LOOP
|
|
EXECUTE format('DROP INDEX IF EXISTS freight.%I', idx_name);
|
|
END LOOP;
|
|
END $$;
|
|
`);
|
|
|
|
// Live wagon numbers stay unique; soft-deleted rows are exempt.
|
|
await queryRunner.query(`
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_wagons_wagon_number_active"
|
|
ON freight.wagons (wagon_number)
|
|
WHERE deleted_at IS NULL;
|
|
`);
|
|
}
|
|
|
|
public async down(): Promise<void> {
|
|
// No-op: re-adding a plain UNIQUE would fail whenever two soft-deleted
|
|
// wagons share a number, and the partial index is strictly safer. Left in
|
|
// place intentionally.
|
|
}
|
|
}
|