Accelerate the chart range switch, prefetch two list pages, calm two 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.
This commit is contained in:
Marc-André Bombeck committed 2026-08-13 19:06:56 +02:00
1 parent ac96e5e975
commit 61114fab90
31 files changed
+962 -326

No files matched your search

@@ -80,7 +80,12 @@ export function AchievementUnlockNotifier({
// to re-render on the same cadence.
const { data } = useAchievementsQuery({
enabled: !!user && achievementsEnabled,
refetchInterval: 2 * 60 * 1000,
// 5 min: every in-app write already invalidates the achievements cell
// (the `*DependentKeys` bundles all carry it), so this poll exists ONLY
// to surface an unlock earned by out-of-band ingest (an iOS batch, a
// Withings sync). A toast for those arriving up to five minutes later is
// an honest trade against an app-global 2-minute poll.
refetchInterval: 5 * 60 * 1000,
});
useEffect(() => {