- wahoo-production-cutover: ops checklist for moving the Wahoo Cloud API integration from sandbox to production tier (new app registration, logo upload, forced reauthorization). - wahoo-route-update: switch the route push pipeline from POST-per- version to POST-then-PUT so re-pushing an edited route updates the existing Wahoo route instead of creating a duplicate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2.8 KiB
Why
The trails.cool Wahoo Cloud API integration is currently registered as a sandbox application. Sandbox apps are rate-limited (250 req/day, 100/hr, 25 per 5 min) and Wahoo does not surface our logo or treat us as a first-class fitness app. To support real users at scale we need to be promoted to the production tier, which requires a Wahoo-side review of our app, scopes, redirect URI, and branding assets — none of which are visible in this codebase. This change captures the cutover as an auditable checklist so we don't lose track of the external steps and so we have a record of the sandbox-only quirks we already worked around.
What Changes
- Submit our Wahoo app for production review and obtain production rate-limit tier (sandbox 250/day → production 5000/day; 25 per 5 min → 200; 100/hr → 1000/hr).
- Confirm all five requested scopes are configured on the production app:
workouts_read,user_read,offline_data,routes_read,routes_write. - Upload a trails.cool logo to Wahoo's developer console so it appears next to routes pushed by us in the Wahoo mobile app (logo is keyed off
fitness_app_id, currently2156in sandbox). - Verify the production app's redirect URI is exactly
https://trails.cool/api/sync/callback/wahoo(Wahoo is byte-strict on this). - Register a separate production app (Wahoo issues new
client_id/client_secret) and plan a coordinated reauthorization for already-connected users — every existing Wahoo connection breaks at cutover and users are prompted to reconnect. Document the user-visible disruption. - Document, for posterity, the sandbox-only workarounds we already shipped so future maintainers don't repeat the discovery cost: per-(app, user) unrevoked-token cap (revoke on disconnect — #346),
route[file]must be adata:application/vnd.fit;base64,...URI (#349), FIT Coursecapabilitiesmust includevalid|distance|positionnot justtime(#348).
This is an operations change, not a code change. No spec deltas — wahoo-import and wahoo-route-push describe behaviors that don't change between sandbox and production.
Capabilities
New Capabilities
Modified Capabilities
Impact
- No application code changes.
- Secrets:
infrastructure/secrets.app.envis updated with the new productionclient_id/client_secretand the journal is redeployed. - Existing users: every connected Wahoo user has to reauthorize once at cutover; the disconnect/connect UX already handles this, but we should communicate it ahead of time.
- Wahoo developer console: branding (logo), redirect URI, scopes — all set externally.
- Documentation:
apps/journal/.env.exampleand CLAUDE.md may want a one-line note about which tier the app is on.