Commit graph

338 commits

Author SHA1 Message Date
Ullrich Schäfer
9223eacb91
Remove type:dashboard from annotation config
The type:dashboard field was causing Grafana to filter annotations
by dashboard scope. Our deploy annotations are global (no dashboardUID),
so the target.type:tags is the only filter needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:57:39 +02:00
Ullrich Schäfer
16fd07bd97
Merge pull request #141 from trails-cool/fix/grafana-annotation-target
Fix Grafana deploy annotation query
2026-03-29 21:53:57 +02:00
Ullrich Schäfer
cafedfe6fc
Fix Grafana annotation query: add target with type tags
The annotation config was missing the target block that tells
Grafana to filter by tags. Without it, the annotation query
was silently ignored.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:53:33 +02:00
Ullrich Schäfer
af12837772
Merge pull request #140 from trails-cool/fix/deploy-annotations-curl-dashboards
Fix deploy annotations: wget→curl + dashboard queries
2026-03-29 20:51:06 +02:00
Ullrich Schäfer
fcfea209b8
Add deploy annotation query to all Grafana dashboards
Provisioned dashboards now display deploy markers (cyan vertical
lines) by querying built-in Grafana annotations tagged "deploy".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:49:40 +02:00
Ullrich Schäfer
87be96db67
Switch deploy annotations from BusyBox wget to curl
BusyBox wget in the Grafana Alpine container doesn't support
--post-data/--header. Grafana's image includes curl.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:49:40 +02:00
Ullrich Schäfer
7d0ad7fe31
Merge pull request #139 from trails-cool/fix/deploy-annotation-env-file
Fix deploy annotation reading token from wrong env file
2026-03-29 20:00:07 +02:00
Ullrich Schäfer
c2b9032686
Fix deploy annotation reading token from wrong env file
GRAFANA_SERVICE_TOKEN is in secrets.infra.env, which the infra
workflow merges into .env on the server. The apps workflow was
reading from app.env (which only has app secrets).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:59:17 +02:00
Ullrich Schäfer
8440c2de8f
Merge pull request #138 from trails-cool/chore/grafana-service-token
Add GRAFANA_SERVICE_TOKEN to encrypted infra secrets
2026-03-29 19:51:45 +02:00
Ullrich Schäfer
8ab174d5bb
Add GRAFANA_SERVICE_TOKEN to encrypted infra secrets
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:49:29 +02:00
Ullrich Schäfer
4d8b9a6bb4
Merge pull request #137 from trails-cool/feat/grafana-deploy-annotations
Add Grafana deploy annotations to CD workflows
2026-03-29 19:47:53 +02:00
Ullrich Schäfer
6c482238e8
Add Grafana deploy annotations to all CD workflows
Posts an annotation to Grafana after each successful deploy, tagged
with "deploy" and the service name. Annotations appear as vertical
markers on dashboards, making it easy to correlate deploys with
metric changes.

Uses GRAFANA_SERVICE_TOKEN from SOPS secrets — must be added via
sops infrastructure/secrets.infra.env. Gracefully skips if the
token is not configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 19:44:15 +02:00
Ullrich Schäfer
f6b89a2b7e
Merge pull request #135 from trails-cool/copilot/change-map-zoom-for-route
Fit map to route bounds on open
2026-03-29 19:38:05 +02:00
Ullrich Schäfer
156bb7cb36
Merge branch 'main' into copilot/change-map-zoom-for-route 2026-03-29 19:35:27 +02:00
Ullrich Schäfer
99a4d7af97
Fix fitBounds running before elevation chart resizes map
invalidateSize() + requestAnimationFrame ensures Leaflet knows
the map's actual dimensions after the elevation chart renders.
Also removes unnecessary filter on already-typed coordinates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:20:06 +02:00
Ullrich Schäfer
fe3b1f5a79
Merge pull request #136 from trails-cool/copilot/add-agents-file-and-context
Add GitHub Copilot context files
2026-03-29 15:15:52 +02:00
copilot-swe-agent[bot]
d20505720c
Restore 'primary development tool' qualifier for Claude Code in README
Agent-Logs-Url: https://github.com/trails-cool/trails/sessions/5338ac00-6f6c-4e04-8d15-3c443d87eab4

Co-authored-by: stigi <13815+stigi@users.noreply.github.com>
2026-03-29 13:12:04 +00:00
copilot-swe-agent[bot]
2079b7e6de
Simplify copilot-instructions.md to point to CLAUDE.md instead of duplicating content
Agent-Logs-Url: https://github.com/trails-cool/trails/sessions/bc100497-d093-4f44-bf81-5fbd357af6b3

Co-authored-by: stigi <13815+stigi@users.noreply.github.com>
2026-03-29 12:41:30 +00:00
copilot-swe-agent[bot]
1b9683752f
Fit map to route bounds when opening a route in the planner
Agent-Logs-Url: https://github.com/trails-cool/trails/sessions/558ccff8-ed5d-432a-a5d3-aca49c0e531e

Co-authored-by: stigi <13815+stigi@users.noreply.github.com>
2026-03-29 12:31:40 +00:00
copilot-swe-agent[bot]
0ac1d4ca39
Add .github/copilot-instructions.md and update README for GitHub Copilot
Agent-Logs-Url: https://github.com/trails-cool/trails/sessions/d830c6a7-0796-4aeb-8169-d7a7718a6170

Co-authored-by: stigi <13815+stigi@users.noreply.github.com>
2026-03-29 12:30:59 +00:00
copilot-swe-agent[bot]
39c58185b8
Initial plan 2026-03-29 12:28:15 +00:00
copilot-swe-agent[bot]
9de1a05903
Initial plan 2026-03-29 12:26:51 +00:00
Ullrich Schäfer
28fa0f6875
Merge pull request #134 from trails-cool/feat/route-error-toasts
Add route error toasts with waypoint rollback
2026-03-29 14:11:45 +02:00
Ullrich Schäfer
b9a77be020
Add route error toasts with waypoint rollback
- Show error toasts when route calculation fails, with distinct messages:
  - "No route found" for BRouter 4xx (unroutable waypoints, missing tiles)
  - "Route calculation failed" for server errors / network failures
  - "Too many requests" for rate limiting
- Rollback all waypoints to last known good state on route failure
- Guard against restore→recompute loop via restoringRef flag
- Extract reusable useToasts hook from awareness toast logic
- Add BRouterError class to distinguish client vs server errors
- API returns 422 for unroutable requests instead of blanket 502

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:09:20 +02:00
Ullrich Schäfer
6a18980d7e
Merge pull request #133 from trails-cool/fix/waypoint-drag-ghost-marker
Fix waypoint drag creating unwanted split points
2026-03-29 12:36:38 +02:00
Ullrich Schäfer
400189d9c1
Fix waypoint drag creating unwanted split points
The ghost marker (route split indicator) was interfering with waypoint
dragging because it sat above waypoints (zIndexOffset 1000) and stayed
active during drag operations.

Adopt brouter-web's suspension pattern:
- Suspend route interaction on waypoint mouseover (not just dragstart),
  unsuspend on mouseout — ghost marker hides before any click/drag
- Lower ghost marker zIndexOffset to -100 so waypoints always receive
  clicks first
- Keep drag guards as a safety net

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:34:09 +02:00
Ullrich Schäfer
26dd1a4d83
Merge pull request #132 from trails-cool/chore/upgrade-i18next-v26
Upgrade i18next v26 + react-i18next v17 with SSR-safe init
2026-03-29 11:55:52 +02:00
Ullrich Schäfer
4403e22006
Remove useEffect flicker from ClientDate
Now that both server and client use the same locale from context,
the post-hydration useEffect that re-formatted with the browser's
OS locale was causing a visible flicker. Just render with the
context locale directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:48:01 +02:00
Ullrich Schäfer
38ada3bd4f
Pass full locale from Accept-Language to ClientDate
Add detectLocale() that extracts the full locale tag (e.g. "de-DE")
from the request, not just the language. The journal root loader passes
it via LocaleContext so ClientDate renders with the correct locale on
both server and client — no more hardcoded "en-US" fallback.

Also fixes settings page hydration mismatch by using ClientDate for
passkey creation dates instead of inline toLocaleDateString().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:46:21 +02:00
Ullrich Schäfer
79f000fcc5
Upgrade i18next v26 + react-i18next v17 with SSR-safe init
Split initI18n() into separate server/client initialization paths
inspired by remix-i18next's architecture:

- initI18nServer(lng): no LanguageDetector, per-request language from
  Accept-Language header
- initI18nClient(): LanguageDetector reads <html lang> first to match
  server, then localStorage and navigator
- detectLanguage(request): parses Accept-Language for best match

Fixes rehydration errors caused by v26 removing initImmediate option
(replaced with initAsync) and LanguageDetector running on the server
where browser APIs don't exist.

Also makes <html lang> dynamic instead of hardcoded "en".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:38:36 +02:00
Ullrich Schäfer
4be716687a
Merge pull request #126 from trails-cool/dependabot/npm_and_yarn/production-54355eb8c8
Bump the production group with 10 updates
2026-03-29 10:58:53 +02:00
Ullrich Schäfer
f597ff2f85
Merge branch 'main' into dependabot/npm_and_yarn/production-54355eb8c8 2026-03-29 10:53:17 +02:00
Ullrich Schäfer
8bfd923368
Merge pull request #130 from trails-cool/fix/home-passkey-prompt
Only show add-passkey prompt for users without passkeys
2026-03-29 10:53:09 +02:00
Ullrich Schäfer
4859f5d5e0
Only show add-passkey prompt when user has no passkeys
The prompt now only appears when coming from signup/login with
?add-passkey=1 AND the user has zero passkeys. Passkey count display
removed from home — that info lives in /settings now.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:50:30 +02:00
Ullrich Schäfer
c825005249
Merge pull request #128 from trails-cool/chore/static-assets
Add favicons and static assets to silence 404s
2026-03-29 10:43:47 +02:00
Ullrich Schäfer
57a41501da
Merge branch 'main' into dependabot/npm_and_yarn/production-54355eb8c8 2026-03-29 10:41:28 +02:00
Ullrich Schäfer
46a7c1be34
Merge branch 'main' into chore/static-assets 2026-03-29 10:41:22 +02:00
Ullrich Schäfer
5735a0dc8f
Merge pull request #129 from trails-cool/chore/skip-gitleaks-dependabot
Skip Gitleaks scan for Dependabot PRs
2026-03-29 10:41:07 +02:00
Ullrich Schäfer
60d7220634
Merge branch 'main' into chore/skip-gitleaks-dependabot 2026-03-29 10:40:56 +02:00
Ullrich Schäfer
d797564201
Skip Gitleaks scan for Dependabot PRs
Gitleaks requires a license key for org repos. Skip the step (not the
job) for dependabot[bot] so the Security Scan job still passes as a
required status check. pnpm audit still runs for all PRs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:40:27 +02:00
Ullrich Schäfer
33c0315941
Revert "Skip Gitleaks scan for Dependabot PRs"
This reverts commit b15c5af72c.
2026-03-29 10:40:08 +02:00
Ullrich Schäfer
b15c5af72c
Skip Gitleaks scan for Dependabot PRs
Gitleaks requires a license key for org repos. Skip the step (not the
job) for dependabot[bot] so the Security Scan job still passes as a
required status check. pnpm audit still runs for all PRs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:38:41 +02:00
Ullrich Schäfer
d426912945
Merge branch 'main' into chore/static-assets 2026-03-29 10:36:22 +02:00
Ullrich Schäfer
518ee9ab69
Add favicons, apple-touch-icons, and Chrome DevTools JSON
Eliminates 404 noise from:
- /favicon.ico (browsers)
- /apple-touch-icon.png, /apple-touch-icon-precomposed.png (iOS)
- /.well-known/appspecific/com.chrome.devtools.json (Chrome)

Favicon uses the Waypoint Dot logo mark (sage green, SVG + ICO).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:35:03 +02:00
Ullrich Schäfer
107d926a0e
Merge pull request #124 from trails-cool/passkey-browser-compat
Passkey browser compat, magic link registration, account settings
2026-03-29 10:34:23 +02:00
Ullrich Schäfer
8bc426daf4
Merge branch 'main' into passkey-browser-compat 2026-03-29 10:31:53 +02:00
Ullrich Schäfer
a766bffad5
Add purpose column to magic_tokens, fix email change race condition
- Add `purpose` column (default: 'login') to distinguish login tokens
  from email-change tokens
- verifyMagicToken only matches purpose='login'
- verifyEmailChange only matches purpose='email-change'
- Re-check email availability at verification time, not just initiation
  — prevents race where someone registers with the new email between
  request and verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:28:53 +02:00
dependabot[bot]
aa4d491950
Bump the production group with 10 updates
Bumps the production group with 10 updates:

| Package | From | To |
| --- | --- | --- |
| [@react-router/dev](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dev) | `7.13.1` | `7.13.2` |
| [@react-router/node](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-node) | `7.13.1` | `7.13.2` |
| [@react-router/serve](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-serve) | `7.13.1` | `7.13.2` |
| [drizzle-orm](https://github.com/drizzle-team/drizzle-orm) | `0.45.1` | `0.45.2` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `7.13.1` | `7.13.2` |
| [turbo](https://github.com/vercel/turborepo) | `2.8.20` | `2.8.21` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.57.1` | `8.57.2` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.0` | `4.1.2` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.45.0` | `10.46.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.45.0` | `10.46.0` |


Updates `@react-router/dev` from 7.13.1 to 7.13.2
- [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.13.2/packages/react-router-dev)

Updates `@react-router/node` from 7.13.1 to 7.13.2
- [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.13.2/packages/react-router-node)

Updates `@react-router/serve` from 7.13.1 to 7.13.2
- [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.13.2/packages/react-router-serve)

Updates `drizzle-orm` from 0.45.1 to 0.45.2
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/0.45.1...0.45.2)

Updates `react-router` from 7.13.1 to 7.13.2
- [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.13.2/packages/react-router)

Updates `turbo` from 2.8.20 to 2.8.21
- [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.8.20...v2.8.21)

Updates `typescript-eslint` from 8.57.1 to 8.57.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.57.2/packages/typescript-eslint)

Updates `vitest` from 4.1.0 to 4.1.2
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.2/packages/vitest)

Updates `@sentry/node` from 10.45.0 to 10.46.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.45.0...10.46.0)

Updates `@sentry/react` from 10.45.0 to 10.46.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.45.0...10.46.0)

---
updated-dependencies:
- dependency-name: "@react-router/dev"
  dependency-version: 7.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@react-router/node"
  dependency-version: 7.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@react-router/serve"
  dependency-version: 7.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: drizzle-orm
  dependency-version: 0.45.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-router
  dependency-version: 7.13.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: turbo
  dependency-version: 2.8.21
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: typescript-eslint
  dependency-version: 8.57.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: vitest
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@sentry/node"
  dependency-version: 10.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react"
  dependency-version: 10.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-29 08:26:40 +00:00
Ullrich Schäfer
715b272395
Fix i18n: use common:key namespace syntax for cross-namespace keys
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:19:11 +02:00
Ullrich Schäfer
881374008f
Merge pull request #125 from trails-cool/openspec-account-settings
Add account-settings OpenSpec change
2026-03-29 10:17:25 +02:00