mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 22:18:12 +00:00
feat(train-scheduling): mid-route consist changes, audit history, safer workspace
- planned couples: loose wagons join the train at a route stop, added from the schedule yards tab; capacity credits them per corridor edge and coupling validates locomotive weight/length caps per leg - real-cut toggle: a cut wagon permanently leaves the train build at its cut yard (soft cut still sits out one trip only) - fix heaviest-leg display counting a shared slot's full cargo on every spanned edge (phantom pull-weight overload on S-2026-00045) - confirmation dialogs for workspace add/load/unload/remove actions - train-builder History and Detached-wagons tabs, backed by paginated endpoints; builder detaches now always write adjustment-log rows Migrations 3660 (planned_wagon_couples, planned_wagon_real_cuts) and 3670 (adjustment log train_schedule_id nullable) — both applied to the dev DB by hand; watch mode does not run migrations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,9 @@ export type WagonAdjustmentAction = (typeof WAGON_ADJUSTMENT_ACTIONS)[number];
|
||||
@Index(['trainScheduleId'])
|
||||
@Index(['trainId'])
|
||||
export class ScheduleWagonAdjustmentLog extends BaseEntity {
|
||||
@Column({ name: 'train_schedule_id', type: 'uuid' })
|
||||
trainScheduleId!: string;
|
||||
/** Null when the change was made from the train builder with no live schedule. */
|
||||
@Column({ name: 'train_schedule_id', type: 'uuid', nullable: true })
|
||||
trainScheduleId!: string | null;
|
||||
|
||||
@Column({ name: 'train_id', type: 'uuid' })
|
||||
trainId!: string;
|
||||
|
||||
@@ -139,6 +139,24 @@ export class TrainSchedule extends BaseEntity {
|
||||
@Column({ name: 'planned_wagon_cut_yards', type: 'jsonb', nullable: true })
|
||||
plannedWagonCutYards?: Record<string, string> | null;
|
||||
|
||||
/**
|
||||
* LOOSE wagons this departure plans to COUPLE onto the train at a route
|
||||
* stop: `{ wagonId: pickupYardId }`. They join the built train permanently
|
||||
* when the trip reaches that stop (dispatch for the origin, checkpoint log
|
||||
* for mid-route stops).
|
||||
*/
|
||||
@Column({ name: 'planned_wagon_couples', type: 'jsonb', nullable: true })
|
||||
plannedWagonCouples?: Record<string, string> | null;
|
||||
|
||||
/**
|
||||
* Cut wagons (see plannedWagonCutYards) flagged as REAL cuts: the built
|
||||
* train permanently loses the wagon at its cut yard. Absent from this list,
|
||||
* a cut is soft — the wagon sits out the rest of this trip but stays in
|
||||
* the build.
|
||||
*/
|
||||
@Column({ name: 'planned_wagon_real_cuts', type: 'jsonb', nullable: true })
|
||||
plannedWagonRealCuts?: string[] | null;
|
||||
|
||||
/** OPEN = accepting/holding bookings; FULL = train filled; CLOSED = manually closed. Orthogonal to `status`. */
|
||||
@Column({ name: 'booking_window_status', type: 'varchar', length: 10, default: 'OPEN' })
|
||||
bookingWindowStatus!: string;
|
||||
|
||||
Reference in New Issue
Block a user