feat(train-scheduling): numbered marshalling-doc picker per corridor stop

Backend now generates a separate marshalling document per corridor stop
where the consist actually coupled/uncoupled/switched something
(marshallingStops/marshallingDocumentAt), instead of one 'current
position' doc. Wires that into the backoffice:

- TrainScheduleV2DetailPage: the single Intercity Marshalling menu item
  becomes one item per stop with a logged change, falling back to the
  old single item when nothing has happened yet.
- TrainScheduleTrackPage: same fallback/menu treatment on its own
  marshalling button.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Hagernesh
2026-08-28 11:49:08 +00:00
parent 8be886eb1d
commit 9e1e680394
7 changed files with 152 additions and 21 deletions

View File

@@ -85,6 +85,7 @@ import type {
UpdateCheckpointPayload,
DispatchSchedulePayload,
StaffBookingWindow,
MarshallingStop,
ScheduleMergePreview,
TrainScheduleDetail,
TrainScheduleFilters,
@@ -595,6 +596,13 @@ export const api = {
({ id }) => QUERY_KEYS.TRAIN_SCHEDULING.track(id),
),
marshallingStops: endpoint<{ id: string }, MarshallingStop[]>(
"train-scheduling",
"marshalling-stops",
({ id }) => trainSchedulingService.getMarshallingStops(id),
({ id }) => QUERY_KEYS.TRAIN_SCHEDULING.marshallingStops(id),
),
unassignedBookings: endpoint<
{ scheduleId: string },
UnassignedBookingsResponse

View File

@@ -33,6 +33,7 @@ import type {
UpdateCheckpointPayload,
DispatchSchedulePayload,
StaffBookingWindow,
MarshallingStop,
ScheduleMergePreview,
TrainScheduleDetail,
UpdateScheduleWindowRulePayload,
@@ -760,6 +761,24 @@ export const trainSchedulingService = {
return response.data;
},
getMarshallingStops: async (scheduleId: string): Promise<MarshallingStop[]> => {
const response = await client.get<MarshallingStop[]>(
URL_CONSTANTS.TRAIN_SCHEDULING.MARSHALLING_STOPS(scheduleId),
);
return unwrap(response.data);
},
downloadMarshallingDocumentAt: async (
scheduleId: string,
stopIndex: number,
): Promise<Blob> => {
const response = await client.get(
URL_CONSTANTS.TRAIN_SCHEDULING.MARSHALLING_DOCUMENT_AT(scheduleId, stopIndex),
{ responseType: "blob" },
);
return response.data;
},
getTrack: async (scheduleId: string): Promise<TrainTrackResponse> => {
const response = await client.get<TrainTrackResponse>(
URL_CONSTANTS.TRAIN_SCHEDULING.CHECKPOINTS(scheduleId),