import { useQuery } from "@tanstack/react-query"; import { api, type DashboardKpis, type DashboardKpisParams } from "@/lib/api"; /** * Server-aggregated Dashboard KPIs. * * Replaces the previous `useClaims({ limit: 100 })` + client-side * reduce pattern. With 60k+ claims in production, paginating * ``/api/claims`` and reducing client-side silently produced wrong * numbers — the Dashboard's "Billed / Received / Denial rate / Pending * AR" tiles were computed from a 100-row sample, not the full * population. This hook hits ``GET /api/dashboard/kpis`` which does * the aggregation server-side in a single read. * * Refreshes every 60s when the backend is configured so the KPIs stay * roughly current without a manual reload. Live event-publish from * ``useTailStream`` would be more elegant, but the underlying * aggregates span the whole DB so we'd need a new "kpi_updated" * event; 60s polling is a clear-enough SLA for a Dashboard view. * * Sample-data mode (no backend wired): returns ``data: undefined`` * rather than calling ``useQuery``. The Dashboard handles that with * zero-shaped fallbacks so the KPI tiles render a coherent "0" rather * than throwing. There's no in-memory aggregator — the old * client-side reduce was the bug, not a feature to preserve. */ export function useDashboardKpis(params: DashboardKpisParams = {}) { const q = useQuery({ queryKey: ["dashboard", "kpis", params], queryFn: () => api.getDashboardKpis(params), enabled: api.isConfigured, refetchInterval: api.isConfigured ? 60_000 : false, staleTime: 30_000, }); if (!api.isConfigured) { return { data: undefined, isLoading: false, isError: false, error: null, refetch: () => Promise.resolve(), dataUpdatedAt: 0, } as const; } return q; }