Fix Wahoo import bugs, add Import All, update spec
Bugs fixed: - FIT parser returns timestamps as Date objects, not strings — convert to ISO 8601 before passing to generateGpx (caused str.replace crash) - FIT parser already converts semicircles to degrees — remove redundant conversion that produced near-zero coordinates - Wahoo CDN URLs are pre-signed S3 URLs — remove Bearer auth header from download requests (caused 400 "Unsupported Authorization Type") - Filter out third-party workouts (fitness_app_id >= 1000) since Wahoo does not share their data via the API UX improvements: - Individual imports use fetcher (no page refresh), button shows "Importing..." inline - "Import all" button imports all unimported workouts on the page sequentially with progress indicator - Add @vitejs/plugin-basic-ssl for local HTTPS dev (opt-in via HTTPS=1) Also adds unit test for FIT-to-GPX conversion with real fixture file, and updates wahoo-import spec to reflect all behaviors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
01d7620617
commit
20b91ef511
10 changed files with 258 additions and 58 deletions
|
|
@ -32,11 +32,15 @@ New Wahoo workouts SHALL be automatically imported when they complete.
|
|||
#### Scenario: Webhook receives new workout
|
||||
- **WHEN** Wahoo sends a `workout_summary` webhook to `/api/sync/webhook/wahoo`
|
||||
- **THEN** the system identifies the user via `provider_user_id`
|
||||
- **AND** downloads the FIT file from Wahoo's CDN
|
||||
- **AND** downloads the FIT file from Wahoo's CDN (without auth headers, as CDN URLs are pre-signed)
|
||||
- **AND** converts it to GPX
|
||||
- **AND** creates a journal activity with the GPX, stats, and PostGIS geometry
|
||||
- **AND** records the import in `sync_imports` to prevent duplicates
|
||||
|
||||
#### Scenario: Webhook for workout without file
|
||||
- **WHEN** a webhook arrives for a workout with no FIT file URL
|
||||
- **THEN** the activity is created without GPX or geometry
|
||||
|
||||
#### Scenario: Duplicate webhook
|
||||
- **WHEN** a webhook arrives for a workout already imported
|
||||
- **THEN** the import is skipped silently (idempotent)
|
||||
|
|
@ -51,20 +55,46 @@ Users SHALL be able to browse and selectively import older Wahoo workouts.
|
|||
#### Scenario: View workout list
|
||||
- **WHEN** a user visits the Wahoo import page
|
||||
- **THEN** their Wahoo workouts are listed with date, type, duration, and distance
|
||||
- **AND** already-imported workouts are marked
|
||||
- **AND** already-imported workouts are marked as "Imported"
|
||||
- **AND** third-party workouts (fitness_app_id >= 1000) are filtered out, as Wahoo does not share their data via the API
|
||||
- **AND** workouts without a FIT file show a "No GPS" badge with a tooltip explaining the provider has no route data
|
||||
|
||||
#### Scenario: Import workout
|
||||
#### Scenario: Import single workout
|
||||
- **WHEN** a user clicks "Import" on a Wahoo workout
|
||||
- **THEN** the FIT file is downloaded, converted to GPX, and a new activity is created
|
||||
- **THEN** the import runs in the background using a fetcher (no page refresh)
|
||||
- **AND** the button shows "Importing..." during the import
|
||||
- **AND** changes to "Imported" when complete
|
||||
|
||||
#### Scenario: Import all workouts
|
||||
- **WHEN** a user clicks "Import all"
|
||||
- **THEN** all unimported workouts on the current page are imported sequentially
|
||||
- **AND** a progress indicator shows "Importing X of Y..."
|
||||
|
||||
### Requirement: Activity import metadata
|
||||
Imported activities SHALL show their origin in the UI.
|
||||
|
||||
#### Scenario: View imported activity
|
||||
- **WHEN** a user views an activity that was imported from Wahoo
|
||||
- **THEN** an "Imported from wahoo" badge is displayed on the detail page
|
||||
|
||||
#### Scenario: Delete and reimport
|
||||
- **WHEN** a user deletes an imported activity
|
||||
- **THEN** the sync_imports record is also deleted
|
||||
- **AND** the workout appears as importable again on the import page
|
||||
|
||||
### Requirement: FIT to GPX conversion
|
||||
The system SHALL convert Wahoo's FIT binary files to GPX format.
|
||||
|
||||
#### Scenario: Convert FIT with GPS data
|
||||
- **WHEN** a FIT file contains GPS track records
|
||||
- **THEN** track points with lat, lon, elevation, and timestamp are extracted
|
||||
- **THEN** track points with lat, lon, elevation, and ISO 8601 timestamps are extracted
|
||||
- **AND** coordinates are used as-is from the FIT parser (which already converts semicircles to degrees)
|
||||
- **AND** a valid GPX string is produced using `generateGpx`
|
||||
|
||||
#### Scenario: FIT without GPS data
|
||||
- **WHEN** a FIT file has no GPS records (e.g., indoor trainer workout)
|
||||
- **THEN** the activity is created without GPX or geometry (stats only)
|
||||
|
||||
#### Scenario: Workout without FIT file
|
||||
- **WHEN** a workout has no file URL (e.g., aborted recording, third-party app data)
|
||||
- **THEN** the activity is created without GPX or geometry
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue