Sync the wahoo-import "FIT to GPX conversion" requirement into the main spec and move the completed change to openspec/changes/archive/2026-07-16-fit-parsing-hardening. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.6 KiB
1.6 KiB
1. Fixtures first
- 1.1 Collect fixture FIT files — adapted: per the chosen approach, cases are driven by mocked
fit-file-parseroutput infit.test.ts(pause, multisession, indoor no-GPS, corrupt coords/missing-timestamp) rather than binary files. Real device binaries can be added later without changing the converter. - 1.2 Parser
events/sessionsshapes captured as theFitEvent/FitSessiontypes + code comments infit.ts, and exercised by the mocked-parser tests.
2. Converter
- 2.1 Segmentation: split on timer stop/start event pairs, fallback on record gaps > 5 min (named constants)
- 2.2 Session slicing: records windowed per session, one-or-more segments per session, single-session unchanged
- 2.3 Validation gates: finite/in-range coordinates, timestamp required, non-finite altitude → undefined; prefer
enhanced_altitude(speed isn't emitted to GPX so its preference is moot) - 2.4 Return
{ gpx, sport }with the FIT→SportType mapping table; update call sites (Wahoo importer + webhook, Garmin importer) — provider-explicit type wins, FIT sport is fallback - 2.5 Unit tests over the fixtures: segment counts (pause becomes a segment boundary, which is what keeps moving time honest), corrupt-record drops, enhanced-altitude preference, sport mapping, no-GPS returns null gpx
3. Verification
- 3.1 Re-run the Wahoo importer test suite; confirm existing single-session imports produce identical stats (14 pass; mock updated to the
{gpx, sport}shape) - 3.2 Run
pnpm typecheck && pnpm lint && pnpm test— all green