Skip to content

fix(health,stats,wall): decode HC sleep stages, surface HR + active calories, period-aware heatmap, muscle-balance toggle, un-pin wall shell#35

Merged
rwlove merged 1 commit into
mainfrom
feat/health-fixes-stats-toggles
Jun 10, 2026
Merged

fix(health,stats,wall): decode HC sleep stages, surface HR + active calories, period-aware heatmap, muscle-balance toggle, un-pin wall shell#35
rwlove merged 1 commit into
mainfrom
feat/health-fixes-stats-toggles

Conversation

@rwlove

@rwlove rwlove commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses four reported issues, root-caused against the live store (which currently ingests only steps, heart_rate, sleep, active_caloriesno resting_heart_rate, no exercise).

1. Health — deep sleep, heart rate, cardio

  • Deep sleep (bug): Health Connect serialises sleep stages as numeric Stage codes ("4"=LIGHT, "5"=DEEP, "6"=REM, 1/3/7=awake). addSleepStages only matched string labels, so Deep/Light/REM stayed 0. Now decodes both numeric codes and labels.
  • Heart rate: no resting_heart_rate is ingested, so the Resting HR tile/line were always blank. Synthesize a resting proxy from each day's minimum heart_rate when no real resting record exists; a real record still wins.
  • Cardio / active calories: no exercise-session records exist (only daily active_calories). Surfaced active_calories through parser → aggregation as a new ActiveCalories series, with a dashboard tile and a daily chart on the Cardio tab. True per-session cardio still needs the HC bridge to export ExerciseSession records (see Follow-up).

2. Muscle Balance — Sets/Volume toggle

New toggle on the tab, defaulting to Sets (number of sets). Radar chart, breakdown panel, titles, and tooltips all follow the selection.

3. Consistency heatmap — period-aware

Was hard-pinned to a fixed 53-week year. Now scales to the selected period (week/month/year/all time); leading days before the period start render muted.

4. AI page header (wall)

The standard navbar has shipped since v0.0.88, but wall-sw.js served the /wall/ HTML shell cache-first and never bumped CACHE_NAME, so a long-lived kiosk kept painting the pre-navbar shell forever. Now serves the shell network-first (cache fallback for offline boot) and bumps to pump-wall-v4 to evict the stale cache.

Tests

internal/web/healthstats_test.go covers numeric stage decode, the resting-HR proxy (incl. real-record precedence), and active-calorie summing. go test ./... green.

Schema

No schema change — ActiveCalories is aggregation-only over existing health_record rows. No migration / no schema version bump.

Follow-up (bridge, out of this repo)

Per-session cardio needs the Android Health Connect → Webhook bridge to export ExerciseSession records under an exercise key. Until then the Cardio tab shows active calories + an explanatory empty state.

🤖 Generated with Claude Code

…active calories, period-aware heatmap, muscle-balance toggle, un-pin wall shell

Health data fixes (root-caused against the live store, which only ingests
steps/heart_rate/sleep/active_calories — no resting_heart_rate, no exercise):

- Deep sleep: Health Connect serialises sleep stages as numeric Stage codes
  ("4"=LIGHT, "5"=DEEP, "6"=REM, 1/3/7=awake), but addSleepStages only matched
  string labels, so every stage bucket stayed 0. Decode both numeric codes and
  labels.
- Heart rate: no resting_heart_rate is ingested, so the Resting HR tile/line
  were always blank. Synthesize a resting proxy from each day's minimum
  heart_rate when no real resting record exists; a real record still wins.
- Cardio / active calories: no exercise-session records exist (only daily
  active_calories). Surface active_calories through the parser + aggregation as
  a new ActiveCalories series, with a dashboard tile and a daily chart on the
  Cardio tab. True per-session cardio still needs the HC bridge to export
  ExerciseSession records (documented in the empty-state note).

Stats:

- Muscle Balance: add a Sets/Volume toggle (defaults to Sets — number of sets).
  Radar chart, breakdown panel, titles and tooltips all follow the selection.
- Consistency heatmap: was hard-pinned to a fixed 53-week year. Scale the grid
  to the selected period (week/month/year/all time); days before the period
  start render muted.

Wall (AI page):

- The standard navbar has shipped since v0.0.88, but wall-sw.js served the
  /wall/ HTML shell cache-first and never bumped CACHE_NAME, so a long-lived
  kiosk kept painting the pre-navbar shell forever. Serve the shell
  network-first (cache fallback for offline boot) and bump to pump-wall-v4 to
  evict the stale cache.

Adds healthstats_test.go covering stage decode, the resting-HR proxy
(including real-record precedence), and active-calorie summing. No schema
change (ActiveCalories is aggregation-only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rwlove rwlove merged commit 139e7c8 into main Jun 10, 2026
3 checks passed
@rwlove rwlove deleted the feat/health-fixes-stats-toggles branch June 10, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant