Files
HealthLog/src/lib/query-keys/measurements.ts
T
Marc-André Bombeck 590b08286a feat(vorsorge): drop trend strip, relative last-done, discreet due status
Remove the 7-day bar strip under the Vorsorge card last-done line and its
backing component, query key, and i18n strings. Render the last-done value
as a relative date (today / yesterday / absolute) through a shared
relativeCalendarDate helper that reuses the medication today/yesterday keys.
Show the next-due status as discreet coloured text - green today, orange
overdue - leaving the card surface neutral.
2026-06-20 11:54:11 +02:00

159 lines
6.0 KiB
TypeScript

/**
* Query keys — measurements, sleep night, and per-chart aggregate reads.
* Part of the centralized factory; aggregated in `./index.ts`.
*/
export const measurementKeys = {
measurements: () => ["measurements"] as const,
/**
* v1.15.13 — the measurements management-list read with its full filter
* + sort + pagination state baked into the key so the cache slot is
* correct for every filter combination (a `sourceEq` / date-range /
* type / page / sort change re-keys instead of poisoning a shared
* slot). Rides under the `["measurements"]` prefix so
* `measurementDependentKeys` (and a bulk-delete invalidation) reaches
* every slot at once. `mode` distinguishes the synthetic day-grouped /
* sleep-night branches from the plain `raw` list.
*/
measurementsList: (params: {
type: string | undefined;
sourceEq: string | undefined;
from: string | undefined;
to: string | undefined;
valueMin: number | undefined;
valueMax: number | undefined;
page: number;
sortBy: string;
sortDir: string;
mode: "raw" | "groupBy=day" | "sleep-night";
}) =>
[
"measurements",
"list",
params.type ?? null,
params.sourceEq ?? null,
params.from ?? null,
params.to ?? null,
params.valueMin ?? null,
params.valueMax ?? null,
params.page,
params.sortBy,
params.sortDir,
params.mode,
] as const,
/**
* v1.11.5 — last-night hypnogram (`GET /api/sleep/night`). The `date`
* discriminator lets the night-picker step back through recent nights
* without colliding caches; `undefined` is the most-recent night.
*/
sleepNight: (date?: string) => ["sleep-night", date ?? "latest"] as const,
/**
* v1.17.0 — sleep-rhythm read (`GET /api/sleep/rhythm`): the
* server-authoritative sleep-debt + chronotype DTO. Reads the same raw
* SLEEP_DURATION rows the night view does, so a sleep write invalidates
* it through the shared measurement-dependent set.
*/
sleepRhythm: () => ["sleep-rhythm"] as const,
/**
* v1.4.40 W-RSC — per-chart daily-aggregate fetch from the dashboard
* + insights chart row. Pre-fix the key was bare `["chart-data", …]`
* across the codebase, which excluded it from
* `measurementDependentKeys` and left chart caches stale for up to
* 60 s after a measurement save (audit-C2). Routing through the
* factory pulls every variant under a single
* `["chart-data"]` invalidation prefix so a mutation refreshes the
* tile strip + the chart row in lockstep.
*
* The shape carries the heavy parameter list because the chart query
* is bounded by metric set, value mode, BMI divisor, timezone, and
* fetch window; the factory packs those into a single tuple to keep
* the cache layout byte-identical with the pre-v1.4.40 layout.
*/
chartData: (
types: string,
valueMode: string,
bmiDivisor: string | number,
timezone: string,
fromIso: string,
toIso: string,
// v1.7.0 — display-time value scale (e.g. m/s → km/h via 3.6).
// Defaults to 1 so every pre-v1.7.0 caller packs a byte-identical
// tuple; a non-default scale re-keys the cache so the processed
// (scaled) series doesn't bleed across charts that share the
// underlying raw window.
valueScale: number = 1,
// v1.18.6 — read-mode discriminator ("preloaded" vs "fetch"). The
// dashboard's batched-slice render and a self-fetch must not share a
// cache entry, otherwise a range-tab change (which drops batched
// coverage) could read a batched slice. Defaults to "" and is only
// appended when set, so every pre-v1.18.6 caller packs a
// byte-identical tuple and the existing cache layout is unchanged.
readMode: string = "",
) =>
readMode
? ([
"chart-data",
types,
valueMode,
bmiDivisor,
timezone,
fromIso,
toIso,
valueScale,
readMode,
] as const)
: ([
"chart-data",
types,
valueMode,
bmiDivisor,
timezone,
fromIso,
toIso,
valueScale,
] as const),
/**
* v1.8.5 — bounded recent-timestamp read powering the
* measurement-diversity nudge on an insights category page. Keyed by
* the page's `MeasurementType` so each metric caches its own window.
* Shares the `measurement-dependent` invalidation prefix below so an
* edit/delete in the values subpage re-runs the clustering check.
*/
measurementDiversity: (type: string) =>
["measurement-diversity", type] as const,
/**
* v1.18.7 — per-day drill-down list for one `MeasurementType`
* (`GET /api/measurements?type=&dayKey=`), opened from a values-list
* day row. Keyed by `(type, dayKey)` so each expanded day caches its own
* slot. Distinct `["measurement-drilldown"]` prefix (not `["measurements"]`)
* because the day list is a stable historical slice that the drain has
* already settled — it does not need a measurement-write fan-out.
*/
measurementDrilldown: (type: string, dayKey: string) =>
["measurement-drilldown", type, dayKey] as const,
/**
* v1.18.7 — per-metric personal-records read (`GET /api/personal-records`)
* backing the decorative PR badge on a metric tile. Per-metric key so two
* tiles never share a cache slot; its own `["personal-records"]` prefix.
*/
personalRecordsByMetric: (metric: string) =>
["personal-records", "by-metric", metric] as const,
/**
* v1.18.6 — batched dashboard daily series
* (`GET /api/measurements/series-batch`). Shares the `chart-data`
* prefix so a fresh measurement evicts it alongside the per-chart
* caches (it lands in `measurementDependentKeys`). Keyed by the
* comma-joined type list + the ISO window so a changed visible-chart
* set or window re-fetches cleanly.
*/
chartSeriesBatch: (types: string, fromIso: string, toIso: string) =>
["chart-data", "series-batch", types, fromIso, toIso] as const,
};