fix(query-keys): refresh the day view and timeline after every write

Symptoms, workouts, lab results, allergies, documents and questionnaires
evicted only their own lists. An open day, its calendar dots and the
timeline kept the pre-write answer for up to five minutes, so "Capture
for this day" saved a symptom or a workout and the day showed the old
list, and a deleted row stayed on it.

Workouts, labs, allergies and documents get a bundle beside the seven
that already carry the day and timeline roots; the six lab lists become
one (the OCR dialog's own copy of the commit hook's list goes with it).
Symptoms and questionnaires add the two roots to their list. Symptoms
stay off the illness bundle on purpose: nothing on the dashboard or the
Today digest reads them. Custom metrics need nothing: neither the day
nor the timeline reads them. invalidateKeys now drops a key listed twice,
since spread bundles share the two roots.
This commit is contained in:
Marc-André Bombeck committed 2026-11-11 19:41:14 +01:00
1 parent aae029d94e
commit 2e73b0ffec
24 files changed
+257 -118

No files matched your search

@@ -45,7 +45,7 @@
"app/insights/catalog/page.tsx :: MetricCatalogPage": 204,
"app/insights/medications/page.tsx :: InsightsMedikamentePage": 265,
"app/insights/page-client.tsx :: InsightsPageClient": 375,
"app/labs/page.tsx :: LabsPage": 228,
"app/labs/page.tsx :: LabsPage": 216,
"app/medications/page-client.tsx :: MedicationsPageClient": 590,
"app/notifications/page.tsx :: NotificationsPage": 327,
"components/activity/activity-calendar-card.tsx :: ActivityCalendarCard": 470,
@@ -1071,7 +1071,7 @@
"components/labs/lab-biomarker-chart.tsx": 3,
"components/labs/lab-biomarker-detail.tsx": 13,
"components/labs/lab-form.tsx": 6,
"components/labs/lab-history-list.tsx": 4,
"components/labs/lab-history-list.tsx": 3,
"components/labs/lab-list.tsx": 5,
"components/labs/lab-reference-range-bar.tsx": 1,
"components/labs/lab-trend-card.tsx": 1,
@@ -49,15 +49,15 @@ const FACTORY = "lib/query-keys/index.ts";
* match — the wrapper carries the refetch internally, so they are compliant by
* construction and correctly invisible here.
*
* The cycle / encounter / vaccination / illness families joined the matcher
* alongside the original three: the encounter and illness bundles now carry a
* daily-read key directly, the vaccination bundle's reminder root feeds the
* Today rail, and cycle rides along so a future daily-read key added to its
* The cycle / encounter / vaccination / illness / workout families joined the
* matcher alongside the original three: the encounter, illness and workout
* bundles carry a daily-read key directly, the vaccination bundle's reminder
* root feeds the Today rail, and cycle rides along so a future daily-read key added to its
* bundle cannot ship an unpaired site silently (its current sites are
* allowlisted below with the reason).
*/
const INVALIDATION =
/invalidateKeys\(\s*[^,]+,\s*\[?\s*(?:\.\.\.)?\s*(?:medicationDependentKeys|measurementDependentKeys|moodDependentKeys|cycleDependentKeys|encounterDependentKeys|vaccinationDependentKeys|illnessDependentKeys)\b/g;
/invalidateKeys\(\s*[^,]+,\s*\[?\s*(?:\.\.\.)?\s*(?:medicationDependentKeys|measurementDependentKeys|moodDependentKeys|cycleDependentKeys|encounterDependentKeys|vaccinationDependentKeys|illnessDependentKeys|workoutDependentKeys)\b/g;
// Match the CALL form only (open paren), never the bare import specifier —
// otherwise the `import { refetchInactiveDailyReads }` line would inflate the
// count and let a file drop one paired call while still "passing".