Intercity bookings never get their own train — they ride whichever import/export
train passes through their corridor — so the work is scattered across other
people's schedules and there was nowhere to see it as a whole. The per-schedule
ride-along panel answers "what can THIS train carry"; this answers "what is
happening to intercity cargo".
Purely additive: the existing ride-along panel and the schedule detail page are
untouched, and loading/unloading still happens there, where the train's position
is confirmed. This is a read-only view that points back to it.
Each row carries both ends' facility status, because a booking whose origin or
destination has no equipment can never be worked there — the operator should see
that while the train is still coming, not when the load is refused. Those
bookings are counted and called out.
New GET /train-scheduling/intercity/bookings; the type is IntercityRideAlongRow,
not IntercityBookingRow, which already means the per-schedule candidate row.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Intercity load unload
Data model — yards.has_facility, yard_facilities, facility_handling_events, resolver, seeder
The gate — intercity load/unload refused where there's no facility
GRN raised on every facility load/unload; storage only at Indode
Yards config toggle — adding a facility is now a toggle, not a code change
Which yards can handle cargo is data, not a constant — the set grows. The Yards
config screen now carries the flag, so adding a facility is a toggle rather than
a code change. Config-driven, so this is a column plus a form field.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every facility raises a GRN — the goods changed hands, whether or not anyone
stores them. What differs is what happens next: Indode has a warehouse, so cargo
left there goes through the existing warehouse flow and accrues storage and
demurrage; Sebeta, Modjo, Adama and Dire Dawa only move cargo between train and
truck, so the handling event and its GRN are the whole record.
facility_handling_events carries that record because warehouse_inventory cannot:
its warehouse/yard/zone are NOT NULL, so a facility with equipment but no
warehouse could never have a row there. inventory_id links the storage record
when the facility does keep the cargo, which is what ties an Indode handover to
its demurrage.
generateGrnNumber moves to common/grn.util.ts so a GRN raised at a facility is
indistinguishable from one raised in a warehouse — the two live in different
tables, and a second generator would let the formats drift.
Recording is best-effort: the cargo moved regardless, so paperwork must never
fail the journey.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>