mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
176 lines
8.6 KiB
TypeScript
176 lines
8.6 KiB
TypeScript
/**
|
|
* Query keys — insights tree: comprehensive payloads, status assessments,
|
|
* derived metrics, correlations, layout, and AI settings.
|
|
* Part of the centralized factory; aggregated in `./index.ts`.
|
|
*/
|
|
export const insightsKeys = {
|
|
insightsRoot: () => ["insights"] as const,
|
|
insightsComprehensive: () => ["insights", "comprehensive"] as const,
|
|
insightsTargets: () => ["insights", "targets"] as const,
|
|
/**
|
|
* Shared cache key for the rich `/api/insights/generate` advisor
|
|
* payload. Every surface that subscribes under this key shares the
|
|
* same cache so a regenerate on one surface refreshes the others
|
|
* without a second LLM round-trip.
|
|
*/
|
|
insightsAdvisor: () => ["insights", "advisor"] as const,
|
|
/**
|
|
* v1.11.0 — period-narrative summary (`/api/insights/narrative?period=…`).
|
|
* Keyed by period + locale so the week and month summaries cache
|
|
* independently and a locale switch fetches the matching prose.
|
|
*/
|
|
insightsNarrative: (period: string, locale: string) =>
|
|
["insights", "narrative", period, locale] as const,
|
|
insightsBpStatus: (locale: string) =>
|
|
["insights", "blood-pressure-status", locale] as const,
|
|
insightsWeightStatus: (locale: string) =>
|
|
["insights", "weight-status", locale] as const,
|
|
insightsPulseStatus: (locale: string) =>
|
|
["insights", "pulse-status", locale] as const,
|
|
insightsBmiStatus: (locale: string) =>
|
|
["insights", "bmi-status", locale] as const,
|
|
insightsMoodStatus: (locale: string) =>
|
|
["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,
|
|
/**
|
|
* Per-biomarker assessment for the lab-marker detail page. One generic
|
|
* route (`/api/insights/biomarker-assessment?biomarkerId=…`) backs every
|
|
* marker, so the key is parameterised by the marker id alongside the
|
|
* locale. Same read-only + stale-while-revalidate contract as
|
|
* `insightsMetricStatus`; the `["insights"]` prefix keeps it in the
|
|
* standard invalidation fan-out.
|
|
*/
|
|
insightsBiomarkerAssessment: (biomarkerId: string, locale: string) =>
|
|
["insights", "biomarker-assessment", biomarkerId, locale] as const,
|
|
/**
|
|
* v1.8.7.1 — mutationKey for the on-demand full-warm POST
|
|
* (`/api/insights/pregenerate`). Lives in the factory so the bare-array
|
|
* ESLint rule stays satisfied; the warm enqueues every assessment
|
|
* generation on the worker, so there is no read cache to invalidate
|
|
* here — the existing status queries pick up the warmed text via their
|
|
* own stale-while-revalidate.
|
|
*/
|
|
insightsPregenerate: () => ["insights", "pregenerate"] as const,
|
|
/**
|
|
* v1.10.0 — categorical events (WX-B). The device-flagged event
|
|
* awareness timeline (`/api/insights/rhythm-events`). No locale segment
|
|
* — the payload is verdicts + timestamps; the surface localises its own
|
|
* prose. The `["insights"]` prefix keeps it in the standard insights
|
|
* invalidation fan-out (an Apple Health batch write that lands an event
|
|
* row busts it via the prefix).
|
|
*/
|
|
insightsRhythmEvents: () => ["insights", "rhythm-events"] as const,
|
|
/**
|
|
* v1.10.0 — derived-wellness metrics. One generic route
|
|
* (`/api/insights/derived?metric=…[&type=…]`) backs the vitals
|
|
* dashboard tiles, the composite score-anatomy view, and the home
|
|
* wellness strip — all through the one `useDerivedMetric` hook.
|
|
*
|
|
* One generic route backs every derived metric (sleep score, readiness,
|
|
* coincident-deviation, vitals baseline, …); the optional sub-type is the
|
|
* chosen vital for `VITALS_BASELINE`. The fourth tuple slot is always
|
|
* present (`null` when no sub-type) so the cache never poisons between a
|
|
* 3-element and a 4-element shape for the same metric prefix. Pure compute
|
|
* over the rollup tier — a measurement write keeps it fresh by construction
|
|
* (next read sees new buckets), so the `["insights"]` prefix carries the
|
|
* invalidation fan-out.
|
|
*/
|
|
insightsDerived: (metric: string, type?: string | null) =>
|
|
["insights", "derived", metric, type ?? null] as const,
|
|
/**
|
|
* v1.10.0 — batched derived-metric read (`/api/insights/derived/batch`).
|
|
* One request resolves the whole dashboard grid server-side instead of N
|
|
* concurrent single-metric reads sharing the Prisma pool. Keyed by the
|
|
* sorted token list so the same grid always hits one cache entry; sits
|
|
* under the `["insights", "derived"]` prefix so a measurement-write
|
|
* invalidation fan-out reaches it exactly like the single-metric reads.
|
|
*/
|
|
insightsDerivedBatch: (tokens: readonly string[]) =>
|
|
["insights", "derived", "batch", [...tokens].sort().join(",")] as const,
|
|
/**
|
|
* v1.10.0 — FDR-controlled correlation discovery
|
|
* (`/api/insights/correlations`). Read-only descriptive surface; the
|
|
* `["insights"]` prefix keeps it in the existing invalidation fan-out.
|
|
*/
|
|
insightsCorrelations: () => ["insights", "correlations"] as const,
|
|
|
|
/**
|
|
* v1.4.41 W-FRONTEND-FACTORY — Settings → AI surfaces (provider chain,
|
|
* insights settings, user provider preference) and the targets editor
|
|
* all read these endpoints; centralising the keys keeps invalidation
|
|
* symmetrical with the user-thresholds + auth surfaces.
|
|
*/
|
|
insightsSettings: () => ["insights", "settings"] as const,
|
|
insightsProviderChain: () => ["insights", "provider-chain"] as const,
|
|
insightsGlp1Timeline: (limit: number | string) =>
|
|
["insights", "glp1-timeline", limit] as const,
|
|
|
|
/**
|
|
* v1.5.5 — per-user insights tile layout (mirrors
|
|
* `dashboardWidgets`). The Settings UI + the iOS client + the
|
|
* `/insights` shell all read this key; the PUT mutation invalidates
|
|
* it on save so every consumer paints the new layout in lockstep.
|
|
*/
|
|
insightsLayout: () => ["user", "insightsLayout"] as const,
|
|
|
|
/**
|
|
* v1.11.4 item J — bounded 30-day daily-aggregate read backing the
|
|
* Insights Trends-row deterministic caption (`trend-descriptor.ts`).
|
|
* Keyed by the comma-joined measurement type set so each card's slot
|
|
* caches its own small window (≤ 30 rollup rows). Distinct from
|
|
* `chartData(...)` so the caption never re-keys when the chart's
|
|
* internal value-mode / scale / range state changes; it only needs the
|
|
* raw 30-day series to derive direction + magnitude. Shares the
|
|
* `["trend-series"]` invalidation prefix so a measurement write
|
|
* refreshes the caption in lockstep with the chart.
|
|
*/
|
|
insightsTrendSeries: (types: string) => ["trend-series", types] as const,
|
|
|
|
/**
|
|
* v1.21.2 (A1) — per-metric "Coach read" strip
|
|
* (`/api/insights/coach-read?metric=<MeasurementType>`). One generic route
|
|
* backs every metric sub-page, so the key is parameterised by the
|
|
* MeasurementType. Pure compute over the baseline + correlation engines —
|
|
* the `["insights"]` prefix keeps it in the standard invalidation fan-out
|
|
* (a measurement write busts it so the placement refreshes).
|
|
*/
|
|
insightsCoachRead: (metric: string) =>
|
|
["insights", "coach-read", metric] as const,
|
|
|
|
/**
|
|
* v1.25 — baseline-drift read (`/api/insights/health-status`). Combines the
|
|
* personal-band deviations + the dated changepoint shifts into one awareness
|
|
* card. Pure compute over the rollup tier; the `["insights"]` prefix keeps it
|
|
* in the standard invalidation fan-out (a measurement write busts it).
|
|
*/
|
|
insightsHealthStatus: () => ["insights", "health-status"] as const,
|
|
|
|
/**
|
|
* v1.25 — breathing-disturbance screening read
|
|
* (`/api/insights/breathing-screening`). Last ~30 nights of the per-night
|
|
* index + device-flagged events. The `["insights"]` prefix carries the
|
|
* invalidation fan-out from an Apple Health sleep batch write.
|
|
*/
|
|
insightsBreathingScreening: () =>
|
|
["insights", "breathing-screening"] as const,
|
|
|
|
/**
|
|
* v1.25 — "what changed since your last panel" read
|
|
* (`/api/insights/labs-changes`). The two most-recent numeric lab panels'
|
|
* shared-analyte deltas. The `["insights"]` prefix keeps it in the standard
|
|
* invalidation fan-out.
|
|
*/
|
|
insightsLabsChanges: () => ["insights", "labs-changes"] as const,
|
|
};
|