Commit graph

665 commits

Author SHA1 Message Date
Ullrich Schäfer
4c089756a1
Fix sentry-config typecheck: explicit types: [node] in tsconfig
@types/node is a devDependency of the package but tsc only auto-picks
it up locally due to root node_modules hoisting. CI runs with pnpm's
isolated resolution so the dep isn't visible to tsc without an
explicit types field — matching what packages/jobs/tsconfig.json does.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 00:43:48 +02:00
Ullrich Schäfer
01f002cc46
Stop Sentry on logout; fix E2E + Dockerfile for merged consolidation
- sentry.client.ts: add stopSentryClient() that awaits Sentry.close() so
  the SDK tears down when a user logs out. Hub methods become no-ops
  until initSentryClient() is called again on next login.
- root.tsx: call stopSentryClient() from the user-effect when user === null.
- Add sentry-config to journal + planner Dockerfiles (was missing after
  #237 introduced the new workspace package, breaking the Dockerfile
  package check).
- Footer: replace inner <nav> with <div> — nested nav landmarks broke
  the journal "nav bar shows on all pages" e2e test (two navigation
  roles on the page).
- e2e auth: tick the required ToS checkbox in the shared registerUser
  helper so passkey registration tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 00:40:36 +02:00
Ullrich Schäfer
adbf507101
Merge pull request #237 from trails-cool/feat/sentry-consolidation-v2
Consolidate Sentry config; fix Planner PII & missing captureException
2026-04-18 00:31:25 +02:00
Ullrich Schäfer
8e576ac578
Consolidate Sentry config into shared package; fix inconsistencies
Introduces @trails-cool/sentry-config with three helpers that encode
the common Sentry.init options:
- nodeSentryConfig(appContext) for the two HTTP servers
- browserSentryConfig(appContext, env) for the Journal client
- mobileSentryConfig(__DEV__) for the React Native app
- drop404s beforeSend for servers

Also fixes three inconsistencies found in the audit:
- Planner server was missing sendDefaultPii: false (IPs could leak)
- Planner entry.server.tsx didn't call Sentry.captureException on SSR
  render errors; Journal's SSR did
- Sentry.init location now matches across apps (both in server.ts;
  Journal previously had it in app/entry.server.tsx, which meant init
  ran lazily on first request rather than at server startup)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 00:30:09 +02:00
Ullrich Schäfer
27c9892bab
Merge pull request #236 from trails-cool/feat/sentry-dev-log
Log Sentry dev-inert status; explicit replay=0
2026-04-18 00:15:48 +02:00
Ullrich Schäfer
4092f21475
Log Sentry dev-inert status; explicit replay=0
When Sentry init runs but is disabled (local dev / CI), log a debug
message so developers can see Sentry *would* send in production.

Also explicitly set replaysSessionSampleRate/replaysOnErrorSampleRate
to 0 in the client and mobile configs. Replay integration isn't
installed, so this is documentation — it prevents future accidental
enablement if an integration is ever added.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 00:15:31 +02:00
Ullrich Schäfer
cc0f44258a
Add legal pages, ToS acceptance, and alpha banner
- Journal: Impressum (§5 TMG), Terms of Service, GDPR privacy page
- Registration flow: required ToS checkbox, termsAcceptedAt persisted
- Alpha banner on Journal (always visible); alpha badge on Planner hero
- Footer with legal links + GitHub on both apps
- Reduce PII: sendDefaultPii=false, Sentry init only after login (Journal)
- Drop Sentry from Planner (no login, no consent possible)
- Drop localStorage caching from i18n client detection
- Sync SSR i18n resources each request so locale edits HMR without restart

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 00:08:48 +02:00
Ullrich Schäfer
6c1cd23358
Merge pull request #232 from trails-cool/feat/login-code
Add login code for mobile authentication
2026-04-17 22:53:43 +02:00
Ullrich Schäfer
a056ec286b
Merge branch 'main' into feat/login-code 2026-04-17 22:38:57 +02:00
Ullrich Schäfer
1397eb0d1d
Merge pull request #233 from trails-cool/spec/legal-disclaimers
Spec: Legal disclaimers (Impressum, Terms, alpha status)
2026-04-17 22:32:24 +02:00
Ullrich Schäfer
b58d899132
Merge branch 'main' into spec/legal-disclaimers 2026-04-17 22:29:44 +02:00
Ullrich Schäfer
d06ce8d77d
Merge pull request #234 from trails-cool/fix/main-ci-broken
Fix CI on main: typecheck and lint errors
2026-04-17 22:29:23 +02:00
Ullrich Schäfer
258e1bb5e5
Fix CI on main: RouteMap typecheck + metro.config lint
- RouteMap.tsx referenced undefined MapLibreRN namespace, causing
  typecheck to fail on main and in every downstream PR
- metro.config.js is CommonJS, exclude from ESLint flat config

Changes that were pushed directly to main earlier bypassed CI and
broke both typecheck and lint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:26:38 +02:00
Ullrich Schäfer
680815e1f6 Add OpenSpec proposal for legal disclaimers
Proposal, design, specs, and tasks for German legal compliance (Impressum,
Datenschutzerklärung, ToS) and alpha-stage disclaimers at signup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:12:23 +02:00
Ullrich Schäfer
3bcb1fce7c
Add 6-digit login code for mobile authentication
Magic links open in the device browser, not the OAuth in-app browser,
so the session doesn't carry over. A login code lets mobile users
type a 6-digit code from their email into the login page instead.

- Generate 6-digit numeric code alongside magic link token
- Store code in magic_tokens table
- Add verify-code step to login API endpoint
- Show code input UI after magic link is sent
- Include code in email template
- i18n keys for code UI (en + de)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 20:56:42 +02:00
Ullrich Schäfer
2a94af5655
Add Metro config for monorepo module resolution
Metro couldn't resolve hoisted packages (@maplibre, @gorhom, etc.)
because it only looked in apps/mobile/node_modules. Configure
watchFolders and nodeModulesPaths to include the monorepo root.

Also revert MapLibre fallback — direct import is correct, the issue
was Metro resolution, not a missing native module.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 07:39:04 +02:00
Ullrich Schäfer
58bff065ff
Gracefully handle missing MapLibre native module
Use try/catch require() for MapLibre so the app works without it
(shows fallback UI). Needed when running on builds that don't include
MapLibre native module (old EAS builds, Expo Go).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 07:28:25 +02:00
Ullrich Schäfer
d74a19afb6
Merge pull request #231 from trails-cool/fix/route-compute-auth
Fix route compute 401: use authenticated API client
2026-04-15 07:15:29 +02:00
Ullrich Schäfer
5c4c0ae49d
Fix route compute 401: use authenticated API client
The route editor called fetch() directly for /api/v1/routes/compute
without the bearer token. Now uses the API client which injects auth
headers and handles 401 auto-refresh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 07:12:13 +02:00
Ullrich Schäfer
3ad2ef9006
Merge pull request #230 from trails-cool/fix/flaky-overnight-e2e
Fix flaky overnight E2E test timeout
2026-04-15 02:30:55 +02:00
Ullrich Schäfer
b7fe68359c
Fix flaky overnight E2E test: increase timeouts
The "Waypoints (3)" assertion timed out at 5s in CI. The waypoints
load from URL params but the sidebar needs BRouter mock response +
Yjs sync before updating. Increase to 15s to match other assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 02:27:59 +02:00
Ullrich Schäfer
c838bd1efc
Merge pull request #229 from trails-cool/fix/android-dev-networking
Allow cleartext HTTP on Android for dev server
2026-04-15 02:25:38 +02:00
Ullrich Schäfer
310f20e0a3
Allow cleartext HTTP on Android for dev server
Android 9+ blocks cleartext HTTP by default. Enable usesCleartextTraffic
so the emulator can reach the Journal dev server at http://10.0.2.2:3000.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 02:21:06 +02:00
Ullrich Schäfer
64b2372a13
Merge pull request #228 from trails-cool/feat/mobile-route-editing
Mobile route editor, MapLibre, bottom sheet, and local builds
2026-04-15 01:26:09 +02:00
Ullrich Schäfer
6c55de9d65
Fix Android emulator dev server: use 10.0.2.2 instead of localhost
Android emulator has its own network stack — localhost refers to the
emulator, not the host. Use 10.0.2.2 (host loopback alias) on Android.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:22:50 +02:00
Ullrich Schäfer
b2514f48be
Add local build scripts via Expo CNG/prebuild
- prebuild: generate native ios/ and android/ projects
- prebuild:clean: regenerate from scratch
- run:ios / run:android: build and run locally with Xcode/Gradle
- Add ios/ and android/ to .gitignore (CNG-generated)

Allows building locally without EAS credits:
  pnpm --filter @trails-cool/mobile prebuild
  pnpm --filter @trails-cool/mobile run:ios

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:19:37 +02:00
Ullrich Schäfer
bdde95e69b
Use @gorhom/bottom-sheet for waypoint sheet
Replace custom View-based bottom sheet with @gorhom/bottom-sheet:
- Native gesture-driven drag, snap points, pan-down-to-close
- Proper safe area handling built in
- Wrap app with GestureHandlerRootView
- Add react-native-reanimated plugin to Expo config

Adds react-native-reanimated and react-native-gesture-handler as
native dependencies (requires new EAS build).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:09:13 +02:00
Ullrich Schäfer
fe07fbdf59
Fix WaypointSheet safe area: add bottom inset padding
Close button was overlapping the home indicator. Now uses
useSafeAreaInsets() for dynamic bottom padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
d45f1e14fd
Fix route display: parse track coordinates from GPX on init
The route polyline wasn't visible because segments were initialized
empty. Now extractSegmentsFromGpx() parses trkpt coordinates from
the GPX string via regex on init, so the route shows immediately
in both view and edit modes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
bd311cd339
Implement mobile route editor with MapLibre and BRouter routing
Route editing (Phase 3.3):
- useRouteEditor hook: waypoint state, add/move/delete, BRouter
  routing via Journal API proxy, GPX generation, save to API
- RouteMap component: MapLibre Native with OSM raster tiles,
  route polyline (ShapeSource + LineLayer), waypoint markers
  (MarkerView), long-press to add waypoints, computing indicator
- WaypointSheet: bottom sheet for waypoint actions — delete with
  confirmation, overnight stop toggle, coordinates display
- Route detail screen: view mode (map preview + stats) and edit
  mode (full-screen map with save button)
- Unsaved changes guard on navigation (beforeRemove listener)
- Smart waypoint insertion at nearest route segment
- Waypoint extraction from GPX via regex (sync, no DOM needed)

Adds DOM.Iterable to mobile tsconfig for gpx package compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 01:06:10 +02:00
Ullrich Schäfer
62543cd629
Merge pull request #225 from trails-cool/spec/staging-environments
Spec: Staging & PR preview environments
2026-04-15 01:03:49 +02:00
Ullrich Schäfer
448fa8b9b6
Merge branch 'main' into spec/staging-environments 2026-04-15 01:01:05 +02:00
Ullrich Schäfer
d2842937bd
Merge pull request #227 from trails-cool/fix/journal-dockerfile-no-jobs
Fix journal Dockerfile: remove premature app/jobs COPY
2026-04-14 12:33:31 +02:00
Ullrich Schäfer
6cb9a81307 Extend Dockerfile CI check to verify COPY source paths exist
The check now also verifies that source paths referenced by
COPY --from=build lines actually exist in the repo. This would have
caught the premature app/jobs COPY that broke the journal build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:27:18 +02:00
Ullrich Schäfer
8886764ec8 Remove premature app/jobs COPY from journal Dockerfile
The journal doesn't have an app/jobs directory yet — that will arrive
with the Komoot import PR. The COPY line was added prematurely and
breaks the Docker build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:26:10 +02:00
Ullrich Schäfer
a3e97be662
Merge pull request #226 from trails-cool/fix/dockerfile-jobs-package
Fix Dockerfiles: add jobs package for pg-boss resolution
2026-04-14 12:18:32 +02:00
Ullrich Schäfer
7c207a2a98 Add CI check for missing workspace packages in Dockerfiles
Adds a script that verifies every packages/*/package.json is listed in
all app Dockerfiles. Catches the recurring issue where adding a new
workspace package breaks production because the Dockerfile deps stage
doesn't know about it.

Also fixes two pre-existing missing packages in the planner Dockerfile
(api, map-core) caught by the new check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:15:25 +02:00
Ullrich Schäfer
fe57a690c0 Fix Dockerfiles: add jobs package for pg-boss resolution
Both Dockerfiles were missing packages/jobs/package.json in the deps stage,
causing pnpm install to skip pg-boss. Also copy app/jobs directories into
the runtime stage so job handlers are available at runtime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 12:13:09 +02:00
Ullrich Schäfer
29f9808557
Merge pull request #224 from trails-cool/feat/pg-boss-background-jobs
Add pg-boss background job queue with session expiry
2026-04-14 09:11:45 +02:00
Ullrich Schäfer
f75dd12f59 Fix pg-boss queue creation before work registration
pg-boss v10 requires explicit queue creation via `createQueue()` before
`schedule()` or `work()` can reference a queue. Without this, the planner
crashes on startup in fresh databases (like CI) with "Queue not found".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 09:08:19 +02:00
Ullrich Schäfer
39ebaa9841 Add OpenSpec proposal for staging environments
Proposal, design, specs, and tasks for persistent staging instance and
ephemeral PR preview environments on the existing Hetzner server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 09:02:23 +02:00
Ullrich Schäfer
32c5fbde8f Add pg-boss background job queue with session expiry
Add @trails-cool/jobs package wrapping pg-boss for durable background job
execution using the existing PostgreSQL database. Wire up planner session
expiry as the first scheduled job (hourly, 7-day TTL) — this was previously
dead code that never ran. Add placeholder worker to journal for future
Komoot import and federation jobs.

Infrastructure: grant grafana_reader access to pgboss schema, add job queue
health panels to Service Health dashboard, add failed job alert.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 21:17:24 +02:00
Ullrich Schäfer
fc80e66ad4
Merge pull request #222 from trails-cool/fix/observability-and-crash-fix
Fix journal crash loop and improve observability
2026-04-13 20:43:21 +02:00
Ullrich Schäfer
fda376267c
Merge pull request #221 from trails-cool/feat/mobile-activities-ui
Configure EAS Build, native deps, and Sentry
2026-04-13 02:33:03 +02:00
Ullrich Schäfer
b465081e1b
Fix CI: add react-test-renderer to match react version
The smoke test failed in CI with version mismatch between react
(19.2.5 from catalog) and react-test-renderer (19.2.0 transitive).
Adding it explicitly ensures they stay in sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:30:00 +02:00
Ullrich Schäfer
57ca9b8d0d
Update Sentry auth token with org:ci scope
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:29:33 +02:00
Ullrich Schäfer
04c8995d7c
Update Sentry auth token with org:ci scope
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:27:53 +02:00
Ullrich Schäfer
3c172c1e56
Fix CD: add api and map-core packages to Journal Dockerfile
The journal now depends on @trails-cool/api which depends on zod.
The Dockerfile was missing these package.json files, causing pnpm
install to skip them and the build to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:27:09 +02:00
Ullrich Schäfer
19c2358c88
Fix CD: add api and map-core packages to Journal Dockerfile
The journal now depends on @trails-cool/api (added in PR #217) which
depends on zod. The Dockerfile was missing the package.json for api
and map-core, causing pnpm install to skip them and the build to fail
with "Failed to resolve import zod".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:23:09 +02:00
Ullrich Schäfer
3da7b8d41f
Fix lockfile sync: add @expo/fingerprint to root devDependencies
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 02:21:03 +02:00