2026-10-16 17:13:31 -06:00
|
|
|
// The warehouse board (phase 4 contract, api/warehouse.py).
|
|
|
|
|
import { api } from "./client";
|
|
|
|
|
import { qs } from "./query";
|
2026-10-18 15:08:34 -06:00
|
|
|
import { normaliseFacets, type BoardQuery, type BoardResponse, type PacketCard } from "./types";
|
2026-10-16 17:13:31 -06:00
|
|
|
|
|
|
|
|
const COLUMNS = ["incoming", "pulling", "hold", "pulled", "released"] as const;
|
|
|
|
|
|
|
|
|
|
/** Every column and number present, even when the server leaves one out. */
|
|
|
|
|
function normalise(raw: Partial<BoardResponse> | null): BoardResponse {
|
|
|
|
|
const cols = (raw?.columns ?? {}) as Partial<Record<(typeof COLUMNS)[number], PacketCard[]>>;
|
|
|
|
|
const columns = Object.fromEntries(COLUMNS.map((c) => [c, Array.isArray(cols[c]) ? cols[c] : []])) as BoardResponse["columns"];
|
2026-10-18 15:08:34 -06:00
|
|
|
const facets = normaliseFacets(raw?.facets);
|
2026-10-16 17:13:31 -06:00
|
|
|
return {
|
|
|
|
|
kpis: { waiting: 0, pulling: 0, hold: 0, pulled: 0, open_shorts: 0, released_24h: 0, ...(raw?.kpis ?? {}) },
|
|
|
|
|
columns,
|
|
|
|
|
shorts: Array.isArray(raw?.shorts) ? raw.shorts : [],
|
2026-10-18 15:08:34 -06:00
|
|
|
...(facets ? { facets } : {}),
|
2026-10-16 17:13:31 -06:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const warehouseApi = {
|
|
|
|
|
board: async (q: BoardQuery = {}, signal?: AbortSignal): Promise<BoardResponse> =>
|
|
|
|
|
normalise(await api.get<Partial<BoardResponse> | null>(`/api/warehouse/board${qs({ ...q })}`, signal)),
|
|
|
|
|
};
|