mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
Audit of the progressive-read commit. All three findings share one root cause: a DetectedWorkout with no metrics is now visible to the UI, which was impossible before — previously nothing left HealthConnectManager until every per-session aggregate had come back. 1. Sharing during the pending window published a lossy event. `toNewWorkoutRoute` collapses the null metrics to `0` (the composer route carries primitives), and `NewWorkoutViewModel.applyPrefill` reads `0` as absent and clears the field. So a tap on Share before stage 2 landed opened the composer with duration only, and publishing it marked the workout as shared — the real numbers never got their turn. The Share button now waits for the metrics. Everything still offering one in that window is a Health Connect workout, since a published one is already published, so the gate is blanket rather than per-workout. 2. Every resume stripped an already-complete dashboard. `refresh` runs on `LifecycleResumeEffect`, and the collect body overwrote the contribution with stage 1's skeletons — removing the distance, calories, heart-rate, steps and elevation cells and most of Best Efforts for as long as stage 2 took. The comment claiming a resume "re-reads in place" was only true for the few ms before stage 1 arrived. A partial stage now reaches the screen only when there is nothing better on it already; otherwise the previous numbers stay up, unannotated, and stage 2 swaps them atomically. The rule is a pure fold on the new top-level `HealthConnectContribution`, so it is testable without a device. 3. Stage 1 evicted published workouts that still had their metrics. `TrainingLog.merge` prefers the Health Connect copy because it "carries the metrics the published event may have dropped" — a rationale that inverts when that copy has not read its metrics yet. A user with published workouts watched their distance and calorie totals fall to zero and climb back. A copy carrying no metric at all now yields to a matching one that does. This also fixes the non-progressive case where aggregation legitimately returns nothing and the published event holds the only numbers. The dedupe rewrite preserves the existing shape exactly: the rule changes which copy survives a tie, never how many. One session matching several published events still collapses to one entry. Tests: 5 more in PartialMetricsReportTest (published totals held through the partial pass, the loaded copy still winning, both-metric-less and several-matches edges), and HealthConnectContributionTest covering the fold — first load shows stage 1, a resume does not, an empty completed read still clears the gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VgfgpDWnu635p2qc2K2yMX