Activities recorded from a structured Garmin workout carry a workoutId;
when its steps line up 1:1 with the recorded laps, the per-step target
pace/HR zone is resolved (via a Karvonen lookup for named zones) and stored
on each lap. The Review Queue plots it against the actual per-lap pace/HR
so the user can eyeball whether a run matches its plan while sorting it.
Manual assignments are the user's definitive word and Race assignments come
from a hard Garmin fact (eventType.typeKey), not a retunable rule -- neither
is ever touched by reclassify again, and Race can no longer be set by hand
via the review queue. Adds an Activities page so this locked/unlocked status
is visible per workout, since Review Queue only ever showed unresolved items.
Race is the 8th fixed workout kind, seeded with a real (not placeholder)
rule since Garmin Connect's eventType.typeKey reports "race" for
manually-tagged race activities. Non-running activity types (padel,
cycling, strength training, ...) are now dropped at sync time instead of
being stored. The Review Queue's type filter is now clickable exclusive
pill buttons instead of a dropdown.
Review Queue: show pace alongside distance/duration/HR, sort by activity
date (most recent first) instead of classification timestamp, and add a
filter by workout kind with a special "Unsorted" option for runs where
the rule engine found zero candidates at all (distinct from ambiguous
multi-candidate runs).
Profile: remove the phase-detection warm-up/cool-down section from the
UI -- not used by anything yet (phase segmentation is future work) and
was adding noise. The underlying fields are untouched so no data is lost
and the settings screen still round-trips them on save.
Two Minor findings from the final whole-branch review: the smartrun-dev
skill still told developers to set GARMIN_EMAIL/GARMIN_PASSWORD (now
sourced from the profile row instead), and validateProfile's deliberate
choice not to require 0-100% HR zone coverage had no explanation.
Implements GET /api/profile and PUT /api/profile endpoints with validation
of HR zones (must be contiguous, non-overlapping, 0-100%). Also updates
profile migration to use correct HR zone defaults (0-20, 20-40, etc.)
that match validation requirements.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>