mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 04:50:54 +00:00
fix issue
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user