Merge pull request #378 from trails-cool/stigi/spec-drift-catchup

Spec drift catch-up: FIT location, notification payload fields, shared-packages
This commit is contained in:
Ullrich Schäfer 2026-05-10 16:05:09 +02:00 committed by GitHub
commit f843915c5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 10 additions and 3 deletions

View file

@ -76,7 +76,7 @@ When adding a new spec, slot it into the most relevant group below and update th
- [`secret-management`](specs/secret-management/spec.md) — SOPS-encrypted env files, key rotation.
- [`observability`](specs/observability/spec.md) — Prometheus, Loki, Grafana dashboards.
- [`background-jobs`](specs/background-jobs/spec.md) — pg-boss queue, cron scheduling, retry policy, handler timeouts shared across the apps.
- [`shared-packages`](specs/shared-packages/spec.md) — workspace package boundaries (`@trails-cool/types`, `@trails-cool/map`, etc.).
- [`shared-packages`](specs/shared-packages/spec.md) — workspace package boundaries (`@trails-cool/types`, `@trails-cool/map`, `@trails-cool/fit`, etc.).
## Conventions

View file

@ -45,7 +45,7 @@ Each notification row SHALL include a `payload` (JSONB) capturing the denormaliz
#### Scenario: follow notifications snapshot the follower / target
- **WHEN** a `follow_request_received`, `follow_received`, or `follow_request_approved` notification is created
- **THEN** the row's `payload` records the relevant party's `username` and `displayName`, and `payload_version = 1`
- **THEN** the row's `payload` records `followerUsername`, `followerDisplayName`, `targetUsername`, and `targetDisplayName`, and `payload_version = 1`
#### Scenario: activity_published snapshots the activity + owner
- **WHEN** an `activity_published` notification is created

View file

@ -48,6 +48,13 @@ The `@trails-cool/ui` package SHALL provide shared React components (buttons, la
- **WHEN** an app renders the Button component from `@trails-cool/ui`
- **THEN** a styled button is displayed consistent with the trails.cool design
### Requirement: FIT encoding package
The `@trails-cool/fit` package SHALL provide a `gpxToFitCourse` function that converts a GPX string to a FIT Course binary (`Uint8Array`) suitable for upload to Wahoo and other head units. It is the sole owner of FIT file generation; apps do not bundle their own FIT encoder. See `wahoo-route-push` spec for the full round-trip contract.
#### Scenario: Import gpxToFitCourse in Journal
- **WHEN** the Journal app imports `@trails-cool/fit`
- **THEN** it has access to `gpxToFitCourse({ gpx, name })` returning a `Uint8Array`
### Requirement: i18n package
The `@trails-cool/i18n` package SHALL provide react-i18next configuration and translation strings starting with English and German.

View file

@ -95,7 +95,7 @@ Imported activities SHALL show their origin in the UI.
- **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.
The system SHALL convert FIT binary files to GPX format. The conversion logic lives at `apps/journal/app/lib/connected-services/fit.ts` — a provider-agnostic location shared across any future provider that produces FIT files (Garmin, Coros, etc.). Wahoo's importer and webhook both import from this shared module; they do not contain their own copy.
#### Scenario: Convert FIT with GPS data
- **WHEN** a FIT file contains GPS track records