mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 04:32:42 +00:00
feat(insights): add generic per-metric assessment loader
Add a parameterised query key (insightsMetricStatus) and a useInsightMetricStatus hook that reads the generic per-metric assessment route GET /api/insights/metric-status?metric=<id>. The seven bespoke status routes keep their own keys and hook union; this one covers the HealthKit metric sub-pages that share a single route keyed by the metric id. The hook mirrors the existing status loader: 8 s client ceiling, no inline retry, and the bounded preparing poll. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> (cherry picked from commit a3407a2f6c1e9f54c92a6f182db894ae0593e69f)
This commit is contained in:
1 parent
e33911e2d4
commit
16b0c349f2
2 files changed
+66
No files matched your search
@@ -163,3 +163,59 @@ export function useInsightStatus(metric: InsightStatusMetric) {
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* v1.8.7.1 — generic per-metric assessment loader for the HealthKit
|
||||
* metric sub-pages. The seven bespoke metrics above (`weight`, `pulse`,
|
||||
* …) each own a hand-written `/api/insights/<metric>-status` route; the
|
||||
* ~29 HealthKit pages instead share one generic route keyed by the
|
||||
* metric id:
|
||||
*
|
||||
* GET /api/insights/metric-status?metric=<METRIC_ID>&locale=<locale>
|
||||
*
|
||||
* where METRIC_ID is the existing HealthKit measurement identifier
|
||||
* (`HEART_RATE_VARIABILITY`, `RESTING_HEART_RATE`, `SLEEP_DURATION`, …).
|
||||
* The response envelope, the 8 s client ceiling, the no-retry policy and
|
||||
* the bounded `preparing` poll are identical to `useInsightStatus` — the
|
||||
* card consumes the same `InsightStatusData` shape for every scope.
|
||||
*
|
||||
* `enabled` lets the page suppress the fetch entirely when the metric has
|
||||
* no data (the page renders the insufficient-data empty state instead of
|
||||
* the card), so a brand-new account never fires an assessment round-trip.
|
||||
*/
|
||||
export function useInsightMetricStatus(metric: string, enabled = true) {
|
||||
const { isAuthenticated } = useAuth();
|
||||
const { locale } = useTranslations();
|
||||
|
||||
return useQuery({
|
||||
queryKey: queryKeys.insightsMetricStatus(metric, locale),
|
||||
queryFn: async (): Promise<InsightStatusData> => {
|
||||
const controller = new AbortController();
|
||||
const timeoutHandle = setTimeout(
|
||||
() => controller.abort(),
|
||||
STATUS_TIMEOUT_MS,
|
||||
);
|
||||
try {
|
||||
const res = await fetch(
|
||||
`/api/insights/metric-status?metric=${encodeURIComponent(
|
||||
metric,
|
||||
)}&locale=${locale}`,
|
||||
{ signal: controller.signal },
|
||||
);
|
||||
if (!res.ok) throw new Error("Failed");
|
||||
const json = (await res.json()) as { data: InsightStatusData };
|
||||
return json.data;
|
||||
} finally {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
},
|
||||
enabled: isAuthenticated && enabled,
|
||||
staleTime: 60 * 1000,
|
||||
retry: 0,
|
||||
refetchInterval: (query) =>
|
||||
nextStatusPollInterval(
|
||||
query.state.data?.preparing,
|
||||
query.state.dataUpdateCount,
|
||||
),
|
||||
});
|
||||
}
|
||||
@@ -103,6 +103,16 @@ export const queryKeys = {
|
||||
["insights", "mood-status", locale] as const,
|
||||
insightsMedicationComplianceStatus: (locale: string) =>
|
||||
["insights", "medication-compliance-status", locale] as const,
|
||||
/**
|
||||
* v1.8.7.1 — per-metric insight assessment for the HealthKit metric
|
||||
* sub-pages. One generic route (`/api/insights/metric-status?metric=…`)
|
||||
* backs every HealthKit metric, so the key is parameterised by the
|
||||
* metric id alongside the locale rather than minting a bespoke factory
|
||||
* entry per metric. The seven bespoke `*-status` routes above keep
|
||||
* their own keys; this one covers the ~29 generic HealthKit pages.
|
||||
*/
|
||||
insightsMetricStatus: (metric: string, locale: string) =>
|
||||
["insights", "metric-status", metric, locale] as const,
|
||||
|
||||
medications: () => ["medications"] as const,
|
||||
medicationDetail: (id: string) => ["medications", id] as const,
|
||||
|
||||
Reference in new issue
Block a user