Release v1.37.16 - #790
Merged
Merged
Conversation
Integration syncs (Fitbit, Oura, Polar, WHOOP, Strava, Nightscout) now mark the per-user analytics cells stale and sweep the workouts cache at their sync tails — imported rows used to stay invisible to the cached dashboard, analytics and workout readers until the TTL lapsed. The WHOOP per-resource webhook/cron driver and the Polar workouts leg carry the same call, matching the posture Google Health and the workout batch route already had. Illness, cycle and encounter write routes hard-evict the analytics bucket through the new invalidateUserHealthContext helper: Rest Mode, the cycle context and the Today-rail appointment feed all read from cached cells under that bucket, and an interactive write must be true on the very next read.
Ten client mutation sites forgot a consumer: a coach-accepted checkup stayed invisible for up to five minutes, a threshold or target edit left the dashboard bands stale, a score-config save marked the daily reads stale but never refetched them, a booked visit missed the Today rail, a source-priority reorder kept every chart on the old canonical picks, an adopted self-context note never reached the Settings read. Each site now invalidates what its write changed and forces the unmounted snapshot + digest reads to refetch through refetchInactiveDailyReads. New illnessDependentKeys bundle carries the daily reads (Rest Mode frames both), dailyDigest joins encounterDependentKeys, and the chart-data prefix gains a factory accessor for whole-cache flushes. The daily-reads guard learns the cycle / encounter / vaccination / illness bundle families and a second matcher for direct snapshot/digest invalidateQueries without a forced refetch, each with a frozen reasoned allowlist. Both matchers were proven live by reverting a fix and watching the guard go red (see the test doc comment).
GET /api/insights/correlations was the most expensive uncached read in the app: a 180-day window, ~10 parallel series reads, Pearson + FDR in-process, plus two syncAcceptedPatterns DB writes — all paid on every mount. The built body now reads through the analytics bucket's SWR cell (60 s fresh / 1 h stale, keyed userId|correlations|locale), and the pattern-sync writes live inside the builder, so a cache hit performs no write on the read path. Eviction truth comes free: measurement, mood, medication, illness and custom-metric writes already sweep the user's prefix in that bucket, and a pattern dismiss sweeps it through invalidateUserCorrelationPatterns. The route test pins the contract: a second GET inside the fresh window re-runs neither the measurement window read nor the pattern sync, and serves a byte-equal body.
…polls placeholderData keeps the previous range painted while a health-chart range switch fetches, paired with its truth condition: the container dims and goes inert while isPlaceholderData is true, so the old range cannot masquerade as the new one. The mood chart needs no pairing — its range is a client-side slice over one static-key query and never drops to a skeleton. /checkups and /mood gain the dashboard-template RSC prefetch: the primary list read moves into a shared lib read (route + wrapper consume one query, so filter/order/wire shape cannot drift), the wrapper honours the DASHBOARD_SSR_PREFETCH kill-switch, resolves identity through getUnswitchedSession, JSON-round-trips the dehydrated state, and fails soft to the bare client on every error path. Page-prefetch unit tests pin the seeded keys and the fail-soft arms; the SSR hydration spec gains an assertion per page. The achievement-unlock poll drops to five minutes (in-app writes already invalidate the cell; the poll only covers out-of-band ingest), and the plan-proposal poll gains the advisor-style bounded attempt ceiling so an open thread stops polling after its budget.
The prefetch-caching guard's frozen route set and the session-surface guard's direct-derivation list both name every RSC prefetch wrapper; /checkups and /mood join them with the same reasoning as their five predecessors — getUnswitchedSession only, skipped under a switch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Performance and cache-truth patch.
Two commit groups. The first closes the write-to-read gaps: six integration syncs now mark the server caches stale on arrival, illness, cycle and appointment writes evict the analytics cache, ten client mutation sites that forgot a reader now invalidate it, and the daily-reads guard grew two new matcher families (further key bundles plus direct snapshot/digest invalidations) with recorded break-proofs. The second makes the app faster where it is felt: the correlations discovery read answers from a server-side cache with writes kept off the hit path, chart range switches keep the previous data visible and dimmed instead of dropping to a skeleton, the checkups and mood pages prefetch their first read server-side behind the existing kill switch, and two background polls are calmer.
No migrations. No wire-shape changes; the OpenAPI regen carries only the version bump.
Battery: typecheck, lint, unit (21285 passed), format:check, integration (201 files, 1844 passed), production build all green in the working tree.