This commit is contained in:
Marshal
2026-07-14 11:06:49 +00:00
parent 957a185a4d
commit 6d0cf50b4d
64 changed files with 4896 additions and 404 deletions

View File

@@ -156,6 +156,7 @@ import {
import {
locomotivesService,
type Locomotive,
type LocomotiveListFilters,
type SaveLocomotivePayload,
} from "./locomotives.service";
import { overviewService } from "./overview.service";
@@ -181,13 +182,24 @@ import {
type SaveSignaturePayload,
} from "./signatures.service";
import { trainService, type Train } from "./trains.service";
import {
trainBuilderService,
type AvailableTrain,
type BuildTrainPayload,
type BuiltTrainListFilters,
type BuiltTrainListResponse,
type TrainComposition,
} from "./trainBuilder.service";
import { trainSchedulingService } from "./trainScheduling.service";
import { wagonTypesService, type WagonType } from "./wagon-types.service";
import {
wagonService,
wagonTransferRequestService,
type Wagon,
type WagonListFilters,
type WagonMovementRecord,
type WagonTransferRequest,
type CreateTransferRequestPayload,
} from "./wagon.service";
import { warehouseService } from "./warehouse.service";
@@ -213,6 +225,19 @@ const TRAIN_SCHEDULING_INVALIDATIONS: ReadonlyArray<readonly unknown[]> = [
QUERY_KEYS.BOOKINGS.ROOT,
];
/**
* Train Builder mutations change wagon/locomotive availability and the
* schedule-creation train picker alongside the builder's own lists.
*/
const TRAIN_BUILDER_INVALIDATIONS: ReadonlyArray<readonly unknown[]> = [
QUERY_KEYS.TRAIN_BUILDER.ROOT,
QUERY_KEYS.TRAIN_SCHEDULING.ROOT,
["wagons"],
["locomotives"],
["trains"],
QUERY_KEYS.FLEET.ROOT,
];
export const api = {
trainScheduling: {
// ── Queries ────────────────────────────────────────────────────────────
@@ -286,6 +311,14 @@ export const api = {
({ routeId }) => QUERY_KEYS.TRAIN_SCHEDULING.locomotives(routeId),
),
availableTrains: endpoint<{ routeId: string }, AvailableTrain[]>(
"train-scheduling",
"available-trains",
({ routeId }) =>
trainBuilderService.availableTrains(routeId).then((r) => r.data),
({ routeId }) => QUERY_KEYS.TRAIN_SCHEDULING.availableTrains(routeId),
),
bookableSchedules: endpoint<
{ originYardId?: string | null; destinationYardId?: string | null },
BookableSchedule[]
@@ -1621,6 +1654,55 @@ export const api = {
),
},
wagonTransferRequests: {
list: endpoint<
{ status?: WagonTransferRequest["status"] },
WagonTransferRequest[]
>(
"wagonTransferRequests",
"list",
({ status }) =>
wagonTransferRequestService.list(status).then((r) => r.data),
({ status }) => ["wagonTransferRequests", "list", status ?? "ALL"],
),
getById: endpoint<{ id: string }, WagonTransferRequest>(
"wagonTransferRequests",
"getById",
({ id }) => wagonTransferRequestService.getById(id).then((r) => r.data),
({ id }) => ["wagonTransferRequests", "detail", id],
),
create: endpoint<CreateTransferRequestPayload, WagonTransferRequest>(
"wagonTransferRequests",
"create",
(payload) =>
wagonTransferRequestService.create(payload).then((r) => r.data),
undefined,
() => [["wagonTransferRequests"]],
),
fulfill: endpoint<
{ id: string; wagonIds: string[] },
WagonTransferRequest
>(
"wagonTransferRequests",
"fulfill",
({ id, wagonIds }) =>
wagonTransferRequestService.fulfill(id, wagonIds).then((r) => r.data),
undefined,
() => [["wagonTransferRequests"], ["wagons"]],
),
cancel: endpoint<{ id: string }, WagonTransferRequest>(
"wagonTransferRequests",
"cancel",
({ id }) => wagonTransferRequestService.cancel(id).then((r) => r.data),
undefined,
() => [["wagonTransferRequests"]],
),
},
trains: {
list: endpoint<void, Train[]>(
"trains",
@@ -1661,6 +1743,80 @@ export const api = {
),
},
// Train Builder — persistent coded consists (2+ locomotives + ordered wagons)
// that train scheduling can reference as a unit. Every mutation also touches
// wagon/locomotive availability, so those roots are invalidated together.
trainBuilder: {
list: endpoint<{ filters?: BuiltTrainListFilters }, BuiltTrainListResponse>(
"train-builder",
"list",
({ filters }) => trainBuilderService.list(filters).then((r) => r.data),
({ filters }) => QUERY_KEYS.TRAIN_BUILDER.list(filters),
),
composition: endpoint<{ id: string }, TrainComposition>(
"train-builder",
"composition",
({ id }) => trainBuilderService.getComposition(id).then((r) => r.data),
({ id }) => QUERY_KEYS.TRAIN_BUILDER.composition(id),
),
build: endpoint<BuildTrainPayload, TrainComposition>(
"train-builder",
"build",
(payload) => trainBuilderService.build(payload).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
setLocomotives: endpoint<
{ id: string; locomotiveIds: string[] },
TrainComposition
>(
"train-builder",
"setLocomotives",
({ id, locomotiveIds }) =>
trainBuilderService.setLocomotives(id, locomotiveIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
assignWagons: endpoint<{ id: string; wagonIds: string[] }, TrainComposition>(
"train-builder",
"assignWagons",
({ id, wagonIds }) =>
trainBuilderService.assignWagons(id, wagonIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
removeWagon: endpoint<{ id: string; wagonId: string }, TrainComposition>(
"train-builder",
"removeWagon",
({ id, wagonId }) =>
trainBuilderService.removeWagon(id, wagonId).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
reorderWagons: endpoint<{ id: string; wagonIds: string[] }, TrainComposition>(
"train-builder",
"reorderWagons",
({ id, wagonIds }) =>
trainBuilderService.reorderWagons(id, wagonIds).then((r) => r.data),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
disband: endpoint<string, void>(
"train-builder",
"disband",
(id) => trainBuilderService.disband(id).then(() => undefined),
undefined,
() => TRAIN_BUILDER_INVALIDATIONS,
),
},
locomotives: {
list: endpoint<void, Locomotive[]>(
"locomotives",
@@ -1669,6 +1825,13 @@ export const api = {
() => ["locomotives"],
),
listFiltered: endpoint<{ filters?: LocomotiveListFilters }, Locomotive[]>(
"locomotives",
"listFiltered",
({ filters }) => locomotivesService.getAll(filters ?? {}).then((r) => r.data),
({ filters }) => ["locomotives", "list", filters ?? {}],
),
create: endpoint<Partial<SaveLocomotivePayload>, Locomotive>(
"locomotives",
"create",