feat(web/m7-coverage-gauge): coverage API client + query

Adds CoverageRollup type, getCoverageRollup() against
/api/admin/library/coverage, and createCoverageQuery() with the same
3s/30s pacing used by scan-status. New qk.coverage() key follows the
existing zero-arg tuple pattern. Vitest covers the GET path and the
empty-library zero-state plus the with_art + pending + settled = total
invariant.
This commit is contained in:
2026-05-06 10:12:57 -04:00
parent 97cca4411a
commit 3a424c6f73
3 changed files with 67 additions and 0 deletions
+26
View File
@@ -236,3 +236,29 @@ export function createScanStatusQuery() {
refetchInterval: 3_000
});
}
// Library coverage --------------------------------------------------------
export type CoverageRollup = {
total: number;
with_art: number;
pending: number;
settled: number;
pending_no_mbid: number;
};
export async function getCoverageRollup(): Promise<CoverageRollup> {
return api.get<CoverageRollup>('/api/admin/library/coverage');
}
// Same pacing as scan-status — 3s while polling, 30s stale-time. The
// query is cheap server-side (one aggregate per call) and we want
// the gauge to tick during a scan.
export function createCoverageQuery() {
return createQuery({
queryKey: qk.coverage(),
queryFn: getCoverageRollup,
staleTime: 30_000,
refetchInterval: 3_000
});
}