mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 06:28:12 +00:00
- Introduced new yard distances resource with CRUD operations. - Created migration for yard distances table with necessary constraints. - Implemented service and repository for yard distances handling. - Added controller for API endpoints to manage yard distances. - Updated rule engine configuration to include yard distances. - Enhanced rule engine resource page to support yard distance selection. - Updated contracts and train builder pages to handle new yard distance logic. - Added error handling utility for better error message extraction.
67 lines
2.7 KiB
TypeScript
67 lines
2.7 KiB
TypeScript
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
|
|
/**
|
|
* Configured rail distance between two yards (Configuration → Yard Distances).
|
|
* Route creation resolves each segment's km from here (symmetric lookup:
|
|
* one A↔B row serves both directions) instead of accepting free-text km,
|
|
* and snapshots the value onto route_milestones.distance_km.
|
|
*
|
|
* Uniqueness is a partial index (deleted_at IS NULL) so a soft-deleted pair
|
|
* can be re-created.
|
|
*/
|
|
export class CreateYardDistances2060000000000 implements MigrationInterface {
|
|
name = 'CreateYardDistances2060000000000';
|
|
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(`
|
|
CREATE TABLE IF NOT EXISTS freight.yard_distances (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
from_yard_id uuid NOT NULL REFERENCES freight.yards(id),
|
|
to_yard_id uuid NOT NULL REFERENCES freight.yards(id),
|
|
distance_km numeric(10,2) NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
deleted_at timestamptz
|
|
);
|
|
`);
|
|
await queryRunner.query(`
|
|
CREATE INDEX IF NOT EXISTS idx_yard_distances_from_yard
|
|
ON freight.yard_distances (from_yard_id);
|
|
`);
|
|
await queryRunner.query(`
|
|
CREATE INDEX IF NOT EXISTS idx_yard_distances_to_yard
|
|
ON freight.yard_distances (to_yard_id);
|
|
`);
|
|
await queryRunner.query(`
|
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_yard_distances_pair
|
|
ON freight.yard_distances (from_yard_id, to_yard_id)
|
|
WHERE deleted_at IS NULL;
|
|
`);
|
|
// Backfill from segments already stored on existing routes so editing them
|
|
// does not immediately fail the "pair not configured" check. One row per
|
|
// unordered pair; where routes disagree the longest segment wins.
|
|
await queryRunner.query(`
|
|
INSERT INTO freight.yard_distances (from_yard_id, to_yard_id, distance_km)
|
|
SELECT DISTINCT ON (LEAST(prev_yard_id, yard_id), GREATEST(prev_yard_id, yard_id))
|
|
prev_yard_id, yard_id, distance_km
|
|
FROM (
|
|
SELECT
|
|
yard_id,
|
|
distance_km,
|
|
LAG(yard_id) OVER (PARTITION BY route_id ORDER BY sequence_no) AS prev_yard_id
|
|
FROM freight.route_milestones
|
|
WHERE deleted_at IS NULL
|
|
) segments
|
|
WHERE prev_yard_id IS NOT NULL
|
|
AND distance_km IS NOT NULL
|
|
AND distance_km > 0
|
|
ORDER BY LEAST(prev_yard_id, yard_id), GREATEST(prev_yard_id, yard_id), distance_km DESC
|
|
ON CONFLICT DO NOTHING;
|
|
`);
|
|
}
|
|
|
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
await queryRunner.query(`DROP TABLE IF EXISTS freight.yard_distances;`);
|
|
}
|
|
}
|