feat(warehouse): P1 dashboard analytics — dwell/aging, cycle-time + on-time, live deltas

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>
This commit is contained in:
Hagernesh
2026-07-15 13:51:23 +00:00
parent 6391ba837a
commit fc4aadbc57
15 changed files with 510 additions and 10 deletions

View File

@@ -492,6 +492,8 @@ export const URL_CONSTANTS = {
OPS_STATS: "/warehouse-inventory/ops-stats",
THROUGHPUT: (granularity: 'week' | 'month' | 'year') =>
`/warehouse-inventory/throughput?granularity=${granularity}`,
DWELL_STATS: "/warehouse-inventory/dwell-stats",
CYCLE_STATS: "/warehouse-inventory/cycle-stats",
ZONE_OCCUPANCY: (yardId?: string) =>
yardId
? `/warehouse-inventory/zone-occupancy?yardId=${yardId}`
@@ -564,6 +566,7 @@ export const URL_CONSTANTS = {
FEE_PREVIEW: (inventoryId: string) =>
`/warehouse-inventory/${inventoryId}/fee-preview`,
ACCRUAL_DASHBOARD: "/warehouse-fees/accrual-dashboard",
ON_TIME_DISPATCH: "/warehouse-fees/on-time-dispatch",
ACCRUAL_ACK: (inventoryId: string) =>
`/warehouse-fees/accrual/${inventoryId}/acknowledge`,
},