14fcbca5f1
The Remittances page's three KPI tiles — REMITS / TOTAL PAID / ADJUSTMENTS — were computed page-locally via items.reduce(...) over the merged tail of the current page + live delta. With a 100-row default limit, a 1,739-row population showed count=100, paid=$16,934, adjustments=$147 — silently understating reality because the page hadn't loaded the remaining rows yet. This change mirrors the silent-incompleteness fix that /api/dashboard/kpis (commit59c3275) and /api/remittances (commitd81b6ed) made for their tiles: * CycloneStore.summarize_remittances() iterates the full filtered remittance population (no limit) and returns {count, total_paid, total_adjustments}. Mirrors iter_remittances with limit=_ITER_UNBOUNDED. * GET /api/remittances/summary — server endpoint with the same filter parameters as /api/remittances. Registered BEFORE the /api/remittances/stream handler so FastAPI doesn't treat 'summary' as a stream sub-path. * api.listRemittanceSummary + useRemittanceSummary hook. * Remittances.tsx swaps off items.reduce, consumes the server summary. Tiles render the server totals so the values reflect the entire DB population, not the page-local sample. Verified live: /api/remittances/summary returns {count: 1739, total_paid: 227181.58, total_adjustments: 13792.65}, which matches DB ground truth exactly. Tests: 8 new backend tests in test_api_remittances_summary.py; 1 new frontend test in Remittances.test.tsx (kpi_tiles_use_server_summary_not _page_local_reduce) plus the page-level test for the zero-valued mock default.
31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
import { useQuery } from "@tanstack/react-query";
|
|
import {
|
|
api,
|
|
type ListRemittancesParams,
|
|
type RemittanceSummary,
|
|
} from "@/lib/api";
|
|
|
|
/**
|
|
* Server-aggregated KPI totals for the Remittances page tiles.
|
|
* Returns ``{count, total_paid, total_adjustments}`` summed over the
|
|
* full filtered remittance population — NOT a page-limited sample.
|
|
*
|
|
* The page's KPI tiles consume this hook instead of summing
|
|
* ``items.reduce(...)`` over the current page (25 rows) + live-tail
|
|
* delta, which silently understates the true population in the same
|
|
* shape that ``59c3275`` retired for the Dashboard and that
|
|
* ``d81b6ed`` retired for the count tile.
|
|
*
|
|
* The optional ``params`` object lets the page pass through the same
|
|
* filter chips it uses for the list endpoint (``status``, ``payer``,
|
|
* ``date_from``, ``date_to``) so the summary and the row list always
|
|
* agree on which rows they're describing.
|
|
*/
|
|
export function useRemittanceSummary(params: ListRemittancesParams = {}) {
|
|
return useQuery<RemittanceSummary>({
|
|
queryKey: ["remittances", "summary", params],
|
|
queryFn: () => api.listRemittanceSummary(params),
|
|
enabled: api.isConfigured,
|
|
});
|
|
}
|