mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 04:08:11 +00:00
add yard distances management to rule engine
- 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.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
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;`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user