Ullrich Schäfer
da3659e07a
Also redirect to /settings/connections when disconnecting from a provider page
2026-05-23 20:46:52 +02:00
Ullrich Schäfer
12371d8c89
Return to the settings page the user came from after disconnecting
...
Previously always redirected to /settings (which resolves to /settings/profile).
Now reads the Referer header and redirects back to the originating /settings/*
page, defaulting to /settings/connections if no valid referer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 20:46:29 +02:00
Ullrich Schäfer
a181dfe6b8
Add cron job to sweep stale import batches every minute
...
Batches stuck in pending or running for more than 10 minutes (server
restart mid-import, pg-boss job dropped) are marked failed with a
user-visible message. Runs every minute via pg-boss cron with a 55s
expiry so overlapping runs are dropped.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 19:08:49 +02:00
Ullrich Schäfer
64624cb13c
Merge pull request #401 from trails-cool/sorting
...
Add activity sort toggle on activities page
2026-05-23 18:26:06 +02:00
Ullrich Schäfer
88078090e6
Add activity sort toggle on activities page
...
Same sort toggle as the user profile page (#399 ): default is activity
date (startedAt), switchable to "Date added" (createdAt) via ?sort=addedAt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:21:04 +02:00
Ullrich Schäfer
5ff7af8a81
Add background bulk import for Komoot
...
Replace the per-tour import UI with a fire-and-forget background job:
- Add `import_batches` DB table tracking status, found/imported/duplicate counts
- Add `runKomootBulkImport` server function that pages all Komoot tours,
fetches GPX, creates activities, and deduplicates via sync_imports
- Add `komoot-bulk-import` pg-boss job registered at server startup
- Add POST /api/sync/komoot/import to enqueue the job
- Add GET /api/sync/komoot/import-status to return the latest batch
- Replace the Komoot import page with a progress UI that polls every 2s
while a batch is running and shows found/imported/skipped counts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:19:10 +02:00
Ullrich Schäfer
8641b0ad90
Add activity sort toggle on user profile page
...
Default sort is by activity date (startedAt); users can switch to
"Date added" (createdAt) via a URL query param (?sort=addedAt).
Activities without a startedAt fall to the bottom when sorted by date.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 18:06:06 +02:00
Ullrich Schäfer
b25c5a9505
Fix import-all skipping every other workout
...
When a workout is imported and the loader revalidates, importableWorkouts
shrinks. The snapshot-update useEffect was overwriting the ref with the
shorter list, causing the index to point to the wrong item and skip every
alternate workout. Remove the snapshot update so the original list is used
throughout the import-all session.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 13:00:43 +02:00
Ullrich Schäfer
45c40ecea3
Make listImportable resilient to Komoot API errors; fix import E2E test
...
Return empty list instead of throwing when Komoot API is unavailable (e.g.
in CI with a synthetic user ID). Replaces direct API call in the import
test with a page-context test that verifies the page loads correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 11:05:15 +02:00
Ullrich Schäfer
4a5319fa72
Rewrite komoot E2E tests to use server-side seed endpoint
...
page.route() only intercepts browser requests, not server-side fetch calls.
Add /api/e2e/komoot seed endpoint that creates a Komoot connection directly
and returns a session cookie, so tests can verify UI state without mocking
the Komoot API at the network layer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 10:57:16 +02:00
Ullrich Schäfer
25f7d35e03
Fix E2E: associate labels with inputs via htmlFor/id; increase test timeouts
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 10:49:18 +02:00
Ullrich Schäfer
03304c354b
Add Komoot import with public (bio verification) and authenticated modes
...
Two-mode import: public mode verifies Komoot account ownership by checking
that the user's trails.cool profile URL appears in their Komoot bio — no
credentials stored. Authenticated mode uses email + password (AES-256-GCM
encrypted) to import private tours as well.
Includes unit tests for crypto/komoot client and E2E tests for the full
connect + import flow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 10:18:46 +02:00
Ullrich Schäfer
9e2ca5595e
Centralize waypoint Yjs serialization in waypointFromYMap/waypointToYMap
...
Introduce waypoint-ymap.ts with typed helpers so all Yjs↔Waypoint
conversions go through one place. New Waypoint fields now only need
to be added once rather than in every consumer.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 21:02:27 +02:00
Ullrich Schäfer
02f8a8be44
Propagate waypoint notes through session init, save-to-journal, and Journal display
...
- use-yjs: seed note from initialWaypoints on session open
- api.sessions: include note in initialWaypoints type
- SaveToJournalButton: include note in GPX waypoints on save
- Journal routes.: map and display waypoint notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:52:12 +02:00
Ullrich Schäfer
aef67aab7a
Include waypoint note in GPX export and extractWaypoints type
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 07:38:55 +02:00
Ullrich Schäfer
845301f0ae
Persist waypoint note from GPX drag-drop import
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 07:30:31 +02:00
Ullrich Schäfer
c2abb64ee0
Add per-waypoint notes and nearby POI snap to Planner
...
- `note` field on Waypoint type, stored in Yjs Y.Map and exported as
`<desc>` inside `<wpt>` in GPX
- Inline textarea note editing in WaypointSidebar with auto-resize,
character counter (500 max), save-on-blur, Escape cancel
- Note indicator dot on map markers; note tooltip on hover
- `useNearbyPois` hook: fetches POIs within 500m of selected waypoint
via Overpass proxy, 500ms debounce, AbortController, 60s rate-limit
suppression
- NearbyPoiMarkers component: renders POI markers on map for selected
waypoint with snap-to-POI on click
- Nearby section in WaypointSidebar: list with snap buttons, spinner,
empty/rate-limited states, "Show more" toggle (5 → all)
- Unit tests for fetchNearbyPois bbox geometry and snap-to-POI Yjs
transaction behaviour
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:58:21 +02:00
Ullrich Schäfer
861701e881
Show POI details (phone, website, opening hours) on Journal route detail page
...
Waypoints snapped to OSM POIs in the Planner now carry their metadata all
the way through to the Journal:
- Extend Waypoint type with osmId and poiTags fields
- Extract osmId/poiTags from Yjs Y.Map in ExportButton and SaveToJournalButton
- Encode POI metadata as <trails:poi> extensions in GPX <wpt> elements
- Parse <trails:poi> extensions back in the GPX parser
- Display phone, website, opening hours, address on Journal route detail
- E2E test for the full roundtrip; seed endpoint now defaults to public visibility
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 23:32:38 +02:00
dependabot[bot]
78a986b946
Bump the production group with 40 updates
...
Bumps the production group with 40 updates:
| Package | From | To |
| --- | --- | --- |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo ) | `55.0.23` | `55.0.24` |
| [@playwright/test](https://github.com/microsoft/playwright ) | `1.59.1` | `1.60.0` |
| [@sentry/vite-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins ) | `5.2.1` | `5.3.0` |
| [eslint](https://github.com/eslint/eslint ) | `10.3.0` | `10.4.0` |
| [i18next](https://github.com/i18next/i18next ) | `26.0.10` | `26.2.0` |
| [playwright](https://github.com/microsoft/playwright ) | `1.59.1` | `1.60.0` |
| [react-i18next](https://github.com/i18next/react-i18next ) | `17.0.7` | `17.0.8` |
| [turbo](https://github.com/vercel/turborepo ) | `2.9.12` | `2.9.14` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint ) | `8.59.2` | `8.59.3` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest ) | `4.1.5` | `4.1.6` |
| [@maplibre/maplibre-react-native](https://github.com/maplibre/maplibre-react-native ) | `11.1.1` | `11.2.1` |
| [@sentry/cli](https://github.com/getsentry/sentry-cli ) | `3.4.1` | `3.4.2` |
| [@sentry/react-native](https://github.com/getsentry/sentry-react-native ) | `8.11.0` | `8.11.1` |
| [expo-crypto](https://github.com/expo/expo/tree/HEAD/packages/expo-crypto ) | `55.0.14` | `55.0.15` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client ) | `55.0.32` | `55.0.34` |
| [expo-dev-menu](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-menu ) | `55.0.27` | `55.0.29` |
| [expo-device](https://github.com/expo/expo/tree/HEAD/packages/expo-device ) | `55.0.16` | `55.0.17` |
| [expo-file-system](https://github.com/expo/expo/tree/HEAD/packages/expo-file-system ) | `55.0.19` | `55.0.20` |
| [expo-localization](https://github.com/expo/expo/tree/HEAD/packages/expo-localization ) | `55.0.13` | `55.0.14` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location ) | `55.1.9` | `55.1.10` |
| [expo-navigation-bar](https://github.com/expo/expo/tree/HEAD/packages/expo-navigation-bar ) | `55.0.12` | `55.0.13` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications ) | `55.0.22` | `55.0.23` |
| [expo-secure-store](https://github.com/expo/expo/tree/HEAD/packages/expo-secure-store ) | `55.0.13` | `55.0.14` |
| [expo-splash-screen](https://github.com/expo/expo/tree/HEAD/packages/expo-splash-screen ) | `55.0.20` | `55.0.21` |
| [expo-sqlite](https://github.com/expo/expo/tree/HEAD/packages/expo-sqlite ) | `55.0.15` | `55.0.16` |
| [expo-system-ui](https://github.com/expo/expo/tree/HEAD/packages/expo-system-ui ) | `55.0.17` | `55.0.18` |
| [expo-web-browser](https://github.com/expo/expo/tree/HEAD/packages/expo-web-browser ) | `55.0.15` | `55.0.16` |
| [react-native-screens](https://github.com/software-mansion/react-native-screens ) | `4.24.0` | `4.25.0` |
| [use-latest-callback](https://github.com/satya164/use-latest-callback ) | `0.3.3` | `0.3.4` |
| [@codemirror/view](https://github.com/codemirror/view ) | `6.42.1` | `6.43.0` |
| [ws](https://github.com/websockets/ws ) | `8.20.0` | `8.20.1` |
| [@vitest/browser](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser ) | `4.1.5` | `4.1.6` |
| [@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright ) | `4.1.5` | `4.1.6` |
| [@react-router/dev](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dev ) | `7.15.0` | `7.15.1` |
| [@react-router/node](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-node ) | `7.15.0` | `7.15.1` |
| [@react-router/serve](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-serve ) | `7.15.0` | `7.15.1` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript ) | `10.52.0` | `10.53.1` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript ) | `10.51.0` | `10.53.1` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node ) | `22.19.18` | `22.19.19` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router ) | `7.15.0` | `7.15.1` |
Updates `expo` from 55.0.23 to 55.0.24
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo )
Updates `@playwright/test` from 1.59.1 to 1.60.0
- [Release notes](https://github.com/microsoft/playwright/releases )
- [Commits](https://github.com/microsoft/playwright/compare/v1.59.1...v1.60.0 )
Updates `@sentry/vite-plugin` from 5.2.1 to 5.3.0
- [Release notes](https://github.com/getsentry/sentry-javascript-bundler-plugins/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript-bundler-plugins/compare/5.2.1...5.3.0 )
Updates `eslint` from 10.3.0 to 10.4.0
- [Release notes](https://github.com/eslint/eslint/releases )
- [Commits](https://github.com/eslint/eslint/compare/v10.3.0...v10.4.0 )
Updates `i18next` from 26.0.10 to 26.2.0
- [Release notes](https://github.com/i18next/i18next/releases )
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/i18next/compare/v26.0.10...v26.2.0 )
Updates `playwright` from 1.59.1 to 1.60.0
- [Release notes](https://github.com/microsoft/playwright/releases )
- [Commits](https://github.com/microsoft/playwright/compare/v1.59.1...v1.60.0 )
Updates `react-i18next` from 17.0.7 to 17.0.8
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.7...v17.0.8 )
Updates `turbo` from 2.9.12 to 2.9.14
- [Release notes](https://github.com/vercel/turborepo/releases )
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md )
- [Commits](https://github.com/vercel/turborepo/compare/v2.9.12...v2.9.14 )
Updates `typescript-eslint` from 8.59.2 to 8.59.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases )
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md )
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.3/packages/typescript-eslint )
Updates `vitest` from 4.1.5 to 4.1.6
- [Release notes](https://github.com/vitest-dev/vitest/releases )
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/vitest )
Updates `@maplibre/maplibre-react-native` from 11.1.1 to 11.2.1
- [Release notes](https://github.com/maplibre/maplibre-react-native/releases )
- [Changelog](https://github.com/maplibre/maplibre-react-native/blob/main/CHANGELOG.md )
- [Commits](https://github.com/maplibre/maplibre-react-native/compare/v11.1.1...v11.2.1 )
Updates `@sentry/cli` from 3.4.1 to 3.4.2
- [Release notes](https://github.com/getsentry/sentry-cli/releases )
- [Changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-cli/compare/3.4.1...3.4.2 )
Updates `@sentry/react-native` from 8.11.0 to 8.11.1
- [Release notes](https://github.com/getsentry/sentry-react-native/releases )
- [Changelog](https://github.com/getsentry/sentry-react-native/blob/main/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-react-native/compare/8.11.0...8.11.1 )
Updates `expo-crypto` from 55.0.14 to 55.0.15
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-crypto/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-crypto )
Updates `expo-dev-client` from 55.0.32 to 55.0.34
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-dev-client/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client )
Updates `expo-dev-menu` from 55.0.27 to 55.0.29
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-dev-menu/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-menu )
Updates `expo-device` from 55.0.16 to 55.0.17
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-device/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-device )
Updates `expo-file-system` from 55.0.19 to 55.0.20
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-file-system/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-file-system )
Updates `expo-localization` from 55.0.13 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-localization/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-localization )
Updates `expo-location` from 55.1.9 to 55.1.10
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-location/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location )
Updates `expo-navigation-bar` from 55.0.12 to 55.0.13
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-navigation-bar/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-navigation-bar )
Updates `expo-notifications` from 55.0.22 to 55.0.23
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-notifications/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications )
Updates `expo-secure-store` from 55.0.13 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-secure-store/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-secure-store )
Updates `expo-splash-screen` from 55.0.20 to 55.0.21
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-splash-screen/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-splash-screen )
Updates `expo-sqlite` from 55.0.15 to 55.0.16
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-sqlite/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-sqlite )
Updates `expo-system-ui` from 55.0.17 to 55.0.18
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-system-ui/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-system-ui )
Updates `expo-web-browser` from 55.0.15 to 55.0.16
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-web-browser/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-web-browser )
Updates `react-native-screens` from 4.24.0 to 4.25.0
- [Release notes](https://github.com/software-mansion/react-native-screens/releases )
- [Commits](https://github.com/software-mansion/react-native-screens/compare/4.24.0...4.25.0 )
Updates `use-latest-callback` from 0.3.3 to 0.3.4
- [Release notes](https://github.com/satya164/use-latest-callback/releases )
- [Changelog](https://github.com/satya164/use-latest-callback/blob/main/CHANGELOG.md )
- [Commits](https://github.com/satya164/use-latest-callback/compare/v0.3.3...v0.3.4 )
Updates `@codemirror/view` from 6.42.1 to 6.43.0
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md )
- [Commits](https://github.com/codemirror/view/commits )
Updates `ws` from 8.20.0 to 8.20.1
- [Release notes](https://github.com/websockets/ws/releases )
- [Commits](https://github.com/websockets/ws/compare/8.20.0...8.20.1 )
Updates `@vitest/browser` from 4.1.5 to 4.1.6
- [Release notes](https://github.com/vitest-dev/vitest/releases )
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/browser )
Updates `@vitest/browser-playwright` from 4.1.5 to 4.1.6
- [Release notes](https://github.com/vitest-dev/vitest/releases )
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/browser-playwright )
Updates `@react-router/dev` from 7.15.0 to 7.15.1
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dev/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/dev@7.15.1/packages/react-router-dev )
Updates `@react-router/node` from 7.15.0 to 7.15.1
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-node/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/node@7.15.1/packages/react-router-node )
Updates `@react-router/serve` from 7.15.0 to 7.15.1
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-serve/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/serve@7.15.1/packages/react-router-serve )
Updates `@sentry/node` from 10.52.0 to 10.53.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.52.0...10.53.1 )
Updates `@sentry/react` from 10.51.0 to 10.53.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.51.0...10.53.1 )
Updates `@types/node` from 22.19.18 to 22.19.19
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases )
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node )
Updates `react-router` from 7.15.0 to 7.15.1
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/react-router@7.15.1/packages/react-router )
---
updated-dependencies:
- dependency-name: expo
dependency-version: 55.0.24
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@playwright/test"
dependency-version: 1.60.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/vite-plugin"
dependency-version: 5.3.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: eslint
dependency-version: 10.4.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: i18next
dependency-version: 26.2.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: playwright
dependency-version: 1.60.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: react-i18next
dependency-version: 17.0.8
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: turbo
dependency-version: 2.9.14
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: typescript-eslint
dependency-version: 8.59.3
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: vitest
dependency-version: 4.1.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@maplibre/maplibre-react-native"
dependency-version: 11.2.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/cli"
dependency-version: 3.4.2
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/react-native"
dependency-version: 8.11.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-crypto
dependency-version: 55.0.15
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-dev-client
dependency-version: 55.0.34
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-dev-menu
dependency-version: 55.0.29
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-device
dependency-version: 55.0.17
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-file-system
dependency-version: 55.0.20
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-localization
dependency-version: 55.0.14
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-location
dependency-version: 55.1.10
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-navigation-bar
dependency-version: 55.0.13
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-notifications
dependency-version: 55.0.23
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-secure-store
dependency-version: 55.0.14
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-splash-screen
dependency-version: 55.0.21
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-sqlite
dependency-version: 55.0.16
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-system-ui
dependency-version: 55.0.18
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-web-browser
dependency-version: 55.0.16
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-native-screens
dependency-version: 4.25.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: use-latest-callback
dependency-version: 0.3.4
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@codemirror/view"
dependency-version: 6.43.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: ws
dependency-version: 8.20.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@vitest/browser"
dependency-version: 4.1.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@vitest/browser-playwright"
dependency-version: 4.1.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@react-router/dev"
dependency-version: 7.15.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@react-router/node"
dependency-version: 7.15.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@react-router/serve"
dependency-version: 7.15.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/node"
dependency-version: 10.53.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/react"
dependency-version: 10.53.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@types/node"
dependency-version: 22.19.19
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-router
dependency-version: 7.15.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
...
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-17 08:45:54 +00:00
Ullrich Schäfer
eb30dddbfc
Ignore .vitest-attachments in planner
...
Vitest browser mode writes ephemeral screenshot attachments here during
test runs; only the __screenshots__/ reference snapshots belong in the repo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:53:42 +02:00
stigi
78a5a37214
chore: update visual snapshots [skip ci]
2026-05-10 17:15:46 +00:00
Ullrich Schäfer
7c924827c9
Add initial visual snapshots and fix update script flag
...
Generate baseline screenshots (macOS/Chromium) for the elevation-chart
visual regression suite. The CI update-visual-snapshots workflow will
overwrite these with Linux variants on the first run.
Also fix the test:visual:update script: --update-snapshots is not a
valid Vitest 4 flag; the correct short form is -u.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:09:00 +02:00
Ullrich Schäfer
76028d277d
Remove invalid oxc.transform config from browser vitest config
...
OxcOptions doesn't have a transform key — Vite 8 handles TSX automatically.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:05:15 +02:00
Ullrich Schäfer
fcc4f88379
Fix Vitest browser provider setup and test cleanup
...
- Add @vitest/browser-playwright; use playwright() factory (not string)
- Import page from vitest/browser (not deprecated @vitest/browser/context)
- Add afterEach(cleanup) so each test gets a fresh DOM
- Use oxc transform for JSX instead of esbuild (avoids Vite 8 warning)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 19:01:24 +02:00
Ullrich Schäfer
34529a9432
Split ElevationChart + PlannerMap into deep modules; add visual regression testing
...
ElevationChart (1013 lines) split into:
- elevation-chart-draw.ts — pure drawElevationChart(ctx, w, h, params) function
- use-elevation-data.ts — useElevationData(routeData) hook
- ElevationChart.tsx — ~300 lines, interaction + render only
PlannerMap (869 lines) split into:
- MapHelpers.tsx — 7 Leaflet sub-components (MapExposer, RouteFitter, MapClickHandler,
CursorTracker, NoGoAreaButton, OverlaySync, PoiRefresher)
- use-waypoint-manager.ts — all waypoint CRUD + route data sync
- use-gpx-drop.ts — GPX drag-and-drop hook
- PlannerMap.tsx — ~200 lines, orchestration only
Add Vitest browser visual regression tests for drawElevationChart via
@vitest/browser + Playwright (toMatchScreenshot). Tests cover plain, grade,
elevation, surface color modes plus hover and drag-select states.
Add update-visual-snapshots.yml workflow: triggered by workflow_dispatch or
the `update-snapshots` PR label; commits snapshots back to the branch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 16:41:23 +02:00
Ullrich Schäfer
e387e1f798
Deepen three architectural seams: FIT consolidation, host election extraction, injectable db
...
- Extract shared fitToGpx into connected-services/fit.ts (FIT is a Garmin
open standard used by Wahoo, Coros, Garmin — not provider-specific)
- Add importActivity() to sync/imports.server.ts so providers call one
function instead of createActivity + recordImport separately; eliminates
direct dependency on activities.server.ts from provider adapters
- Update wahoo importer + webhook to use both shared helpers
- Extract useHostElection(yjs) hook from useRouting so host election is
independently testable without mounting the full routing stack
- Add setDb() to journal db.ts for module-level injection in unit tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:52:31 +02:00
Ullrich Schäfer
557244ee87
Fix unused import lint error in api.e2e.route.$id.ts
2026-05-10 15:24:31 +02:00
Ullrich Schäfer
e7a0c132b9
Add e2e tests for Planner callback → geometry stored atomically
...
Introduces two E2E=true-gated test endpoints:
- POST /api/e2e/seed — creates a test user + bare route, returns routeId + JWT
- GET /api/e2e/route/:id — returns { hasGeom } for post-callback assertions
Three new integration tests:
- valid GPX via callback stores geometry (hasGeom = true)
- invalid GPX (< 2 track points) returns 400, geometry not stored
- missing token returns 401
CI: E2E=true added to the "Run E2E tests" step so the seed endpoints
are enabled when react-router-serve runs during the Playwright job.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:18:33 +02:00
Ullrich Schäfer
78b8b8f55f
Atomic GPX save: validate + persist row + geometry in one transaction
...
Eliminates the silent-failure pattern where a route/activity row could
be committed with gpx IS NOT NULL but geom IS NULL if the PostGIS write
failed after the row insert.
- New gpx-save.server.ts owns all GPX validation (GpxValidationError,
validateGpx) and PostGIS geometry writes (writeGeom, tx-aware)
- createRoute, updateRoute, createActivity, createRouteFromActivity all
wrapped in db.transaction() covering row + geom + version snapshot
- demo-bot uses createRoute/createActivity instead of raw inserts;
errors propagate loudly
- Callback endpoint returns 400 for GpxValidationError instead of 401
- ADR-0006 documents the invariant for future explorers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 15:02:56 +02:00
Ullrich Schäfer
6cd779ae02
Merge branch 'main' into dependabot/npm_and_yarn/production-69e9f3c6a7
2026-05-10 13:03:21 +02:00
dependabot[bot]
9cc08a725a
Bump the production group with 41 updates
...
Bumps the production group with 41 updates:
| Package | From | To |
| --- | --- | --- |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo ) | `55.0.19` | `55.0.23` |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react ) | `19.2.5` | `19.2.0` |
| [@expo/fingerprint](https://github.com/expo/expo/tree/HEAD/packages/@expo/fingerprint ) | `0.16.6` | `0.16.7` |
| [i18next](https://github.com/i18next/i18next ) | `26.0.8` | `26.0.10` |
| [react-i18next](https://github.com/i18next/react-i18next ) | `17.0.6` | `17.0.7` |
| [turbo](https://github.com/vercel/turborepo ) | `2.9.8` | `2.9.12` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint ) | `8.59.1` | `8.59.2` |
| [isbot](https://github.com/omrilotan/isbot ) | `5.1.39` | `5.1.40` |
| [zod](https://github.com/colinhacks/zod ) | `4.4.2` | `4.4.3` |
| [@expo/metro-runtime](https://github.com/expo/expo ) | `55.0.10` | `55.0.11` |
| [@gorhom/bottom-sheet](https://github.com/gorhom/react-native-bottom-sheet ) | `5.2.13` | `5.2.14` |
| [@maplibre/maplibre-react-native](https://github.com/maplibre/maplibre-react-native ) | `11.0.2` | `11.1.1` |
| [@sentry/react-native](https://github.com/getsentry/sentry-react-native ) | `8.10.0` | `8.11.0` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants ) | `55.0.15` | `55.0.16` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client ) | `55.0.30` | `55.0.32` |
| [expo-dev-menu](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-menu ) | `55.0.26` | `55.0.27` |
| [expo-device](https://github.com/expo/expo/tree/HEAD/packages/expo-device ) | `55.0.15` | `55.0.16` |
| [expo-file-system](https://github.com/expo/expo/tree/HEAD/packages/expo-file-system ) | `55.0.17` | `55.0.19` |
| [expo-linking](https://github.com/expo/expo/tree/HEAD/packages/expo-linking ) | `55.0.14` | `55.0.15` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location ) | `55.1.8` | `55.1.9` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router ) | `55.0.13` | `55.0.14` |
| [expo-splash-screen](https://github.com/expo/expo/tree/HEAD/packages/expo-splash-screen ) | `55.0.19` | `55.0.20` |
| [expo-status-bar](https://github.com/expo/expo/tree/HEAD/packages/expo-status-bar ) | `55.0.5` | `55.0.6` |
| [expo-system-ui](https://github.com/expo/expo/tree/HEAD/packages/expo-system-ui ) | `55.0.16` | `55.0.17` |
| [expo-web-browser](https://github.com/expo/expo/tree/HEAD/packages/expo-web-browser ) | `55.0.14` | `55.0.15` |
| [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler ) | `2.31.1` | `2.31.2` |
| [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-reanimated ) | `4.3.0` | `4.3.1` |
| [jest-expo](https://github.com/expo/expo/tree/HEAD/packages/jest-expo ) | `55.0.16` | `55.0.17` |
| [react-test-renderer](https://github.com/facebook/react/tree/HEAD/packages/react-test-renderer ) | `19.2.5` | `19.2.6` |
| [@codemirror/view](https://github.com/codemirror/view ) | `6.41.1` | `6.42.1` |
| [@react-router/dev](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dev ) | `7.14.2` | `7.15.0` |
| [@react-router/node](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-node ) | `7.14.2` | `7.15.0` |
| [@react-router/serve](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-serve ) | `7.14.2` | `7.15.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript ) | `10.51.0` | `10.52.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript ) | `10.51.0` | `10.52.0` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite ) | `4.2.4` | `4.3.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node ) | `22.19.17` | `22.19.18` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom ) | `19.2.5` | `19.2.6` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router ) | `7.14.2` | `7.15.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss ) | `4.2.4` | `4.3.0` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite ) | `7.3.2` | `7.3.3` |
Updates `expo` from 55.0.19 to 55.0.23
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo )
Updates `react` from 19.2.5 to 19.2.0
- [Release notes](https://github.com/facebook/react/releases )
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md )
- [Commits](https://github.com/facebook/react/commits/v19.2.0/packages/react )
Updates `@expo/fingerprint` from 0.16.6 to 0.16.7
- [Changelog](https://github.com/expo/expo/blob/main/packages/@expo/fingerprint/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/@expo/fingerprint )
Updates `i18next` from 26.0.8 to 26.0.10
- [Release notes](https://github.com/i18next/i18next/releases )
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/i18next/compare/v26.0.8...v26.0.10 )
Updates `react-i18next` from 17.0.6 to 17.0.7
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.6...v17.0.7 )
Updates `turbo` from 2.9.8 to 2.9.12
- [Release notes](https://github.com/vercel/turborepo/releases )
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md )
- [Commits](https://github.com/vercel/turborepo/compare/v2.9.8...v2.9.12 )
Updates `typescript-eslint` from 8.59.1 to 8.59.2
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases )
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md )
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.2/packages/typescript-eslint )
Updates `isbot` from 5.1.39 to 5.1.40
- [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md )
- [Commits](https://github.com/omrilotan/isbot/compare/v5.1.39...v5.1.40 )
Updates `zod` from 4.4.2 to 4.4.3
- [Release notes](https://github.com/colinhacks/zod/releases )
- [Commits](https://github.com/colinhacks/zod/compare/v4.4.2...v4.4.3 )
Updates `@expo/metro-runtime` from 55.0.10 to 55.0.11
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits )
Updates `@gorhom/bottom-sheet` from 5.2.13 to 5.2.14
- [Release notes](https://github.com/gorhom/react-native-bottom-sheet/releases )
- [Changelog](https://github.com/gorhom/react-native-bottom-sheet/blob/master/CHANGELOG.md )
- [Commits](https://github.com/gorhom/react-native-bottom-sheet/compare/v5.2.13...v5.2.14 )
Updates `@maplibre/maplibre-react-native` from 11.0.2 to 11.1.1
- [Release notes](https://github.com/maplibre/maplibre-react-native/releases )
- [Changelog](https://github.com/maplibre/maplibre-react-native/blob/main/CHANGELOG.md )
- [Commits](https://github.com/maplibre/maplibre-react-native/compare/v11.0.2...v11.1.1 )
Updates `@sentry/react-native` from 8.10.0 to 8.11.0
- [Release notes](https://github.com/getsentry/sentry-react-native/releases )
- [Changelog](https://github.com/getsentry/sentry-react-native/blob/main/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-react-native/compare/8.10.0...8.11.0 )
Updates `expo-constants` from 55.0.15 to 55.0.16
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-constants/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-constants )
Updates `expo-dev-client` from 55.0.30 to 55.0.32
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-dev-client/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client )
Updates `expo-dev-menu` from 55.0.26 to 55.0.27
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-dev-menu/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-menu )
Updates `expo-device` from 55.0.15 to 55.0.16
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-device/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-device )
Updates `expo-file-system` from 55.0.17 to 55.0.19
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-file-system/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-file-system )
Updates `expo-linking` from 55.0.14 to 55.0.15
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-linking/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-linking )
Updates `expo-location` from 55.1.8 to 55.1.9
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-location/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location )
Updates `expo-router` from 55.0.13 to 55.0.14
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-router/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router )
Updates `expo-splash-screen` from 55.0.19 to 55.0.20
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-splash-screen/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-splash-screen )
Updates `expo-status-bar` from 55.0.5 to 55.0.6
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-status-bar/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-status-bar )
Updates `expo-system-ui` from 55.0.16 to 55.0.17
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-system-ui/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-system-ui )
Updates `expo-web-browser` from 55.0.14 to 55.0.15
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-web-browser/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-web-browser )
Updates `react-native-gesture-handler` from 2.31.1 to 2.31.2
- [Release notes](https://github.com/software-mansion/react-native-gesture-handler/releases )
- [Commits](https://github.com/software-mansion/react-native-gesture-handler/compare/v2.31.1...v2.31.2 )
Updates `react-native-reanimated` from 4.3.0 to 4.3.1
- [Release notes](https://github.com/software-mansion/react-native-reanimated/releases )
- [Changelog](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-reanimated/RELEASE.md )
- [Commits](https://github.com/software-mansion/react-native-reanimated/commits/4.3.1/packages/react-native-reanimated )
Updates `jest-expo` from 55.0.16 to 55.0.17
- [Changelog](https://github.com/expo/expo/blob/main/packages/jest-expo/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/jest-expo )
Updates `react-test-renderer` from 19.2.5 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases )
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md )
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react-test-renderer )
Updates `@codemirror/view` from 6.41.1 to 6.42.1
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md )
- [Commits](https://github.com/codemirror/view/commits )
Updates `@react-router/dev` from 7.14.2 to 7.15.0
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dev/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/dev@7.15.0/packages/react-router-dev )
Updates `@react-router/node` from 7.14.2 to 7.15.0
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-node/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/node@7.15.0/packages/react-router-node )
Updates `@react-router/serve` from 7.14.2 to 7.15.0
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-serve/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/@react-router/serve@7.15.0/packages/react-router-serve )
Updates `@sentry/node` from 10.51.0 to 10.52.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.51.0...10.52.0 )
Updates `@sentry/react` from 10.51.0 to 10.52.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.51.0...10.52.0 )
Updates `@tailwindcss/vite` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases )
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md )
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-vite )
Updates `@types/node` from 22.19.17 to 22.19.18
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases )
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node )
Updates `react-dom` from 19.2.5 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases )
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md )
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react-dom )
Updates `react-router` from 7.14.2 to 7.15.0
- [Release notes](https://github.com/remix-run/react-router/releases )
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md )
- [Commits](https://github.com/remix-run/react-router/commits/react-router@7.15.0/packages/react-router )
Updates `tailwindcss` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases )
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md )
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/tailwindcss )
Updates `vite` from 7.3.2 to 7.3.3
- [Release notes](https://github.com/vitejs/vite/releases )
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.3/packages/vite/CHANGELOG.md )
- [Commits](https://github.com/vitejs/vite/commits/v7.3.3/packages/vite )
---
updated-dependencies:
- dependency-name: expo
dependency-version: 55.0.23
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react
dependency-version: 19.2.0
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@expo/fingerprint"
dependency-version: 0.16.7
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: i18next
dependency-version: 26.0.10
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-i18next
dependency-version: 17.0.7
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: turbo
dependency-version: 2.9.12
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: typescript-eslint
dependency-version: 8.59.2
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: isbot
dependency-version: 5.1.40
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: zod
dependency-version: 4.4.3
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@expo/metro-runtime"
dependency-version: 55.0.11
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@gorhom/bottom-sheet"
dependency-version: 5.2.14
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@maplibre/maplibre-react-native"
dependency-version: 11.1.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/react-native"
dependency-version: 8.11.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: expo-constants
dependency-version: 55.0.16
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-dev-client
dependency-version: 55.0.32
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-dev-menu
dependency-version: 55.0.27
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-device
dependency-version: 55.0.16
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-file-system
dependency-version: 55.0.19
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-linking
dependency-version: 55.0.15
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-location
dependency-version: 55.1.9
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-router
dependency-version: 55.0.14
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-splash-screen
dependency-version: 55.0.20
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-status-bar
dependency-version: 55.0.6
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-system-ui
dependency-version: 55.0.17
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-web-browser
dependency-version: 55.0.15
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-native-gesture-handler
dependency-version: 2.31.2
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-native-reanimated
dependency-version: 4.3.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: jest-expo
dependency-version: 55.0.17
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-test-renderer
dependency-version: 19.2.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@codemirror/view"
dependency-version: 6.42.1
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@react-router/dev"
dependency-version: 7.15.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@react-router/node"
dependency-version: 7.15.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@react-router/serve"
dependency-version: 7.15.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/node"
dependency-version: 10.52.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/react"
dependency-version: 10.52.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@tailwindcss/vite"
dependency-version: 4.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@types/node"
dependency-version: 22.19.18
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-dom
dependency-version: 19.2.6
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: react-router
dependency-version: 7.15.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: tailwindcss
dependency-version: 4.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: vite
dependency-version: 7.3.3
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
...
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-10 08:42:40 +00:00
Ullrich Schäfer
b9aac2859a
Drop auth.server.ts re-exports + rename to .server.ts convention (task 5.2)
...
Two cleanups in one pass:
1. Update import paths app-wide from `~/lib/auth.server` to
`~/lib/auth/session.server` for the four session helpers
(sessionStorage, createSession, getSessionUser, destroySession).
~40 files: 33 simple path swaps where the file imported only session
symbols, 5 splits where it also imported per-method auth functions
(auth.verify.tsx, api.settings.email.ts, activities.\$id.tsx,
routes.\$id.tsx, auth.accept-terms.tsx) — those keep one import
from auth.server (for verifyMagicToken, canView, recordTermsAcceptance,
etc.) and gain a second import from auth/session.server.
Two more files used relative paths and were missed by the first
grep pass (lib/oauth.server.ts and routes/oauth.authorize.tsx) —
migrated too.
The @deprecated re-exports block in auth.server.ts is gone.
2. Rename the new auth files to follow the project's `.server.ts`
convention so Vite/React Router treat them as server-only (they
read process.env.SESSION_SECRET, hit the DB, etc. — must NOT enter
the client bundle):
- auth/session.ts → auth/session.server.ts
- auth/completion.ts → auth/completion.server.ts
- auth/completion.test.ts → auth/completion.server.test.ts
Done with `git mv` so blame is preserved.
Verified: typecheck + lint green; 126 unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 03:01:30 +02:00
Ullrich Schäfer
d64c47614d
Implement completeAuth chokepoint + caller migration
...
Implements all of unify-auth-completion (12/14 tasks done; manual
smoke + archive-time spec sync remain).
Design refinement during implementation: completeAuth supports two
response shapes via a `mode` parameter:
- mode: 'redirect' (loaders / direct browser navigation; auth.verify.tsx)
- mode: 'json' (action handlers called by imperative fetch from
client forms; api.auth.login, api.auth.register)
Both modes share createSession + safeReturnTo + Set-Cookie. JSON mode
carries `{ ok: true, step: "done", redirectTo }` (the `step` field
preserves the existing client-form check).
Why two modes: passkey ceremonies are inherently imperative
(start → browser WebAuthn API → finish), so action handlers can't
move to <Form>/useFetcher. Picking option (B) from the design grill —
the chokepoint owns destination selection while clients navigate —
required this dual shape. The 3 hardcoded client-side targets
(returnTo ?? "/", "/", "/?add-passkey=1") collapse into 1 server-side
sanitization pass (safeReturnTo) inside completeAuth.
New module:
- apps/journal/app/lib/auth/session.ts: cookie session storage
(sessionStorage, createSession, getSessionUser, destroySession)
moved from auth.server.ts. Legacy import path kept via re-exports
with @deprecated JSDoc.
- apps/journal/app/lib/auth/completion.ts: completeAuth + safeReturnTo.
- apps/journal/app/lib/auth/completion.test.ts: 10 contract tests
covering both modes, returnTo sanitization (path-relative, protocol-
relative, absolute-URL, malformed), Set-Cookie attachment, redirect
status, JSON shape.
Caller migration:
- api.auth.register.ts passkey-finish → completeAuth(json)
- api.auth.login.ts finish-passkey → completeAuth(json)
- api.auth.login.ts verify-code → completeAuth(json)
- auth.verify.tsx magic-link consumer → completeAuth(redirect)
Client form updates:
- auth.login.tsx: pass returnTo in fetch body, read result.redirectTo
on done.
- auth.register.tsx: pass returnTo: "/?add-passkey=1" for the magic-
link verify-code path (preserves the post-register passkey prompt
via the chokepoint's safeReturnTo, instead of hardcoding it
client-side).
Verified:
- pnpm typecheck && pnpm lint: green across all 15 workspaces.
- pnpm --filter @trails-cool/journal test: 126 passed.
- pnpm test:e2e auth: 4/4 passed without modification — confirms the
refactor is behaviour-preserving for the user-facing flows that
matter most (passkey register + login).
Spec delta in openspec/changes/unify-auth-completion/specs/ applies at
/opsx:archive time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 02:38:15 +02:00
Ullrich Schäfer
067e2ebd0b
fix: enforce Terms gate on bearer-token API requests
...
Mobile API requests authenticated via OAuth2 bearer tokens bypassed the
Terms gate that the root loader applies to web cookie sessions. Extend
requireApiUser to compare the user's termsVersion with TERMS_VERSION
and return a structured 403 { code: "TERMS_OUTDATED", currentTermsVersion }
on mismatch so mobile clients can surface their own re-acceptance UI.
Spec delta on journal-auth captures the new requirement.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:59:28 +02:00
Ullrich Schäfer
8e5b6d6fe9
Wahoo capability adapters + caller migration (groups 3-5)
...
Implements tasks 1.3, 3.2-3.3, 4.1-4.4, 5.1-5.6, 6.1 of
deepen-connected-services. Built TDD: contract test red, adapter green
for each capability seam.
Capability adapters (providers/wahoo/):
- importer.ts: Importer seam — listImportable + importOne against
Wahoo /v1/workouts. Filters fitness_app_id >= 1000 (Wahoo doesn't
share third-party data). 2 contract tests green.
- pusher.ts: RoutePusher seam — pushRoute(ctx, input) -> {remoteId,
version}. FIT-Course conversion, route:<id> external_id, PUT-vs-POST
decision, PUT->POST-on-404 fallback all internal to the adapter
(per ADR-0003). Idempotency via sync_pushes preserved. 4 contract
tests green.
- webhook.ts: WebhookReceiver seam — parseWebhook + handle. Routes
events to local users via provider_user_id; unknown user returns
silently. 6 contract tests green.
- manifest.ts: declares credential_kind=oauth, OAuth config, scopes,
buildAuthUrl, exchangeCode, and references each capability adapter.
Module shape:
- connected-services/index.ts: side-effect imports providers/index.ts
to register manifests, then re-exports manager + registry + types.
- connected-services/providers/index.ts: barrel that calls
registerManifest(wahooManifest).
- connected-services/oauth-state.server.ts: OAuth state encode/decode
(extracted from legacy pushes.server.ts).
- connected-services/push-action.server.ts: orchestration above the
RoutePusher seam — load route, ownership check, scope check, build
RoutePushInput, invoke pusher, return PushOutcome union. Replaces
the legacy pushRouteToProvider in lib/sync/pushes.server.ts.
Caller migration (group 5):
- api.sync.connect.$provider.ts -> manifest.buildAuthUrl
- api.sync.callback.$provider.ts -> manifest.exchangeCode + link()
- api.sync.disconnect.$provider.ts -> unlinkByUserProvider (calls
best-effort revoke via the credential adapter, then deletes locally)
- api.sync.webhook.$provider.ts -> manifest.webhookReceiver dispatch
- api.sync.push.$provider.$routeId.ts -> push-action.pushRouteToProvider
- sync.import.$provider.tsx -> manifest.importer.listImportable +
inline FIT->GPX in the action (form-supplied metadata bypasses the
Importer seam which is reserved for automatic / webhook imports)
- routes.$id.tsx -> getService instead of getConnection
- settings.connections.tsx -> getAllManifests instead of legacy registry
Legacy lib/sync/ deleted except imports.server.ts (which manages the
sync_imports table, untouched by this change).
DB migration verified locally (task 1.3): pnpm db:migrate-data renamed
the table and backfilled credentials JSONB; pnpm db:push then dropped
the legacy access_token/refresh_token/expires_at columns. Final shape
matches the schema; check constraints + unique index in place.
Test status (task 6.1):
- pnpm typecheck: green across all 15 workspaces
- pnpm lint: green
- @trails-cool/journal: 112 passed, 31 skipped — 12 fewer tests than
before because pushes.server.test.ts and the legacy wahoo.test.ts
were deleted. Their coverage is replaced by the new contract tests
(importer/pusher/webhook) plus manager.test.ts + oauth.test.ts.
Remaining: 6.2 (e2e), 6.3-6.4 (manual smoke + staging migration test),
7.1-7.3 (followups + spec deltas at archive).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:25:33 +02:00
Ullrich Schäfer
5dda69ab49
Lint fix: drop unused ProviderOAuthConfig type import
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:14:38 +02:00
Ullrich Schäfer
6de516718d
Schema rename + ConnectedServiceManager foundation (groups 1-2)
...
Implements tasks 1.1-1.4 and 2.1-2.5 of deepen-connected-services:
DB:
- Rename journal.sync_connections -> journal.connected_services.
- Add credential_kind discriminator (oauth | web-login | device) and
credentials JSONB (shape per kind), status column, and a unique index
on (user_id, provider) lifting the previously app-only invariant
into the DB.
- Idempotent backfill in 0002_connected_services.sql moves existing
Wahoo rows' tokens into the JSONB blob with credential_kind='oauth'.
Code:
- New apps/journal/app/lib/connected-services/ module:
- types.ts: ConnectedService, CredentialKind, OAuthCredentials,
NeedsRelinkError, CredentialAdapter, ProviderOAuthConfig, etc.
- credential-adapters/oauth.ts: standard OAuth2 refresh_token flow,
revoke endpoint, 4xx -> NeedsRelinkError / 5xx -> transient.
- manager.ts: ConnectedServiceManager (link, unlink, withFreshCredentials,
markNeedsRelink). Centralizes credential lifecycle in one chokepoint.
- registry.ts: ProviderManifest type + capability seam interfaces
(Importer, RoutePusher, WebhookReceiver). Manifests register
themselves at import time.
Tests:
- manager.test.ts (8 tests): refresh-on-expired, refresh-fail->needs_relink,
ConnectionNotActiveError, link/unlink, revoke is best-effort.
- credential-adapters/oauth.test.ts (10 tests): refresh contract,
refresh_token retention, 4xx vs 5xx behaviour, revoke.
- All 18 new tests pass.
Compatibility:
- apps/journal/app/lib/sync/connections.server.ts is now a thin shim
translating the legacy TokenSet API onto the JSONB-shaped table so
existing callers (routes, pushes.server.ts) keep working until tasks
5.x migrate them to the manager. To be deleted in task 5.6.
Pre-existing journal test failures (12) are unrelated to this change:
they pre-date this PR and stem from a workspace resolution issue with
@trails-cool/fit (verified by running tests against main).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 01:14:38 +02:00
Ullrich Schäfer
7615ecb6e7
Test PR for staging preview lifecycle
...
Adds a one-line clarifying comment near TERMS_GATE_ALLOWLIST. The point
of this PR is to exercise cd-staging.yml end-to-end (preview deploy on
open, update on push, teardown on close).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 22:18:06 +02:00
dependabot[bot]
eec904971d
Bump the production group with 19 updates
...
Bumps the production group with 19 updates:
| Package | From | To |
| --- | --- | --- |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo ) | `55.0.17` | `55.0.19` |
| [@sentry/vite-plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins ) | `5.2.0` | `5.2.1` |
| [eslint](https://github.com/eslint/eslint ) | `10.2.1` | `10.3.0` |
| [jsdom](https://github.com/jsdom/jsdom ) | `29.0.2` | `29.1.1` |
| [react-i18next](https://github.com/i18next/react-i18next ) | `17.0.4` | `17.0.6` |
| [turbo](https://github.com/vercel/turborepo ) | `2.9.6` | `2.9.8` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint ) | `8.59.0` | `8.59.1` |
| [jose](https://github.com/panva/jose ) | `6.2.2` | `6.2.3` |
| [nodemailer](https://github.com/nodemailer/nodemailer ) | `8.0.6` | `8.0.7` |
| [zod](https://github.com/colinhacks/zod ) | `4.3.6` | `4.4.2` |
| [@gorhom/bottom-sheet](https://github.com/gorhom/react-native-bottom-sheet ) | `5.2.10` | `5.2.13` |
| [@sentry/cli](https://github.com/getsentry/sentry-cli ) | `3.4.0` | `3.4.1` |
| [@sentry/react-native](https://github.com/getsentry/sentry-react-native ) | `8.9.1` | `8.10.0` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client ) | `55.0.28` | `55.0.30` |
| [expo-dev-menu](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-menu ) | `55.0.24` | `55.0.26` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications ) | `55.0.20` | `55.0.22` |
| [pg-boss](https://github.com/timgit/pg-boss ) | `12.18.0` | `12.18.2` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript ) | `10.50.0` | `10.51.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript ) | `10.49.0` | `10.51.0` |
Updates `expo` from 55.0.17 to 55.0.19
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo )
Updates `@sentry/vite-plugin` from 5.2.0 to 5.2.1
- [Release notes](https://github.com/getsentry/sentry-javascript-bundler-plugins/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript-bundler-plugins/compare/5.2.0...5.2.1 )
Updates `eslint` from 10.2.1 to 10.3.0
- [Release notes](https://github.com/eslint/eslint/releases )
- [Commits](https://github.com/eslint/eslint/compare/v10.2.1...v10.3.0 )
Updates `jsdom` from 29.0.2 to 29.1.1
- [Release notes](https://github.com/jsdom/jsdom/releases )
- [Commits](https://github.com/jsdom/jsdom/compare/v29.0.2...v29.1.1 )
Updates `react-i18next` from 17.0.4 to 17.0.6
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md )
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.4...v17.0.6 )
Updates `turbo` from 2.9.6 to 2.9.8
- [Release notes](https://github.com/vercel/turborepo/releases )
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md )
- [Commits](https://github.com/vercel/turborepo/compare/v2.9.6...v2.9.8 )
Updates `typescript-eslint` from 8.59.0 to 8.59.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases )
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md )
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.59.1/packages/typescript-eslint )
Updates `jose` from 6.2.2 to 6.2.3
- [Release notes](https://github.com/panva/jose/releases )
- [Changelog](https://github.com/panva/jose/blob/main/CHANGELOG.md )
- [Commits](https://github.com/panva/jose/compare/v6.2.2...v6.2.3 )
Updates `nodemailer` from 8.0.6 to 8.0.7
- [Release notes](https://github.com/nodemailer/nodemailer/releases )
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md )
- [Commits](https://github.com/nodemailer/nodemailer/compare/v8.0.6...v8.0.7 )
Updates `zod` from 4.3.6 to 4.4.2
- [Release notes](https://github.com/colinhacks/zod/releases )
- [Commits](https://github.com/colinhacks/zod/compare/v4.3.6...v4.4.2 )
Updates `@gorhom/bottom-sheet` from 5.2.10 to 5.2.13
- [Release notes](https://github.com/gorhom/react-native-bottom-sheet/releases )
- [Changelog](https://github.com/gorhom/react-native-bottom-sheet/blob/master/CHANGELOG.md )
- [Commits](https://github.com/gorhom/react-native-bottom-sheet/compare/v5.2.10...v5.2.13 )
Updates `@sentry/cli` from 3.4.0 to 3.4.1
- [Release notes](https://github.com/getsentry/sentry-cli/releases )
- [Changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-cli/compare/3.4.0...3.4.1 )
Updates `@sentry/react-native` from 8.9.1 to 8.10.0
- [Release notes](https://github.com/getsentry/sentry-react-native/releases )
- [Changelog](https://github.com/getsentry/sentry-react-native/blob/main/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-react-native/compare/8.9.1...8.10.0 )
Updates `expo-dev-client` from 55.0.28 to 55.0.30
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client )
Updates `expo-dev-menu` from 55.0.24 to 55.0.26
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-menu )
Updates `expo-notifications` from 55.0.20 to 55.0.22
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md )
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications )
Updates `pg-boss` from 12.18.0 to 12.18.2
- [Release notes](https://github.com/timgit/pg-boss/releases )
- [Commits](https://github.com/timgit/pg-boss/compare/12.18.0...12.18.2 )
Updates `@sentry/node` from 10.50.0 to 10.51.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.50.0...10.51.0 )
Updates `@sentry/react` from 10.49.0 to 10.51.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases )
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md )
- [Commits](https://github.com/getsentry/sentry-javascript/compare/10.49.0...10.51.0 )
---
updated-dependencies:
- dependency-name: expo
dependency-version: 55.0.19
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/vite-plugin"
dependency-version: 5.2.1
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: eslint
dependency-version: 10.3.0
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: jsdom
dependency-version: 29.1.1
dependency-type: direct:development
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: react-i18next
dependency-version: 17.0.6
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: turbo
dependency-version: 2.9.8
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: typescript-eslint
dependency-version: 8.59.1
dependency-type: direct:development
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: jose
dependency-version: 6.2.3
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: nodemailer
dependency-version: 8.0.7
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: zod
dependency-version: 4.4.2
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@gorhom/bottom-sheet"
dependency-version: 5.2.13
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/cli"
dependency-version: 3.4.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/react-native"
dependency-version: 8.10.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: expo-dev-client
dependency-version: 55.0.30
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-dev-menu
dependency-version: 55.0.26
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: expo-notifications
dependency-version: 55.0.22
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: pg-boss
dependency-version: 12.18.2
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: production
- dependency-name: "@sentry/node"
dependency-version: 10.51.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
- dependency-name: "@sentry/react"
dependency-version: 10.51.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: production
...
Signed-off-by: dependabot[bot] <support@github.com>
2026-05-03 08:33:39 +00:00
Ullrich Schäfer
db3eeed60f
Apply wahoo-route-update: PUT on re-push instead of duplicate POST
...
Re-pushing an edited route to Wahoo now updates the existing remote
route via PUT against the stored remote_id instead of POSTing a new
copy. external_id drops the version suffix and identifies the logical
route. sync_pushes is keyed by (user, route, provider) and tracks
last_pushed_version for the "local newer" UI state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 12:08:16 +02:00
Ullrich Schäfer
5ea7342f4e
Send Wahoo route file as data URI, not raw base64
...
Wahoo's POST /v1/routes expects route[file] as
'data:application/vnd.fit;base64,<base64>'. We were sending raw
base64, which Wahoo silently discarded — the route would appear in
the user's list with metadata (distance, ascent come from request
fields) but file.url stayed null and the Wahoo app rendered no track.
Confirmed by re-fetching route 50197876 via GET /v1/routes/:id.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 10:29:43 +02:00
Ullrich Schäfer
8b1d473902
Request routes_read Wahoo scope
...
GET /v1/routes/:id needs routes_read; routes_write only covers writes.
Existing connections will need to reauthorize to gain the new scope.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 10:18:13 +02:00
Ullrich Schäfer
b60cd96736
Revoke Wahoo tokens on disconnect; surface OAuth errors
...
Disconnecting a sync provider now calls the provider's revoke endpoint
(DELETE /v1/permissions for Wahoo) before dropping the local row, so
tokens don't accumulate against Wahoo's per-(app,user) cap. The token
exchange now classifies Wahoo's "Too many unrevoked access tokens" 400
as a distinct OAuthError code, and the connections settings page shows
a localized banner for that and other connect failures instead of a
silent ?error=sync_failed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 10:03:50 +02:00
Ullrich Schäfer
fee27f1cd6
Use form-encoded bodies for Wahoo OAuth token requests
...
Wahoo's /oauth/token endpoint returns 400 for JSON bodies. OAuth 2.0
requires application/x-www-form-urlencoded for token requests; switch
exchangeCode and refreshToken to URLSearchParams. Also include the
response body in the thrown error so future failures are diagnosable
without scraping container logs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 09:29:56 +02:00
Ullrich Schäfer
70a1387998
Fix OAuth callback returnTo after settings split
...
The connect loader was setting state to a raw user.id, but the callback
parses state as base64-JSON via decodeOAuthState and falls back to {}
when the parse fails. That sent users back to /settings, which now
redirects to /settings/profile, hiding the freshly saved connection on
a different tab.
Encode the state as a proper PushOAuthState with returnTo set to
/settings/connections so the callback lands on the page that initiated
the flow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 09:20:19 +02:00
Ullrich Schäfer
c89c5798bb
Add packages/fit to journal and planner Dockerfiles
...
The deps stage was missing the COPY for packages/fit/package.json, so
@trails-cool/fit was absent from the workspace at install time and
@garmin/fitsdk could not be resolved during the journal build.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 08:10:15 +02:00
Ullrich Schäfer
76c3e49de2
Add Send to Wahoo UI, i18n, and privacy disclosure
...
Route detail page now renders one of three states for the owner of a
route with a Wahoo connection:
- "Send to Wahoo" button + privacy tooltip when no successful push
exists for the current version, plus the inline last-error blurb
if the previous attempt failed
- "Sent to Wahoo on <date>" pill when sync_pushes has a pushedAt
for the current version
- Banner row at the top mapping the ?push= and ?code= query params
the action route appends to user-facing copy
i18n strings cover all 8 banner states (success, needs_permission,
no_connection, no_geometry, validation, rate_limit, token_expired,
generic) in English and German.
Privacy disclosure lives at /legal/privacy (apps/journal/app/routes/
legal.privacy.tsx), the in-app surface this repo uses instead of a
docs/privacy.md manifest. The new bullet declares that route
geometry, name, and description are transmitted to Wahoo on opt-in
via the Send to Wahoo button.
E2E tests for the push and re-auth flows (tasks 9.4/9.5) are
deferred — they need a server-side Wahoo mock harness that doesn't
exist yet. Slice-4 unit tests cover the pipeline against the
provider mock.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 22:44:50 +02:00
Ullrich Schäfer
a9c0093877
Add Wahoo push action route + OAuth callback resume
...
Adds /api/sync/push/:provider/:routeId as the user-triggered entry
point for pushing a route. The route action delegates to a new
pushes.server.ts pipeline that:
- resolves the latest route_versions row and uses that GPX (not
routes.gpx) so the bytes Wahoo gets match the snapshot the user
sees
- short-circuits on (user, route, version, provider) idempotency:
a successful prior push returns the existing remote_id without
re-calling Wahoo
- detects scope_missing before hitting Wahoo and redirects through
getAuthUrl with a base64url-encoded state carrying pushAfter +
returnTo
- refreshes tokens once on PushError({ code: "token_expired" }) and
retries the push, then updates sync_connections in place
- records every outcome in sync_pushes (insert on first attempt,
update on retry) so the UI can show success/failure state
The OAuth callback handler now decodes the state, resumes a
pushAfter pipeline server-side after exchangeCode, and handles the
?error=access_denied path with a needs_permission notice.
Also flips packages/fit/src/fitsdk.d.ts to a regular .ts side-effect
shim so journal's tsc picks up the @garmin/fitsdk module declaration
when consuming the workspace package via source.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 22:41:24 +02:00
Ullrich Schäfer
5b0bf40b97
Add Wahoo pushRoute and SyncProvider push interface
...
Extends the SyncProvider interface with an optional pushRoute method
plus PushRoutePayload, PushRouteResult, and a typed PushError so the
slice-4 action route can map error codes to user-facing copy without
parsing HTTP statuses itself.
Wahoo provider:
- adds routes_write to the requested OAuth scope set
- implements pushRoute: base64-encodes the FIT, builds the form body
Wahoo's POST /v1/routes expects, parses the remote id out of the
response, and throws typed PushError on 401/403/422/429/5xx
- saveConnection now persists the requested scopes as grantedScopes
on exchangeCode (Wahoo doesn't return a scope field, so the
requested set is the granted set)
Token refresh on 401 is deferred to the slice-4 action route — same
pattern as the existing webhook handler in this repo, which does
inline refresh rather than wrapping every call.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 22:36:45 +02:00
Ullrich Schäfer
8ba5554a67
Add @trails-cool/fit package with GPX→FIT Course encoder
...
Wraps @garmin/fitsdk to emit FIT Course files from GPX, the binary
format Wahoo's POST /v1/routes API requires. Server-side only — the
~1 MB SDK never ships to the planner browser bundle.
Round-trip tests use fit-file-parser as an independent oracle and
assert lat/lon parity within 1e-4 deg and altitude within 0.5 m
across short flat, alpine, multi-day, and single-point fixtures.
Updates design.md decision #1 : the original hand-rolled-encoder plan
was justified largely by ESM friction in the Garmin SDK, but as of
v21.202.0 the SDK is pure ESM with zero deps. Wrapping it saves us
~400 LOC of binary plumbing and ongoing maintenance against future
FIT spec updates.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 22:31:37 +02:00