Multi-truck self-haul had no list anywhere on the warehouse side. The ops
dashboard counted trucks on site and offered no way to open the list, and
the inventory table showed a blank plate on exactly the bookings that have
several trucks: it read booking.customer_truck_plate_number, which
multi-truck self-haul leaves null because plates live in
customer_truck_assignments. Booking BK-2026-000033 has a truck and a driver
on file and displayed neither.
Adds a Trucks on Site page listing every truck that has arrived and not yet
departed, across bookings, with plate, driver, booking, customer, containers
and dwell time. It covers both haulage paths because the gate does — a
customer's own truck and an EDR last-mile truck reach the same barrier — and
flags anything sitting over four hours. It lives under Warehouse Management
rather than Imports or Exports, since the yard is not per-direction.
The inventory queries now read plates and drivers from the assignments and
keep the booking columns as the fallback for single-truck bookings written
before that table existed.
Both new statements were EXPLAIN-validated against the live schema; the
plate fix returns the data that was previously null.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Introduced DEACTIVATED status for trains, allowing staff to park trains indefinitely.
- Implemented methods to deactivate and reactivate trains in the TrainBuilderService.
- Added UI components for train deactivation and reactivation in TrainBuilderDetailPage.
- Created a dropdown setting for admin-managed import train numbers, with corresponding migrations.
- Updated yard code length to accommodate soft-delete suffix.
- Enhanced train status handling to include DEACTIVATED state.
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>
- gateStats(): items cleared through the gate today, average arrival→gate
turnaround (hours, 30d), and clearances per hour over the last 24h → new
GateThroughputCard in the dashboard Performance section.
- Live board: every dashboard query (dashboard, ops, throughput, dwell, cycle,
on-time, zone occupancy, accrual, gate) now auto-refreshes on a 60s interval,
with a "Live" indicator in the header.
New endpoint GET /warehouse-inventory/gate-stats (guarded). Deferred (need
upstream data): capacity forecast, labour productivity, WebSocket push, yard map.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the operational-performance layer to the warehouse cockpit:
- Dwell time & aging: dwellStats() (avg + 0-3/4-7/8-14/15+ buckets over
in-warehouse items) → DwellAgingCard histogram.
- Cycle time & on-time: cycleStats() (arrived→ready→loaded→dispatched stage
averages + dock-to-dispatch) and onTimeDispatchStats() (share of items that
left before their storage free-days expired, resolved via the fee engine's
own rule matching) → CycleTimeCard.
- Live tiles: opsStats() now returns receivedYesterday; KpiStrip renders an
optional ▲/▼ delta, and the ops strip shows received-today vs yesterday.
New endpoints: GET /warehouse-inventory/{dwell-stats,cycle-stats} and
/warehouse-fees/on-time-dispatch (all guarded). New "Performance" section on
WarehouseDashboardPage. On-time reads N/A when there is no sample / no active
storage rule.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- WarehouseDashboardPage now composes the ops KPI strip, lifecycle cards, flow
charts, zone-occupancy heatmap and demurrage/accrual exceptions into one
control-tower view; drop the redundant lifecycle donut.
- New GET /warehouse-inventory/throughput (date_trunc time series) replaces the
client-side buildTrend that downloaded the entire inventory list to bucket it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Added parameter to and for server-side free-text search on contract reference, company name, and booking details.
- Introduced new validation errors in for container clashes and space issues when creating bookings.
- Implemented paginated dropdown settings retrieval in .
- Updated to fetch active yards using a new method that handles pagination.
- Enhanced with a method to fetch all records by walking through pages.
- Refactored to support filtering and pagination in schedule listings.
- Improved to return a paginated list of facilities.
- Updated UI components in and to utilize debounced search inputs for better performance.
- Added alerts in to inform users about booking constraints related to splits and capacity.
- Enhanced to display notifications for split bookings and capacity usage.
- Implemented rejection handling in ContractApprovalStepsCard with a modal for rejection reasons.
- Updated useContractMutations to include rejectStep mutation.
- Added REJECT_STEP URL constant for API integration.
- Enhanced ContractClearanceDetailPage to utilize linkedBookingId for improved booking handling.
- Removed the gate pass granting functionality from the BookingClearanceService and ContractClearanceService, replacing it with a new method to retrieve gate pass status from train schedules.
- Updated the ContractsController to eliminate endpoints related to gate pass granting.
- Refactored the UI components (ExportClearanceStepper and PhasedClearanceActionPanel) to reflect the new gate pass securing process, linking to the train scheduling interface instead.
- Cleaned up related constants and query hooks, removing unused code and references to the gate pass functionality.
- Adjusted types in the contracts to accommodate changes in the gate pass handling logic.
- Implemented migration to release stuck assigned locomotives.
- Added schedule window phases to train schedules.
- Created booking batch offers table for partial capacity bookings.
- Developed BookingSplitService to handle partial booking offers and splits.
- Introduced BookingWindowService to manage booking window lifecycle and transitions.
- Added BookingBatchOffer entity to represent offers made during booking splits.
- Enhanced locomotive options with warnings for scheduling.
- Created UpcomingWindowsSection component to display upcoming booking windows.