5 Commits
Author SHA1 Message Date
Marc-André Bombeck ebeb16daa3 fix(sleep): emit the per-night total, not a single stage, on the sleep tile and series
SLEEP_DURATION is stored in minutes, one row per sleep stage per night
(IN_BED / AWAKE / ASLEEP / CORE / DEEP / REM) since the HealthKit
category-sample ingest landed. The value is not cumulative, so reading
the single most-recent row surfaced one stage's minutes — never the
night. The dashboard sleep tile and the sleep series therefore showed a
fragment of the night rather than the night.

Add a shared `summarizeSleepNights` helper that groups the per-stage
rows by the wake-day calendar date in the user's timezone and sums the
asleep stages (CORE + DEEP + REM, plus a legacy bare-duration row),
excluding IN_BED and AWAKE per the AASM convention already used by the
sleep score. Wire it into:

- the dashboard summary tile, which now emits last night's time asleep
  in hours with an explicit `unit: "h"` and a per-stage breakdown for a
  future detail view;
- the sleep series, which now returns one point per night (time asleep
  in hours) plus a top-level `unit` for every kind so clients never
  infer the unit;
- the slim summaries slice, so the web dashboard tile and the insights
  overview read per-night totals (kept in canonical minutes there; the
  web tile converts to hours) — strictly more correct than averaging
  across stage rows, and parity with the iOS value.
2026-06-04 16:44:53 +02:00
Marc-André BombeckandClaude Opus 4.8 2994954138 test+a11y: fix mocks/expectations for source-priority + dashboard ids; pair coach-memory spinner with motion-reduce
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 13:12:18 +02:00
Marc-André Bombeck d1e3c9a792 test(dashboard): cover isDashboardSnapshotEnabled default-on boundary
Pin undefined/empty/"true" to ON and exactly "false" to OFF so a
future edit cannot quietly regress to the old === "true" opt-in.
2026-05-31 20:00:16 +02:00
Marc-André Bombeck 7802ce1e11 feat(dashboard): enable unified snapshot for atomic first paint
Default the dashboard snapshot flag to ON (disable with
NEXT_PUBLIC_DASHBOARD_SNAPSHOT=false). The legacy four-cell waterfall
let the mood cache resolve first and pop in ahead of the rest of the
strip; the snapshot path hydrates every tile from one un-gated cell so
the whole strip shares a single completion moment.

Defaulting on rather than gating on === "true" sidesteps the
NEXT_PUBLIC_* build-time-baking trap: the production image and dev/e2e
all exercise the snapshot path without a special build flag. Fully
reversible to the legacy path via the env var. Comment-only sync in
page.tsx; no logic change there.
2026-05-31 19:37:02 +02:00
Marc-André BombeckandClaude Opus 4.8 50e0a65228 chore(release): v1.7.0
v1.7.0 — health-record export (PDF + FHIR), flexible medication schedules, first-paint dashboard snapshot, full HealthKit coverage, offline sync delta feed, Coach data clustering. See CHANGELOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:36:17 +02:00