Archive the three implemented + merged changes (activity-sport-type, activity-stats, journal-elevation-profile): their deltas are promoted into openspec/specs/, the changes move to changes/archive/2026-06-12-*, and the three new capabilities are added to the CAPABILITIES index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.8 KiB
1.8 KiB
1. Helpers
- 1.1 Add a pure
movingTime(tracks)helper to@trails-cool/gpx(sum inter-point intervals, exclude sub-threshold/stationary segments, max-gap guard); unit-tested with and without trackpoint times (moving-time.ts+ test). - 1.2 Add a
deriveRate(distance, time, sportType)helper returning{ kind: "pace" | "speed", value }with the sport→kind rule and speed default (stats.ts). - 1.3 Add pure
format*helpers (distance/elevation/duration/speed/pace) instats.ts; labels route through i18n at the call site (activityStatItems).
2. Component
- 2.1 Build the shared
StatRow(ordered{ value, label }items; size sm/lg; no data fetching). - 2.2 Canonical order encoded once in
activityStatItems(distance · time · [moving] · pace/speed · ascent · descent); surfaces draw from it.
3. Adopt across surfaces
- 3.1 Activity detail: replaced the card grid with
StatRow size="lg"(full set incl. pace/speed + moving/elapsed); loader computes moving time from the GPX. - 3.2 Route detail: adopt
StatRow size="lg"(distance, ascent, descent; no time/pace). - 3.3 Feed card: compact
StatRow(distance · time · pace/speed); feed loader already exposes duration + sportType. - 3.4 Profile activity list: compact
StatRow.
4. i18n
- 4.1 Add
journal.stats.*keys (distance, duration, movingTime, avgSpeed, avgPace, ascent, descent) to en + de.
5. Tests & checks
- 5.1 Unit:
movingTime(with/without timestamps; moving ≤ elapsed; stationary/gap exclusion),deriveRate(pace/speed/default/null), formatters. - 5.2 Component:
StatRowrenders ordered items (jsdom);activityStatItemsordering + compact-subset order asserted. - 5.3 typecheck + lint + unit (gpx 63, journal 311) green. Full
pnpm test:e2eruns in CI.