mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
- 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>
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
/**
|
|
* Per-corridor-edge physical load of a train: tare + length of the wagons
|
|
* spanning each edge, plus the cargo weight riding it. Used to validate that
|
|
* a planned mid-route COUPLE keeps every leg within the locomotives' pull
|
|
* weight and train length limits — a wagon cut at Mojo frees its tare/length
|
|
* on the edges past Mojo, a wagon coupled there adds its own only from there.
|
|
*/
|
|
|
|
export interface EdgeLoad {
|
|
weightTons: number;
|
|
lengthMeters: number;
|
|
}
|
|
|
|
export interface EdgeWagonSpan {
|
|
/** Half-open edge span [fromEdge, toEdge) the wagon physically rides. */
|
|
fromEdge: number;
|
|
toEdge: number;
|
|
tareTons: number;
|
|
lengthMeters: number;
|
|
}
|
|
|
|
export interface EdgeCargoLeg {
|
|
fromEdge: number;
|
|
toEdge: number;
|
|
weightTons: number;
|
|
}
|
|
|
|
export function computeEdgeLoads(
|
|
edgeCount: number,
|
|
wagonSpans: readonly EdgeWagonSpan[],
|
|
cargoLegs: readonly EdgeCargoLeg[],
|
|
): EdgeLoad[] {
|
|
const loads: EdgeLoad[] = Array.from({ length: Math.max(1, edgeCount) }, () => ({
|
|
weightTons: 0,
|
|
lengthMeters: 0,
|
|
}));
|
|
const clamp = (edge: number) => Math.min(Math.max(edge, 0), loads.length);
|
|
for (const span of wagonSpans) {
|
|
for (let e = clamp(span.fromEdge); e < clamp(span.toEdge); e += 1) {
|
|
loads[e].weightTons += span.tareTons;
|
|
loads[e].lengthMeters += span.lengthMeters;
|
|
}
|
|
}
|
|
for (const cargo of cargoLegs) {
|
|
for (let e = clamp(cargo.fromEdge); e < clamp(cargo.toEdge); e += 1) {
|
|
loads[e].weightTons += cargo.weightTons;
|
|
}
|
|
}
|
|
return loads;
|
|
}
|