Commit graph

142 commits

Author SHA1 Message Date
Ullrich Schäfer
ef130b4b11
Add /deploy-status command
Shows deployed container versions, latest CD run SHA, and health check
for both apps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:25:18 +01:00
github-actions[bot]
2c47f2a705
Merge pull request #53 from trails-cool/implement-sentry-improvements 2026-03-25 02:18:45 +00:00
Ullrich Schäfer
4a721fc586
Add privacy route to journal route config
Route was missing from the explicit routes.ts, so typegen didn't
generate types for it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:15:38 +01:00
Ullrich Schäfer
9d51fd6b36
Archive sentry-improvements, sync specs
Sync Sentry error tracking requirement (5 scenarios) to main
infrastructure spec. Archive completed change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:13:36 +01:00
Ullrich Schäfer
9a904d9f69
Sentry improvements: context, tracing, source maps, privacy manifest
- Set Sentry user context (id, username) in Journal root for all routes
- Tag Planner errors with session_id
- Use reactRouterV7BrowserTracingIntegration for route-aware traces
- Hidden source maps (no sourceMappingURL in bundles, .map deleted after
  upload to Sentry)
- Privacy manifest at /privacy documenting all data collection
- robots.txt blocking all bots on both apps
- Suppress i18next promotional console log

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:11:07 +01:00
Ullrich Schäfer
6c4d92f7fc
Merge pull request #52 from trails-cool/archive-phase1-mvp
Archive phase-1-mvp, sync specs
2026-03-25 02:55:54 +01:00
Ullrich Schäfer
3a519ea05e
Remove old phase-1-mvp location (moved to archive)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:55:43 +01:00
Ullrich Schäfer
e530492753
Archive phase-1-mvp, sync specs to main
All 85 tasks complete. Archive change to openspec/changes/archive/ and
sync 9 capability specs to openspec/specs/ for future reference.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:55:28 +01:00
github-actions[bot]
f7288c88d1
Merge pull request #51 from trails-cool/sentry-ci-environment 2026-03-25 01:54:08 +00:00
Ullrich Schäfer
4291fa6c3f Set all Sentry sample rates to 1.0
No users yet — capture everything. Traces, session replays, and error
replays all at 100%. Easy to dial back when traffic grows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:54:01 +00:00
Ullrich Schäfer
119dc25f5a Disable Sentry in CI, tag environment correctly
Client: VITE_SENTRY_ENVIRONMENT=ci baked in during CI build, disables
Sentry and sets 0 sample rates. Server: checks process.env.CI to
disable and tag as "ci" environment.

Production remains enabled with "production" environment tag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:54:01 +00:00
Ullrich Schäfer
48c74f16f8
Merge pull request #44 from trails-cool/wire-up-i18n
Wire up i18n in both apps
2026-03-25 02:51:41 +01:00
Ullrich Schäfer
4ecb7a9300 Fix E2E: use heading role for register page check
"Register" appears 3 times on the page (heading, button text, link).
Use getByRole("heading") to target the h1 specifically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:47:58 +00:00
Ullrich Schäfer
df845ec610 Fix E2E test for renamed register heading
The i18n change renamed "Create Account" to "Register" — update the
E2E test to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:47:58 +00:00
Ullrich Schäfer
b96b32cb53 Wire up i18n in both apps
Initialize i18n via initI18n() in both root.tsx files and replace all
hardcoded user-facing strings with useTranslation() calls. Adds missing
translation keys for planner (profiles, connection states, save flow)
and journal (auth pages, route management, passkey prompts).

Both English and German translations are complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:47:58 +00:00
github-actions[bot]
69ba510530
Merge pull request #50 from trails-cool/sentry-sourcemaps 2026-03-25 01:46:18 +00:00
Ullrich Schäfer
091fc0a4bd
Add Sentry source maps and release tracking
- @sentry/vite-plugin uploads source maps during Docker build
- Release tagged with git SHA (SENTRY_RELEASE) on both client and server
- Environment set to production/development for filtering
- CD passes SENTRY_AUTH_TOKEN + SENTRY_RELEASE as Docker build args
- docker-compose passes SENTRY_RELEASE to runtime containers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:43:28 +01:00
github-actions[bot]
1a655d328f
Merge pull request #49 from trails-cool/add-sentry-planner 2026-03-25 01:38:14 +00:00
Ullrich Schäfer
ef07915f38
Add Sentry error tracking to both apps
Planner (client + custom server) and Journal (client + entry.server):
- Client: @sentry/react with browser tracing + replay on error
- Server: @sentry/node for unhandled exceptions
- ErrorBoundary captures React errors via Sentry.captureException
- Disabled in dev, 10% trace sample rate in production

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:35:16 +01:00
github-actions[bot]
1819a17036
Merge pull request #48 from trails-cool/fix-yjs-sync-protocol 2026-03-25 01:26:55 +00:00
Ullrich Schäfer
cc041d3235
Fix Yjs WebSocket server to use sync protocol
The production server was sending raw Yjs updates but the client
(y-websocket's WebsocketProvider) expects the y-protocols sync protocol
with message type headers. This caused "Unexpected end of array" errors
on every connection.

Rewrite to match the Vite dev plugin: use y-protocols/sync for document
sync, y-protocols/awareness for presence, and lib0 for encoding.

Verified locally: server starts, WebSocket connects, sync messages
exchange correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:24:13 +01:00
github-actions[bot]
f078589463
Merge pull request #47 from trails-cool/fix-cors-callback 2026-03-25 01:16:39 +00:00
Ullrich Schäfer
a5d682d671 Fix CORS on Planner→Journal callback endpoint
The Save to Journal button makes a cross-origin POST from
planner.trails.cool to trails.cool. The browser's preflight OPTIONS
request was returning HTML (no CORS headers), blocking the save flow.

Add CORS headers to all responses and handle OPTIONS preflight in a
loader. Origin is restricted to PLANNER_URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:16:32 +00:00
github-actions[bot]
77d785ccde
Merge pull request #46 from trails-cool/mark-phase11-complete 2026-03-25 01:14:26 +00:00
Ullrich Schäfer
85b8454de7 Mark phase 1 MVP tasks 11.6-11.8 complete
- 11.6: i18n wired up in both apps (PR #44)
- 11.7: Responsive layout breakpoints added (PR #45)
- 11.8: Deployed to Hetzner, both apps live at trails.cool

All 11 task groups in phase 1 MVP are now complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:14:19 +00:00
github-actions[bot]
c48b811ea4
Merge pull request #45 from trails-cool/responsive-layout 2026-03-25 01:13:49 +00:00
Ullrich Schäfer
69f420e879
Add basic responsive layout for tablet and mobile
Planner: hide title on small screens, wrap header items, hide waypoint
sidebar below md breakpoint (map takes full width).
Journal: stack route stats and action buttons on mobile, responsive
header layout on route detail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:11:22 +01:00
github-actions[bot]
bdb72ae141
Merge pull request #42 from trails-cool/ci-e2e-production-mode 2026-03-25 01:06:59 +00:00
Ullrich Schäfer
537d515df9 Run E2E tests against production build in CI
In CI, Playwright now starts apps with production commands (react-router-
serve, node --experimental-strip-types) instead of dev servers. This
catches runtime issues like missing exports and import resolution errors
before deploy. Locally, dev servers are still used for fast iteration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:04:38 +00:00
github-actions[bot]
ae8fc4560a
Merge pull request #43 from trails-cool/fix-planner-static-assets 2026-03-25 01:04:05 +00:00
Ullrich Schäfer
394daca38e
Serve static assets in planner's custom server
The custom server.ts only had the React Router request handler — static
assets in build/client/ were never served, causing 404s for all JS/CSS
in production. Add a static file handler with path traversal protection
and immutable caching for hashed assets.

Verified locally: HTML 200, assets 200, Cache-Control: immutable on
/assets/*.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 02:01:27 +01:00
github-actions[bot]
6afba179f3
Merge pull request #41 from trails-cool/fix-automerge-base-branch 2026-03-25 00:55:47 +00:00
Ullrich Schäfer
3a4119e00e Restrict automerge to PRs targeting main
Prevents stacked PRs from being auto-merged into feature branches.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:53:33 +00:00
github-actions[bot]
0bab72dcd7
Merge pull request #39 from trails-cool/fix-planner-production-server 2026-03-25 00:53:00 +00:00
Ullrich Schäfer
62b5fb998e
Fix planner production server + use .ts extensions everywhere
- Fix createRequestHandler → createRequestListener (@react-router/node
  removed the old API)
- Move noEmit + allowImportingTsExtensions to tsconfig.base.json so all
  packages and apps inherit them consistently
- Add explicit .ts extensions to all remaining relative imports across
  packages and apps

Verified locally: node --experimental-strip-types server.ts starts and
responds 200.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:41:33 +01:00
github-actions[bot]
655dc46ec8
Merge pull request #38 from trails-cool/fix-ts-extensions 2026-03-25 00:37:02 +00:00
Ullrich Schäfer
4d73de4e0d
Use explicit .ts extensions for Node-compatible imports
Node's --experimental-strip-types requires explicit .ts extensions on
relative imports. Add allowImportingTsExtensions to both app tsconfigs
and update server-side imports in planner and journal for consistency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:34:16 +01:00
Ullrich Schäfer
1abcc5c804
Merge pull request #37 from trails-cool/fix-production-deploy
Fix production deploy: TS support + DB schema
2026-03-25 01:27:01 +01:00
Ullrich Schäfer
afeefbf19d
Fix production deploy: TypeScript support + DB schema push
Planner crashed because Node.js couldn't handle .ts imports — add
--experimental-strip-types to the CMD. Journal crashed because the
database had no schemas — add drizzle-kit push to the deploy script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:26:16 +01:00
Ullrich Schäfer
0fdcbf77d6
Merge pull request #36 from trails-cool/fix-cd-trigger
Fix CD: trigger after automerge + manual dispatch
2026-03-25 01:18:56 +01:00
Ullrich Schäfer
46c880973d
Fix CD: trigger on automerge + manual dispatch
GITHUB_TOKEN merges (from automerge action) don't trigger push
events on other workflows. Added:
- workflow_run trigger after Automerge completes
- workflow_dispatch for manual gh workflow run cd.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:18:12 +01:00
github-actions[bot]
14656b6527
Merge pull request #35 from trails-cool/fix-docker-builds 2026-03-25 00:12:43 +00:00
Ullrich Schäfer
0a09df27f4
Fix Docker builds: missing deps + bump actions
Dockerfiles:
- Add db package.json to deps stage
- Copy full node_modules (including app-level) to runtime
- Copy packages/ dir for workspace imports at runtime

CD workflow:
- docker/login-action v3 → v4
- docker/build-push-action v6 → v7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:10:01 +01:00
Ullrich Schäfer
21eb943393
Merge pull request #34 from trails-cool/deploy-to-hetzner
Enable CD deployment to Hetzner
2026-03-25 01:02:45 +01:00
Ullrich Schäfer
8e2f183288
Enable CD deployment to Hetzner (task 11.8)
CD workflow:
- Uncommented deploy step
- Copy docker-compose.yml + Caddyfile to server via SCP
- Login to ghcr.io with DEPLOY_GHCR_TOKEN (classic PAT, read:packages)
- Download Germany BRouter segments on first deploy (~750MB)
- Pull images, restart services, verify

Infrastructure:
- BRouter segments as bind mount (./segments) not Docker volume
- Added ORIGIN, PLANNER_URL, SESSION_SECRET, NODE_ENV to Journal
- Added NODE_ENV to Planner
- Disabled Garage for now (no media storage yet)

Required secrets: DEPLOY_HOST, DEPLOY_SSH_KEY, DEPLOY_GHCR_TOKEN

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:00:00 +01:00
github-actions[bot]
970f591a60
Merge pull request #33 from trails-cool/fix-playwright-summary 2026-03-24 23:48:55 +00:00
Ullrich Schäfer
6d8e570afc
Fix Playwright job summary: handle nested suite structure
Playwright JSON has file → describe → specs nesting.
Use stats.expected/unexpected for counts, iterate nested suites.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:46:21 +01:00
github-actions[bot]
a09f41e03d
Merge pull request #32 from trails-cool/playwright-job-summary 2026-03-24 23:41:02 +00:00
Ullrich Schäfer
074bcff4e5
Add Playwright job summary to CI
Generates a markdown summary table in GitHub Actions showing
passed/failed tests with timing per test. Uses the JSON reporter
to output results, then a Node script to format as markdown
and append to $GITHUB_STEP_SUMMARY.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 00:38:38 +01:00
Ullrich Schäfer
19ce2d1f1e
Merge pull request #31 from trails-cool/fix-automerge-workflow-run
Fix automerge: trigger after CI completes
2026-03-25 00:35:24 +01:00