fix(insights): bound the status preparing-poll to a fixed ceiling

The per-metric status cards and the inline medication-compliance query
poll the read-only status route every 4 s while the payload reports
preparing:true. A configured provider whose generation persistently
fails leaves preparing pinned true, so an open Insights page would poll
indefinitely — steady battery and network draw on a screen the user has
walked away from.

Cap the poll at 12 attempts (~48 s) through a shared
nextStatusPollInterval helper both call sites route through. Past the
ceiling the card settles on its existing static / empty state. The happy
path is unchanged: a generation that lands within a couple of intervals
clears preparing and stops the timer exactly as before, and a terminal
no-provider payload never carried preparing so it stays terminal.
This commit is contained in:
Marc-André Bombeck committed 2026-06-01 17:31:45 +02:00
1 parent 8dced00188
commit 65cfa2b83a
3 files changed
+92 -6

No files matched your search

+11 -4
View File
@@ -5,6 +5,7 @@ import Link from "next/link";
import { Loader2, Pill } from "lucide-react";
import { useAuth } from "@/hooks/use-auth";
import { nextStatusPollInterval } from "@/hooks/use-insight-status";
import { queryKeys } from "@/lib/query-keys";
import { useTranslations } from "@/lib/i18n/context";
import { Badge } from "@/components/ui/badge";
@@ -64,11 +65,11 @@ interface MedicationComplianceStatusData {
preparing?: boolean;
}
// v1.8.3 — client ceiling + preparing-poll cadence, mirroring the shared
// v1.8.3 — client ceiling on the round-trip, mirroring the shared
// `use-insight-status` hook so the medication-compliance card never awaits
// an uncapped LLM round-trip on navigation.
// an uncapped LLM round-trip on navigation. The preparing-poll cadence and
// its attempt ceiling come from the shared `nextStatusPollInterval` helper.
const MED_STATUS_TIMEOUT_MS = 8_000;
const MED_STATUS_POLL_MS = 4_000;
interface MedicationDailyData {
expected: number;
@@ -121,8 +122,14 @@ export default function InsightsMedikamentePage() {
enabled: isAuthenticated,
staleTime: 60 * 1000,
retry: 0,
// v1.8.4 — bounded preparing poll: stop after the shared attempt
// ceiling so a persistently failing generation can't poll an open
// page forever.
refetchInterval: (query) =>
query.state.data?.preparing ? MED_STATUS_POLL_MS : false,
nextStatusPollInterval(
query.state.data?.preparing,
query.state.dataUpdateCount,
),
});
const medications = comprehensive?.medications ?? [];