WFDASH-WEBAPP/src/lib/quote-assistant-counts-client.ts
Dave fa854060c4 feat(quote-assistant): AI x/y badge on quotes board
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 20:01:43 +02:00

38 lines
1.3 KiB
TypeScript

import getPocketBase from "@/lib/pocketbase";
export type AiCounts = Record<string, { pending: number; total: number }>;
// The route rejects more than 500 ids per call.
const MAX_IDS_PER_REQUEST = 500;
async function fetchChunk(ids: string[], token: string): Promise<AiCounts> {
const resp = await fetch(
`/api/v1/quotes/assistant/counts?ids=${encodeURIComponent(ids.join(","))}`,
{ headers: { Authorization: `Bearer ${token}` }, cache: "no-store" },
);
if (!resp.ok) return {};
const body: unknown = await resp.json();
if (!body || typeof body !== "object" || Array.isArray(body)) return {};
return body as AiCounts;
}
/**
* Per-quote "AI lines awaiting review" counts for the quotes board badge.
* Best-effort: any failure yields `{}` so the badge simply stays hidden and
* the board is never affected.
*/
export async function fetchAiCounts(ids: string[]): Promise<AiCounts> {
if (ids.length === 0) return {};
try {
const token = getPocketBase().authStore.token;
if (!token) return {};
const chunks: string[][] = [];
for (let i = 0; i < ids.length; i += MAX_IDS_PER_REQUEST) {
chunks.push(ids.slice(i, i + MAX_IDS_PER_REQUEST));
}
const results = await Promise.all(chunks.map((c) => fetchChunk(c, token)));
return Object.assign({}, ...results) as AiCounts;
} catch {
return {};
}
}