Commit graph

266 commits

Author SHA1 Message Date
Ullrich Schäfer
0f57e9b9ac
fix(planner): clear the route when waypoints drop below two
Deleting waypoints down to <2 left the last computed route rendered —
nothing cleared the stale geometry (recompute only runs for >=2). Add a
waypoints observer that drops the computed geometry once fewer than two
waypoints remain, via a new clearComputedRoute (keeps the routing
profile, unlike clearRouteData). Covers all delete paths (sidebar, map,
undo).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 23:46:00 +02:00
Ullrich Schäfer
267c2fb8b7
fix(planner): nearby-POI lookup sends the real session (was 401)
fetchNearbyPois defaulted sessionId to the placeholder "nearby", which
/api/pois's requireSession rejects (401 Unauthorized) — so the nearby-POI
lookup for a selected waypoint always failed on real deployments. Thread
the live planner sessionId through useNearbyPois → fetchNearbyPois →
queryPois (same session the main POI markers already use), and make
sessionId a required arg so the placeholder can't silently return.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 23:37:31 +02:00
Ullrich Schäfer
413c46623e
perf(planner): group colored route into color runs, not 1 polyline/coord
ColoredRoute rendered one interactive-registered <Polyline> per
coordinate pair — ~14.6k on a 485 km route — flooding Leaflet's SVG
layer and event-target map. Run-length group consecutive same-color
segments into a single polyline each (new pure buildColorRuns helper,
unit-tested). Discrete modes (surface/highway/…) collapse to a handful;
the elevation gradient is quantized into 24 buckets so its runs merge
too. Rendering is otherwise identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 08:32:36 +02:00
Ullrich Schäfer
c6ae08676b
fix(planner): waypoint drag no longer snaps back on release
Extract the waypoint marker into a React.memo'd component. The marker's
position/icon were new references every render, so any unrelated
PlannerMap re-render during a drag (e.g. the route-hover chart-sync
state update) re-applied the stale saved position mid-drag — orphaning
the drag so it never committed and the pin jumped back on release.
Memoizing means unrelated re-renders no longer touch the marker, so the
drag commits and the moved position persists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 08:12:06 +02:00
Ullrich Schäfer
6871b154db
fix(planner): clicking a waypoint no longer adds a duplicate
Waypoint markers had no click listener, so Leaflet routed the click to
the map — MapClickHandler then added a new waypoint on top of the one
you clicked (and made markers feel unresponsive). Add a click handler
that consumes the event, so Leaflet treats the marker as the target and
suppresses the map click.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:59:48 +02:00
Ullrich Schäfer
7b15ba609f
feat(planner): restyle map markers + route on tokens
Bring the map surface on-brand (visual-redesign group 4):

- Waypoint markers: sage accent numbered circles (was blue #2563eb);
  overnight stops keep the warm stop tone; note indicator uses the
  eg-mid gold token.
- Plain route line + ghost (insert) marker: sage accent (was blue).
- Map highlight dot (synced with the chart hover): sage accent (was
  red), so map and chart hovers match.
- Day labels: bg-raised surface + text-hi.
- No-go areas: danger token (#a03c3c) instead of bright red.
- GPX drag-over overlay: accent tokens.

Per-mode route coloring (surface/grade/…) is unchanged (data-viz);
coordinating the elevation-mode gradient with the route line is task 1.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:20:17 +02:00
Ullrich Schäfer
92821e6e8b
Merge pull request #609 from trails-cool/feat/planner-elevation-collapsible
feat(planner): collapsible elevation chart with summary bar
2026-07-16 07:11:16 +02:00
Ullrich Schäfer
a5162fcc90
Merge branch 'main' into feat/planner-elevation-canvas 2026-07-16 01:40:27 +02:00
Ullrich Schäfer
8cbaceb356
feat(planner): collapsible elevation chart with summary bar
Docked-but-collapsible placement (the chosen direction):

- A collapse toggle (chevron) in the chart header; state persists to
  localStorage.
- Collapsed = a thin summary bar: a mini sage sparkline + distance and
  ascent/descent + an expand toggle. Reclaims map space on demand.
- Summary figures come from the same authoritative routeStats the
  sidebar uses (distance, elevationGain, elevationLoss), so the numbers
  match the sidebar exactly — not recomputed from the raw elevation
  points (which over-counted ascent ~2x from noise).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:39:01 +02:00
Ullrich Schäfer
97ddf36621
fix(planner): elevation chart drag survives leaving the canvas; move reset-zoom
- Drag-to-zoom on the chart now tracks via window mousemove/mouseup, so
  it keeps going when the pointer leaves the chart and still completes if
  released outside it (previously mouseleave aborted the drag and an
  outside release was lost). Listeners are detached on mouseup/unmount.
- Move the "reset zoom" button from top-right (which overlapped the
  color-mode dropdown) to the bottom-right of the chart, and restyle it
  on tokens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:27:45 +02:00
stigi
0b157ce96e chore: update visual snapshots [skip ci] 2026-07-15 23:22:05 +00:00
Ullrich Schäfer
c38e054088
feat(planner): restyle elevation chart canvas on tokens
Bring the chart's chrome onto the design system (spec task 5.1):

- Plain mode: sage accent line + soft accent→transparent gradient fill
  (was off-palette blue).
- Hover: calm near-black crosshair + accent dot with a light ring, mono
  label (was red).
- Axis + day-divider labels: token colors, Geist Mono; dividers use the
  border-md token.
- Drag-select: accent tint (was blue).

Per-mode data-viz palettes (grade, surface, …) are unchanged. Darwin
visual-regression baselines regenerated; linux baselines to follow via
the update-snapshots workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:20:36 +02:00
Ullrich Schäfer
6d905c152f
Merge pull request #606 from trails-cool/feat/planner-computing-overlay
feat(planner): move "computing route" indicator from topbar to a map overlay
2026-07-16 01:16:09 +02:00
Ullrich Schäfer
24913b9f3e
Merge branch 'main' into feat/planner-colormode-select 2026-07-16 01:03:09 +02:00
Ullrich Schäfer
46018c9f89
feat(planner): move "computing route" from topbar to a map overlay
The topbar's "Route wird berechnet…" text appeared/disappeared with
routing, shifting the topbar layout. Move it onto the map as a floating
status pill (spinner + label, top-center, pointer-events-none) that
appears temporarily without affecting the topbar. Restyle the ambient
top-edge progress bar to accent tokens. Drop the now-unused `computing`
prop from Topbar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 01:01:08 +02:00
Ullrich Schäfer
079ce5aba2
Merge branch 'main' into feat/planner-colormode-select 2026-07-16 00:44:42 +02:00
Ullrich Schäfer
c504d6e34b
Merge branch 'main' into feat/topbar-button-restyle 2026-07-16 00:44:25 +02:00
Ullrich Schäfer
3603624b70
fix(planner): distinct aria-label for export dropdown toggle
The restyled Export split-button's dropdown toggle got aria-label
"Export GPX", colliding with the main button's text and breaking the
E2E selector that clicked the old "▾" glyph. Give it a dedicated
exportOptions label (en + de) and target it in the E2E test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:43:30 +02:00
Ullrich Schäfer
1d3ba956cb
feat(planner): restyle Export + SaveToJournal buttons on tokens
Bring the two slotted topbar actions onto the design system so the bar
reads as one cohesive surface:

- SaveToJournalButton: primary Button primitive; "saved" uses the
  accent, error uses a new --color-danger token, and the return link
  gets secondary token styling.
- ExportButton: token split-button (secondary look, chevron icon,
  single divider) and a token dropdown menu (raised surface, soft
  shadow, muted descriptions).
- New --color-danger token (#a03c3c, the no-go hue at full strength)
  for error text.

Behavior and i18n unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:42:37 +02:00
Ullrich Schäfer
b09d810301
feat(planner): restyle sidebar on tokens (waypoints, notes, days)
Migrate the whole sidebar surface onto the design system:

- SidebarTabs: token tab bar, sage active indicator.
- WaypointSidebar: token surfaces/text; sage number badges; overnight
  marker uses the Badge (stop tone) primitive; route summary + stats
  footer in Geist Mono; destructive delete signalled via bg-nogo.
- NotesPanel + DayBreakdown headers/rows on tokens.
- i18n the previously-hardcoded empty-state string (en + de).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:39:12 +02:00
Ullrich Schäfer
28f92d0d8f
feat(planner): restyle color-mode selector + chart header on tokens
The elevation chart's 10-mode color selector now uses the Select
primitive (token-styled, consistent with ProfileSelector). Chart-header
chrome (top border, title link, legend text) moved onto tokens too.

Kept as a dropdown rather than a segmented control — 10 modes don't fit
a segmented toggle. Canvas/legend data-viz colors are unchanged (task
1.5).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:32:05 +02:00
Ullrich Schäfer
a56445daf3
feat(ui): Select primitive; restyle ProfileSelector on tokens
- New Select primitive in @trails-cool/ui: token-styled native <select>
  (appearance-none + overlaid chevron for a consistent closed control),
  sm/md sizes, sibling of Input. Unit-tested + added to /dev/ui.
- ProfileSelector uses Select (size sm) with token label; the profile
  label now hides on small screens. Completes the topbar's migration
  onto the design system.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:12:23 +02:00
Ullrich Schäfer
723cd8069b
fix(planner): make the /dev/ui gallery scrollable
The app body is h-screen overflow-hidden (for the full-screen map
editor), which clipped the taller gallery so it couldn't scroll. Give
the gallery route its own full-height scroll container.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:57:44 +02:00
Ullrich Schäfer
4f0d4a34b3
feat(planner): redesign topbar with tokens + primitives, presentational
Extract a presentational Topbar driven by plain props, so SessionView
is the container (reads Yjs/awareness) and the topbar can render in the
/dev/ui gallery without a live session.

- New useParticipants(yjs) hook: awareness -> sorted Participant[] +
  renameLocal. Replaces ParticipantList's inline logic.
- New presentational ParticipantAvatars (Avatar + Host Badge + inline
  rename) and Topbar (token-styled shell; undo/redo via IconButton;
  connection status with a live dot). ProfileSelector/Export/Save are
  passed in as slots (their own restyle is separate).
- SessionView composes <Topbar> from real data; delete ParticipantList.
- /dev/ui gains a "Topbar - configurations" section (solo, multiplayer
  + computing, guest/connecting). Surfaced a narrow-width overflow, now
  fixed by making the participant strip the shrink/clip element.

Connection status text ("Connected"/"Verbunden") and behavior are
unchanged, so existing planner E2E selectors still match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:51:27 +02:00
Ullrich Schäfer
1bd5f18a33
feat(ui): topbar primitives — IconButton, SegmentedControl, Avatar
Adds the shared primitives the planner topbar redesign needs, on the
design-system tokens:

- IconButton — icon-only button (undo/redo), ghost/secondary variants,
  requires an accessible label.
- SegmentedControl — generic single-select toggle (color mode
  Plain/Elevation/Surface), radiogroup semantics.
- Avatar — colored initial circle for participants, per-user color with
  an accent fallback.

Co-located jsdom unit tests for each (roles, aria-checked, onChange,
disabled, color fallback). Extends the dev-only /dev/ui gallery with
sections for all three.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:43:14 +02:00
Ullrich Schäfer
6344a513ce
feat(ui): shared primitives (Button, Badge, Card, Input) on the tokens
Second step of the visual-redesign (tokens -> primitives -> surfaces):
a small set of shared, token-driven primitives in @trails-cool/ui so
both apps compose from one styled vocabulary instead of hand-rolling
bg-white/text-gray-* per screen.

- @trails-cool/ui now ships React components (Button variants+sizes,
  Badge tones, Card raised/subtle, Input) plus a tiny cn() helper.
  React is a peer dep; package builds with no bundling step.
- Co-located jsdom unit tests (@testing-library/react) assert roles,
  token classes, variant switching, and behavior — run in the existing
  Unit Tests gate, cross-platform, no snapshot baseline needed.
- Tailwind @source directive in both apps' styles.css so the package's
  token utility classes get generated.
- Dev-only /dev/ui gallery route in the planner renders every primitive
  in all states — a zero-dependency stand-in for Storybook. Excluded
  from production builds (NODE_ENV guard in routes.ts).

No app surfaces are refactored yet; adopting the primitives in the
topbar/sidebar/etc. is the surface task groups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:32:28 +02:00
Ullrich Schäfer
df6df023e0
fix(docker): copy packages/ui/package.json in both Dockerfiles
New @trails-cool/ui workspace package needs its package.json in the
deps stage so pnpm install --frozen-lockfile can resolve the
workspace:* dependency. Fixes the Dockerfile Package Check and the
journal image build.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:11:50 +02:00
Ullrich Schäfer
34c3a31e73
feat(ui): design-system foundation — shared token layer + fonts
Establish the visual-redesign foundation (task group 1): a single
shared source of design tokens both apps consume, so Planner and
Journal read from one palette/typography layer instead of drifting
per-app.

- New @trails-cool/ui package exporting theme.css: Tailwind v4 @theme
  tokens (warm off-white surfaces, one sage accent, earthy overnight
  tones, elevation-gradient colors, shadows) extracted from the
  visual-redesign mockup.
- Self-hosted Outfit (body) + Geist Mono (stats) via @fontsource-variable
  — privacy-first, no Google Fonts CDN.
- Both apps import the theme and set the base canvas to the warm
  off-white token + Outfit as the default font.

Foundation only: tokens are now available as Tailwind utilities
(bg-bg-raised, text-accent, font-mono, …) and raw CSS vars. Wiring
them into specific surfaces (topbar, sidebar, markers, elevation
chart) is later task groups.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:00:28 +02:00
Ullrich Schäfer
eb1ab7d9e4
fix(planner): note tooltip sizes to content (width max-content, cap 280)
Refines #594: a fixed width made short notes an oversized box and wrapped
long notes early. Use `width: max-content` capped at `max-width: 280` so
the tooltip hugs short notes on one line and grows to 280px before wrapping
long ones (instead of collapsing to the longest word, the pre-#593 bug).
Keeps the centered text.

Verified in local dev with both a short ("Zug zurück?") and a long note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:44:05 +02:00
Ullrich Schäfer
64d770ebea
fix(planner): give the note tooltip a fixed width + centered text
Follow-up to #593. With a long note the tooltip still squeezed to ~1 word
wide: an inline-block with only max-width, inside Leaflet's auto-width
tooltip, shrinks to its longest word rather than filling max-width.

Give it an explicit `width: 200` (a consistent, comfortably wide box that
wraps long notes cleanly) and `text-align: center`. Verified live in the
browser against a long repeated note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 21:33:43 +02:00
Ullrich Schäfer
8cf483a4ee
fix(planner): waypoint-note tooltip no longer collapses to one char per line
The note tooltip's inner span was `display: block` with
`word-break: break-word` and no width, so the Leaflet tooltip sized itself
to the block's *min-content* — which under break-word is ~1 character —
and every character wrapped onto its own line (a tall vertical strip).

Switch to `display: inline-block` (sizes to content up to maxWidth, so it
stays one line when short and wraps at 220px when long) and the standard
`overflow-wrap: break-word`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:48:33 +02:00
Ullrich Schäfer
c33a413395
feat(planner): store computed route compact-encoded (groups 2–4)
Wire the map-core codec into route-data.ts so the Yjs session doc stores
the computed route compactly, without changing the routing-host
compute-once-and-share model.

- Codec: add encodeElevations/decodeElevations (delta+varint) so geometry
  = encoded [lon,lat] polyline + elevation channel; precision bumped to
  1e6 (~0.11 m) to preserve the router's 6-decimal output.
- writeComputedRoute: geometry stored once (encoded polyline + elevations,
  no redundant geojson), road metadata run-length encoded.
- Dual-format reads: getCoordinates / readRoadMetadata / new readGeojson
  transparently handle the new encoding AND legacy JSON docs (+ oldest
  geojson-only) — no migration, no flag day; legacy docs re-encode on the
  next recompute. use-elevation-data reads readGeojson (assembled for new
  docs).
- Spec correction: a lossy compact codec can't be byte-identical to legacy
  (generateGpx emits raw precision), so "GPX byte-compatible" is corrected
  to "coordinates preserved within the router's ~0.1 m precision".

Tests: legacy-format read, size assertion (>4x smaller / round-trips),
elevation round-trip. map-core + planner typecheck/lint clean; full
pnpm test 11/11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 17:07:28 +02:00
Ullrich Schäfer
e34a06ff5a
fix(planner): raise WS frame cap above doc cap (fixes sync reconnect loop)
The Yjs sync WebSocket had MAX_MESSAGE_BYTES = 256 KB (per frame) but
MAX_DOC_BYTES = 5 MB (per session doc). A full-state sync frame carries
the entire doc, so any session doc between 256 KB and 5 MB was allowed to
exist yet could never sync: the client's sync frame tripped the 256 KB
per-frame cap, the server closed it (1008), the client reconnected, resent
the same oversized frame, and looped forever — the UI froze, the connection
flapped Verbunden/Verbinde, and the network tab filled with 101 reconnects.

Real routes hit this fast because the BRouter geometry is stored in the doc:
a 4-waypoint, 77 km cycling route was already 305 KB.

Fix: the per-frame cap must be >= the doc cap (a full-doc sync must fit in
one frame). Set MAX_MESSAGE_BYTES = MAX_DOC_BYTES + 256 KB overhead; the
5 MB doc cap stays the real size/abuse guard. Updated the test that had
codified the inverted ordering.

Verified: planner typecheck + lint clean, yjs-server 9/9, planner suite
183/183.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 08:58:24 +02:00
Ullrich Schäfer
d9eee37e39
build(deps): bump the production group across 1 directory with 35 updates
Bumps 35 dependencies in the production group; lockfile regenerated and deduped against latest main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 09:29:56 +02:00
Ullrich Schäfer
b45e69885d
poi-index: map-core selectors, planner.pois schema, /api/pois route + client, metrics
Replace the planner's Overpass proxy with a self-hosted POI index:
- map-core POI categories become structured tag selectors (single source of
  truth) + osmium filter / classification helpers
- planner.pois PostGIS table (centroid points, GiST + category indexes)
- /api/pois serving route (session + same-origin + rate limit, 100 cap)
- lib/pois.ts client (renamed from overpass.ts; GET, quantized bbox)
- metrics: poi_api_requests_total + DB-collected index rows/age gauges;
  drop overpass_* metrics
- remove /api/overpass proxy + dead OVERPASS_URLS on the planner service
  (Journal surface backfill still uses it via code default)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 22:38:03 +02:00
dependabot[bot]
ae585290be
build(deps): bump the production group with 18 updates
Bumps the production group with 18 updates:

| Package | From | To |
| --- | --- | --- |
| [@playwright/test](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` |
| [playwright](https://github.com/microsoft/playwright) | `1.60.0` | `1.61.0` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.61.0` | `8.61.1` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.8` | `4.1.9` |
| [@logtape/logtape](https://github.com/dahlia/logtape/tree/HEAD/packages/logtape) | `2.1.4` | `2.1.5` |
| [isbot](https://github.com/omrilotan/isbot) | `5.1.42` | `5.1.43` |
| [@sentry/cli](https://github.com/getsentry/sentry-cli) | `3.5.0` | `3.5.1` |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo) | `56.0.11` | `56.0.12` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location) | `56.0.17` | `56.0.18` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications) | `56.0.17` | `56.0.18` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `56.2.10` | `56.2.11` |
| [@vitest/browser](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser) | `4.1.8` | `4.1.9` |
| [@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright) | `4.1.8` | `4.1.9` |
| [@garmin/fitsdk](https://github.com/garmin/fit-javascript-sdk) | `21.205.0` | `21.208.0` |
| [pg-boss](https://github.com/timgit/pg-boss) | `12.19.1` | `12.20.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.58.0` | `10.59.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.59.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.19.21` | `22.20.0` |


Updates `@playwright/test` from 1.60.0 to 1.61.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.60.0...v1.61.0)

Updates `playwright` from 1.60.0 to 1.61.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.60.0...v1.61.0)

Updates `typescript-eslint` from 8.61.0 to 8.61.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.61.1/packages/typescript-eslint)

Updates `vitest` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/vitest)

Updates `@logtape/logtape` from 2.1.4 to 2.1.5
- [Changelog](https://github.com/dahlia/logtape/blob/main/CHANGES.md)
- [Commits](https://github.com/dahlia/logtape/commits/2.1.5/packages/logtape)

Updates `isbot` from 5.1.42 to 5.1.43
- [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omrilotan/isbot/compare/v5.1.42...v5.1.43)

Updates `@sentry/cli` from 3.5.0 to 3.5.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.5.0...3.5.1)

Updates `expo` from 56.0.11 to 56.0.12
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo)

Updates `expo-location` from 56.0.17 to 56.0.18
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location)

Updates `expo-notifications` from 56.0.17 to 56.0.18
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications)

Updates `expo-router` from 56.2.10 to 56.2.11
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router)

Updates `@vitest/browser` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/browser)

Updates `@vitest/browser-playwright` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/browser-playwright)

Updates `@garmin/fitsdk` from 21.205.0 to 21.208.0
- [Release notes](https://github.com/garmin/fit-javascript-sdk/releases)
- [Commits](https://github.com/garmin/fit-javascript-sdk/compare/21.205.0...21.208.0)

Updates `pg-boss` from 12.19.1 to 12.20.0
- [Release notes](https://github.com/timgit/pg-boss/releases)
- [Commits](https://github.com/timgit/pg-boss/compare/12.19.1...12.20.0)

Updates `@sentry/node` from 10.58.0 to 10.59.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.58.0...10.59.0)

Updates `@sentry/react` from 10.53.1 to 10.59.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.53.1...10.59.0)

Updates `@types/node` from 22.19.21 to 22.20.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.61.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: playwright
  dependency-version: 1.61.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: typescript-eslint
  dependency-version: 8.61.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: vitest
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@logtape/logtape"
  dependency-version: 2.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: isbot
  dependency-version: 5.1.43
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@sentry/cli"
  dependency-version: 3.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo
  dependency-version: 56.0.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-location
  dependency-version: 56.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-notifications
  dependency-version: 56.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-router
  dependency-version: 56.2.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@vitest/browser"
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@vitest/browser-playwright"
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@garmin/fitsdk"
  dependency-version: 21.208.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: pg-boss
  dependency-version: 12.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/node"
  dependency-version: 10.59.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react"
  dependency-version: 10.59.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@types/node"
  dependency-version: 22.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-21 08:32:18 +00:00
Ullrich Schäfer
3a1c34317d
route-surface-breakdown (Phase 1): Planner-path surface/waytype bars
Synchronous path + rendering for the surface/waytype breakdown:
- map-core `computeSurfaceBreakdown(coords, surfaces, highways)` → distance-
  weighted metres per surface + waytype category (unit-tested);
- `SurfaceBreakdownSchema` in @trails-cool/api;
- nullable `surfaceBreakdown` jsonb on routes + activities;
- Planner `SaveToJournalButton` computes it from the BRouter waytags already in
  routeData and sends it; `api.save-to-journal` forwards it; the journal route
  callback validates + persists (journal is the authoritative validator);
- `SurfaceBreakdown` component (stacked bars per dimension, map-core palettes,
  legend category · % · km largest-first, unknown → "other", hidden when empty)
  on route + activity detail; journal gains a @trails-cool/map-core dep;
- i18n journal.surface.* (en + de).

Phase 2 (async Overpass backfill + SSE for imports/uploads, and the e2e that
seeds a breakdown) follows in a separate PR.

Tests: computeSurfaceBreakdown unit (map-core 36); SurfaceBreakdown component
(jsdom, journal 326). typecheck + lint green; verified in the browser.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 18:46:49 +02:00
dependabot[bot]
19160bbe82
build(deps): Bump the production group across 1 directory with 21 updates
Bumps the production group with 21 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [turbo](https://github.com/vercel/turborepo) | `2.9.17` | `2.9.18` |
| [@logtape/logtape](https://github.com/dahlia/logtape/tree/HEAD/packages/logtape) | `2.1.1` | `2.1.3` |
| [isbot](https://github.com/omrilotan/isbot) | `5.1.41` | `5.1.42` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `8.0.10` | `8.0.11` |
| [@types/nodemailer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nodemailer) | `8.0.0` | `8.0.1` |
| [@expo/metro-runtime](https://github.com/expo/expo) | `56.0.14` | `56.0.15` |
| [@maplibre/maplibre-react-native](https://github.com/maplibre/maplibre-react-native) | `11.3.3` | `11.3.4` |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo) | `56.0.9` | `56.0.11` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants) | `56.0.17` | `56.0.18` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client) | `56.0.19` | `56.0.20` |
| [expo-file-system](https://github.com/expo/expo/tree/HEAD/packages/expo-file-system) | `56.0.7` | `56.0.8` |
| [expo-linking](https://github.com/expo/expo/tree/HEAD/packages/expo-linking) | `56.0.13` | `56.0.14` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location) | `56.0.16` | `56.0.17` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications) | `56.0.16` | `56.0.17` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `56.2.9` | `56.2.10` |
| [expo-sqlite](https://github.com/expo/expo/tree/HEAD/packages/expo-sqlite) | `56.0.4` | `56.0.5` |
| [@codemirror/view](https://github.com/codemirror/view) | `6.43.0` | `6.43.1` |
| [pg-boss](https://github.com/timgit/pg-boss) | `12.18.2` | `12.18.3` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.56.0` | `10.57.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.57.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.19.20` | `22.19.21` |



Updates `turbo` from 2.9.17 to 2.9.18
- [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.17...v2.9.18)

Updates `@logtape/logtape` from 2.1.1 to 2.1.3
- [Changelog](https://github.com/dahlia/logtape/blob/main/CHANGES.md)
- [Commits](https://github.com/dahlia/logtape/commits/2.1.3/packages/logtape)

Updates `isbot` from 5.1.41 to 5.1.42
- [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omrilotan/isbot/compare/v5.1.41...v5.1.42)

Updates `nodemailer` from 8.0.10 to 8.0.11
- [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.10...v8.0.11)

Updates `@types/nodemailer` from 8.0.0 to 8.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

Updates `@types/nodemailer` from 8.0.0 to 8.0.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nodemailer)

Updates `@expo/metro-runtime` from 56.0.14 to 56.0.15
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits)

Updates `@maplibre/maplibre-react-native` from 11.3.3 to 11.3.4
- [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.3.3...v11.3.4)

Updates `expo` from 56.0.9 to 56.0.11
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo)

Updates `expo-constants` from 56.0.17 to 56.0.18
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-constants)

Updates `expo-dev-client` from 56.0.19 to 56.0.20
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client)

Updates `expo-file-system` from 56.0.7 to 56.0.8
- [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 56.0.13 to 56.0.14
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-linking)

Updates `expo-location` from 56.0.16 to 56.0.17
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location)

Updates `expo-notifications` from 56.0.16 to 56.0.17
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications)

Updates `expo-router` from 56.2.9 to 56.2.10
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router)

Updates `expo-sqlite` from 56.0.4 to 56.0.5
- [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 `@codemirror/view` from 6.43.0 to 6.43.1
- [Changelog](https://github.com/codemirror/view/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codemirror/view/commits)

Updates `pg-boss` from 12.18.2 to 12.18.3
- [Release notes](https://github.com/timgit/pg-boss/releases)
- [Commits](https://github.com/timgit/pg-boss/compare/12.18.2...12.18.3)

Updates `@sentry/node` from 10.56.0 to 10.57.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.56.0...10.57.0)

Updates `@sentry/react` from 10.53.1 to 10.57.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.53.1...10.57.0)

Updates `@types/node` from 22.19.20 to 22.19.21
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@codemirror/view"
  dependency-version: 6.43.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@expo/metro-runtime"
  dependency-version: 56.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@logtape/logtape"
  dependency-version: 2.1.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@maplibre/maplibre-react-native"
  dependency-version: 11.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@sentry/node"
  dependency-version: 10.57.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react"
  dependency-version: 10.57.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@types/node"
  dependency-version: 22.19.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@types/nodemailer"
  dependency-version: 8.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@types/nodemailer"
  dependency-version: 8.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo
  dependency-version: 56.0.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-constants
  dependency-version: 56.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-dev-client
  dependency-version: 56.0.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-file-system
  dependency-version: 56.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-linking
  dependency-version: 56.0.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-location
  dependency-version: 56.0.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-notifications
  dependency-version: 56.0.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-router
  dependency-version: 56.2.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-sqlite
  dependency-version: 56.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: isbot
  dependency-version: 5.1.42
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: nodemailer
  dependency-version: 8.0.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: pg-boss
  dependency-version: 12.18.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: turbo
  dependency-version: 2.9.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-11 19:22:35 +00:00
Ullrich Schäfer
c3454641df
security: validate Planner callback URL to close an SSRF sink
The session callbackUrl becomes a server-side fetch target in
api.save-to-journal (POSTed with the callback bearer token, and the
journal's response is reflected to the caller). The /new query-param
loader already validated it, but the programmatic POST /api/sessions
entry point — anonymous, since the Planner is stateless — stored it
unvalidated. An attacker could make the Planner backend POST to
arbitrary hosts, including 169.254.169.254 and other internal targets.

- validateFetchUrl now blocks private / loopback / link-local /
  CGNAT / cloud-metadata hosts (IPv4, IPv6, IPv4-mapped) when an
  explicit allowlist isn't set. Gated on NODE_ENV=production && !E2E
  (the requireSecret idiom) so the dev/e2e journal-on-localhost save
  flow is unaffected. An explicit PLANNER_CALLBACK_ALLOWED_HOSTS still
  takes precedence and remains the full-closure control (it also stops
  DNS-name-to-private rebinding, which literal blocking does not).
- POST /api/sessions now validates callbackUrl exactly as /new does.
- api.save-to-journal re-validates immediately before the fetch
  (defense in depth: covers sessions persisted before this change and
  narrows the create→save rebinding window).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 22:18:18 +02:00
Ullrich Schäfer
765c9f49a8
remove the map and ui shim packages
Both failed the deletion test in the telling direction:

- @trails-cool/ui: Button/Input/Card had zero consumers — both apps
  roll their own elements inline. The only live part was a 6-line
  styles.css (the Tailwind entry + one keyframe), which now lives in
  each app as app/styles.css.
- @trails-cool/map: MapView and RouteLayer had zero consumers; the
  package was otherwise a re-export of two map-core constants, and the
  two import sites now use @trails-cool/map-core directly. The
  "map components go in @trails-cool/map" convention had drifted long
  ago — the real map components live in apps/planner/app/components.

CLAUDE.md's repository structure and conventions updated to match
reality (including pointing shared-type guidance at the post-#515
sources: db row types, api contracts, Waypoint in types). Dockerfiles
no longer COPY the deleted package manifests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 07:47:59 +02:00
Ullrich Schäfer
bf0f7f8d9f
Merge branch 'main' into planner-route-data-seam 2026-06-10 01:48:18 +02:00
dependabot[bot]
154dccf312
chore(deps): Bump node from 25-slim to 26-slim in /apps/planner
Bumps node from 25-slim to 26-slim.

---
updated-dependencies:
- dependency-name: node
  dependency-version: 26-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-09 23:36:01 +00:00
Ullrich Schäfer
3b9672e0ff
planner: give the Yjs document a typed schema seam
The routeData Y.Map's ~15 string keys (geojson, coordinates,
segmentBoundaries, road metadata, profile, colorMode, baseLayer,
overlays, poiCategories) were read and written raw at ~30 call sites,
each with its own JSON parsing and casts; parseJsonArray existed twice
and waypoint extraction four times. GPX assembly was duplicated between
SaveToJournalButton and ExportButton, so the saved plan and the
exported file could silently diverge.

- new lib/route-data.ts owns the routeData (+ noGoAreas) schema:
  typed read/write, JSON encoding internal, ColorMode moves here
  (re-exported from ColoredRoute for existing importers)
- new lib/gpx-export.ts owns GPX assembly: buildRouteGpx /
  buildPlanGpx / buildDayGpxFiles / hasDayBreaks; multi-day splitting
  becomes a pure, tested function
- waypoint-ymap.ts gains extractWaypoints / extractWaypointData; the
  four hand-rolled copies (use-routing, use-waypoint-manager,
  WaypointSidebar, use-days) now share it, and WaypointSidebar's
  moveWaypoint reuses the round-trip helpers instead of re-listing
  every waypoint field
- all hooks/components consume the seam; no raw routeData key strings
  remain outside route-data.ts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 01:35:04 +02:00
dependabot[bot]
a4582654e1
chore(deps): bump the production group across 1 directory with 30 updates
Bumps the production group with 29 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `19.2.6` | `19.2.7` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.2.15` | `19.2.17` |
| [@expo/fingerprint](https://github.com/expo/expo/tree/HEAD/packages/@expo/fingerprint) | `0.19.3` | `0.19.4` |
| [@fission-ai/openspec](https://github.com/Fission-AI/OpenSpec) | `1.3.1` | `1.4.1` |
| [fit-file-parser](https://github.com/jimmykane/fit-parser) | `3.0.1` | `3.0.2` |
| [i18next](https://github.com/i18next/i18next) | `26.3.0` | `26.3.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.60.0` | `8.60.1` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `4.1.7` | `4.1.8` |
| [isbot](https://github.com/omrilotan/isbot) | `5.1.40` | `5.1.41` |
| [@expo/metro-runtime](https://github.com/expo/expo) | `56.0.13` | `56.0.14` |
| [@maplibre/maplibre-react-native](https://github.com/maplibre/maplibre-react-native) | `11.3.0` | `11.3.3` |
| [@sentry/cli](https://github.com/getsentry/sentry-cli) | `3.4.3` | `3.5.0` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants) | `56.0.16` | `56.0.17` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client) | `56.0.18` | `56.0.19` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location) | `56.0.15` | `56.0.16` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications) | `56.0.15` | `56.0.16` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `56.2.8` | `56.2.9` |
| [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-reanimated) | `4.4.0` | `4.4.1` |
| [react-test-renderer](https://github.com/facebook/react/tree/HEAD/packages/react-test-renderer) | `19.2.6` | `19.2.7` |
| [@vitest/browser](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser) | `4.1.7` | `4.1.8` |
| [@vitest/browser-playwright](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright) | `4.1.7` | `4.1.8` |
| [@react-router/dev](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dev) | `7.16.0` | `7.17.0` |
| [@react-router/node](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-node) | `7.16.0` | `7.17.0` |
| [@react-router/serve](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-serve) | `7.16.0` | `7.17.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.55.0` | `10.56.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.56.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.19.19` | `22.19.20` |
| [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `19.2.6` | `19.2.7` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `7.16.0` | `7.17.0` |



Updates `react` from 19.2.6 to 19.2.7
- [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.7/packages/react)

Updates `@types/react` from 19.2.15 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@expo/fingerprint` from 0.19.3 to 0.19.4
- [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 `@fission-ai/openspec` from 1.3.1 to 1.4.1
- [Release notes](https://github.com/Fission-AI/OpenSpec/releases)
- [Changelog](https://github.com/Fission-AI/OpenSpec/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Fission-AI/OpenSpec/compare/v1.3.1...v1.4.1)

Updates `fit-file-parser` from 3.0.1 to 3.0.2
- [Changelog](https://github.com/jimmykane/fit-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jimmykane/fit-parser/commits)

Updates `i18next` from 26.3.0 to 26.3.1
- [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.3.0...v26.3.1)

Updates `typescript-eslint` from 8.60.0 to 8.60.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.60.1/packages/typescript-eslint)

Updates `vitest` from 4.1.7 to 4.1.8
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/vitest)

Updates `isbot` from 5.1.40 to 5.1.41
- [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md)
- [Commits](https://github.com/omrilotan/isbot/compare/v5.1.40...v5.1.41)

Updates `@expo/metro-runtime` from 56.0.13 to 56.0.14
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits)

Updates `@maplibre/maplibre-react-native` from 11.3.0 to 11.3.3
- [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.3.0...v11.3.3)

Updates `@sentry/cli` from 3.4.3 to 3.5.0
- [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.3...3.5.0)

Updates `expo-constants` from 56.0.16 to 56.0.17
- [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 56.0.18 to 56.0.19
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-dev-client)

Updates `expo-location` from 56.0.15 to 56.0.16
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-location)

Updates `expo-notifications` from 56.0.15 to 56.0.16
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications)

Updates `expo-router` from 56.2.8 to 56.2.9
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router)

Updates `react-native-reanimated` from 4.4.0 to 4.4.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.4.1/packages/react-native-reanimated)

Updates `@types/react` from 19.2.15 to 19.2.17
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-test-renderer` from 19.2.6 to 19.2.7
- [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.7/packages/react-test-renderer)

Updates `@vitest/browser` from 4.1.7 to 4.1.8
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/browser)

Updates `@vitest/browser-playwright` from 4.1.7 to 4.1.8
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.8/packages/browser-playwright)

Updates `@react-router/dev` from 7.16.0 to 7.17.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.17.0/packages/react-router-dev)

Updates `@react-router/node` from 7.16.0 to 7.17.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.17.0/packages/react-router-node)

Updates `@react-router/serve` from 7.16.0 to 7.17.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.17.0/packages/react-router-serve)

Updates `@sentry/node` from 10.55.0 to 10.56.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.55.0...10.56.0)

Updates `@sentry/react` from 10.53.1 to 10.56.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.53.1...10.56.0)

Updates `@types/node` from 22.19.19 to 22.19.20
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `react-dom` from 19.2.6 to 19.2.7
- [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.7/packages/react-dom)

Updates `react-router` from 7.16.0 to 7.17.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.17.0/packages/react-router)

Updates `vite` from 7.3.3 to 7.3.5
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.5/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.5/packages/vite)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@expo/fingerprint"
  dependency-version: 0.19.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@fission-ai/openspec"
  dependency-version: 1.4.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: fit-file-parser
  dependency-version: 3.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: i18next
  dependency-version: 26.3.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: typescript-eslint
  dependency-version: 8.60.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: vitest
  dependency-version: 4.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: isbot
  dependency-version: 5.1.41
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@expo/metro-runtime"
  dependency-version: 56.0.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@maplibre/maplibre-react-native"
  dependency-version: 11.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@sentry/cli"
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: expo-constants
  dependency-version: 56.0.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-dev-client
  dependency-version: 56.0.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-location
  dependency-version: 56.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-notifications
  dependency-version: 56.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-router
  dependency-version: 56.2.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-native-reanimated
  dependency-version: 4.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@types/react"
  dependency-version: 19.2.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-test-renderer
  dependency-version: 19.2.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@vitest/browser"
  dependency-version: 4.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@vitest/browser-playwright"
  dependency-version: 4.1.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@react-router/dev"
  dependency-version: 7.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@react-router/node"
  dependency-version: 7.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@react-router/serve"
  dependency-version: 7.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/node"
  dependency-version: 10.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react"
  dependency-version: 10.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@types/node"
  dependency-version: 22.19.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-router
  dependency-version: 7.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: vite
  dependency-version: 7.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-07 09:48:14 +00:00
dependabot[bot]
2e6a83b063
chore(deps): bump the production group with 28 updates
Bumps the production group with 28 updates:

| Package | From | To |
| --- | --- | --- |
| [@expo/fingerprint](https://github.com/expo/expo/tree/HEAD/packages/@expo/fingerprint) | `0.19.2` | `0.19.3` |
| [eslint](https://github.com/eslint/eslint) | `10.4.0` | `10.4.1` |
| [fit-file-parser](https://github.com/jimmykane/fit-parser) | `3.0.0` | `3.0.1` |
| [i18next](https://github.com/i18next/i18next) | `26.2.0` | `26.3.0` |
| [turbo](https://github.com/vercel/turborepo) | `2.9.14` | `2.9.16` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.59.4` | `8.60.0` |
| [@simplewebauthn/server](https://github.com/MasterKale/SimpleWebAuthn/tree/HEAD/packages/server) | `13.3.0` | `13.3.1` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `8.0.8` | `8.0.10` |
| [@expo/metro-runtime](https://github.com/expo/expo) | `56.0.12` | `56.0.13` |
| [@maplibre/maplibre-react-native](https://github.com/maplibre/maplibre-react-native) | `11.2.1` | `11.3.0` |
| [@sentry/react-native](https://github.com/getsentry/sentry-react-native) | `8.12.0` | `8.13.0` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants) | `56.0.15` | `56.0.16` |
| [expo-crypto](https://github.com/expo/expo/tree/HEAD/packages/expo-crypto) | `56.0.3` | `56.0.4` |
| [expo-dev-client](https://github.com/expo/expo/tree/HEAD/packages/expo-dev-client) | `56.0.15` | `56.0.18` |
| [expo-linking](https://github.com/expo/expo/tree/HEAD/packages/expo-linking) | `56.0.11` | `56.0.13` |
| [expo-location](https://github.com/expo/expo/tree/HEAD/packages/expo-location) | `56.0.13` | `56.0.15` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications) | `56.0.13` | `56.0.15` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `56.2.6` | `56.2.8` |
| [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-reanimated) | `4.3.1` | `4.4.0` |
| [react-native-safe-area-context](https://github.com/AppAndFlow/react-native-safe-area-context) | `5.7.0` | `5.8.0` |
| [react-native-worklets](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-worklets) | `0.8.3` | `0.9.1` |
| [yjs](https://github.com/yjs/yjs) | `13.6.30` | `13.6.31` |
| [@react-router/dev](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dev) | `7.15.1` | `7.16.0` |
| [@react-router/node](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-node) | `7.15.1` | `7.16.0` |
| [@react-router/serve](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-serve) | `7.15.1` | `7.16.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.55.0` |
| [@sentry/react](https://github.com/getsentry/sentry-javascript) | `10.53.1` | `10.55.0` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `7.15.1` | `7.16.0` |


Updates `@expo/fingerprint` from 0.19.2 to 0.19.3
- [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 `eslint` from 10.4.0 to 10.4.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v10.4.0...v10.4.1)

Updates `fit-file-parser` from 3.0.0 to 3.0.1
- [Changelog](https://github.com/jimmykane/fit-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jimmykane/fit-parser/commits)

Updates `i18next` from 26.2.0 to 26.3.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.2.0...v26.3.0)

Updates `turbo` from 2.9.14 to 2.9.16
- [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.14...v2.9.16)

Updates `typescript-eslint` from 8.59.4 to 8.60.0
- [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.60.0/packages/typescript-eslint)

Updates `@simplewebauthn/server` from 13.3.0 to 13.3.1
- [Release notes](https://github.com/MasterKale/SimpleWebAuthn/releases)
- [Changelog](https://github.com/MasterKale/SimpleWebAuthn/blob/master/CHANGELOG.md)
- [Commits](https://github.com/MasterKale/SimpleWebAuthn/commits/v13.3.1/packages/server)

Updates `nodemailer` from 8.0.8 to 8.0.10
- [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.8...v8.0.10)

Updates `@expo/metro-runtime` from 56.0.12 to 56.0.13
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits)

Updates `@maplibre/maplibre-react-native` from 11.2.1 to 11.3.0
- [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.2.1...v11.3.0)

Updates `@sentry/react-native` from 8.12.0 to 8.13.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.12.0...8.13.0)

Updates `expo-constants` from 56.0.15 to 56.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-crypto` from 56.0.3 to 56.0.4
- [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 56.0.15 to 56.0.18
- [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-linking` from 56.0.11 to 56.0.13
- [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 56.0.13 to 56.0.15
- [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-notifications` from 56.0.13 to 56.0.15
- [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-router` from 56.2.6 to 56.2.8
- [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 `react-native-reanimated` from 4.3.1 to 4.4.0
- [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.4.0/packages/react-native-reanimated)

Updates `react-native-safe-area-context` from 5.7.0 to 5.8.0
- [Release notes](https://github.com/AppAndFlow/react-native-safe-area-context/releases)
- [Commits](https://github.com/AppAndFlow/react-native-safe-area-context/compare/v5.7.0...v5.8.0)

Updates `react-native-worklets` from 0.8.3 to 0.9.1
- [Release notes](https://github.com/software-mansion/react-native-reanimated/releases)
- [Commits](https://github.com/software-mansion/react-native-reanimated/commits/worklets-0.9.1/packages/react-native-worklets)

Updates `yjs` from 13.6.30 to 13.6.31
- [Release notes](https://github.com/yjs/yjs/releases)
- [Commits](https://github.com/yjs/yjs/compare/v13.6.30...v13.6.31)

Updates `@react-router/dev` from 7.15.1 to 7.16.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.16.0/packages/react-router-dev)

Updates `@react-router/node` from 7.15.1 to 7.16.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.16.0/packages/react-router-node)

Updates `@react-router/serve` from 7.15.1 to 7.16.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.16.0/packages/react-router-serve)

Updates `@sentry/node` from 10.53.1 to 10.55.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.53.1...10.55.0)

Updates `@sentry/react` from 10.53.1 to 10.55.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.53.1...10.55.0)

Updates `react-router` from 7.15.1 to 7.16.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.16.0/packages/react-router)

---
updated-dependencies:
- dependency-name: "@expo/fingerprint"
  dependency-version: 0.19.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: eslint
  dependency-version: 10.4.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: fit-file-parser
  dependency-version: 3.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: i18next
  dependency-version: 26.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: turbo
  dependency-version: 2.9.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: typescript-eslint
  dependency-version: 8.60.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@simplewebauthn/server"
  dependency-version: 13.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: nodemailer
  dependency-version: 8.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@expo/metro-runtime"
  dependency-version: 56.0.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@maplibre/maplibre-react-native"
  dependency-version: 11.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react-native"
  dependency-version: 8.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: expo-constants
  dependency-version: 56.0.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-crypto
  dependency-version: 56.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-dev-client
  dependency-version: 56.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-linking
  dependency-version: 56.0.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-location
  dependency-version: 56.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-notifications
  dependency-version: 56.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: expo-router
  dependency-version: 56.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: react-native-reanimated
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: react-native-safe-area-context
  dependency-version: 5.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: react-native-worklets
  dependency-version: 0.9.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: yjs
  dependency-version: 13.6.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production
- dependency-name: "@react-router/dev"
  dependency-version: 7.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@react-router/node"
  dependency-version: 7.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@react-router/serve"
  dependency-version: 7.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/node"
  dependency-version: 10.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: "@sentry/react"
  dependency-version: 10.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
- dependency-name: react-router
  dependency-version: 7.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-31 08:37:04 +00:00
Ullrich Schäfer
10deae88c9
fix: extensionless server-side imports + lint rule to catch them
## Symptom

Grafana's \`app-crash-log\` alert fires on every deploy. The Loki query
that backs it (\`ERR_|FATAL|uncaughtException|…\`) matches:

  Error [ERR_MODULE_NOT_FOUND]: Cannot find module
  '/app/apps/journal/app/lib/logger.server' imported from
  '/app/apps/journal/app/lib/email.server.ts'

A real bug, not a false positive: \`email.server.ts\` line 2 was
\`import { logger } from \"./logger.server\"\` — no extension.

## Why typecheck didn't catch it

\`tsconfig.base.json\` sets \`moduleResolution: \"bundler\"\`. The bundler
resolver accepts extensionless relative imports because Vite / esbuild
/ webpack resolve them at build time. TypeScript was happy.

Production runs \`node --experimental-strip-types server.ts\`, which
uses Node's NodeNext ESM resolver — strict about extensions. The two
resolvers disagree silently for files Node loads directly (server.ts,
\`.server.ts\` modules dynamically imported from it, and jobs).

## Fix

1. **Added \`.ts\` extensions to the 4 broken imports** I could find:
   - \`apps/journal/app/lib/email.server.ts\` → \`./logger.server.ts\`
     (the actual deploy-blocker)
   - \`apps/planner/app/lib/brouter.ts\` → \`./route-merge.ts\`, \`./http.server.ts\`
   - \`apps/planner/app/lib/use-nearby-pois.ts\` → \`./overpass.ts\`
   - \`packages/map/src/MapView.tsx\` → \`./layers.ts\` (caught by the rule)

2. **Added \`eslint-plugin-import-x\` with \`import-x/extensions: always\`**,
   scoped to files Node actually executes raw:
   - \`apps/*/server.ts\`
   - \`apps/*/app/lib/**/*.server.ts\`
   - \`apps/*/app/jobs/**/*.ts\`
   - \`packages/*/src/**/*.{ts,tsx}\`

   Ignored: route-scoped \`*.server.ts\` files (bundled by Vite into the
   React Router build, never loaded by Node), and test files (Vitest's
   own resolver).

## What's still possible

- Non-\`.server.ts\` files in \`app/lib\` (e.g. \`legal.ts\`, \`actor-iri.ts\`)
  could still ship extensionless imports. They're not in the lint
  scope. If one breaks at runtime we can extend the glob — for now
  they tend to be tiny utility modules that don't import other
  relatives.
- The deeper fix would be \`moduleResolution: nodenext\` for server-side
  tsconfig, or bundling the server code so Node never sees raw \`.ts\`.
  Bigger surgery; the lint rule covers the failure mode for now.

Full repo: pnpm typecheck / lint / test all green after \`pnpm install\`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 08:08:19 +02:00
Ullrich Schäfer
7918ba052a
chore(ts): drop the last 2 \eslint-disable\ comments in prod code
After this, \`grep -rn 'eslint-disable' apps/ packages/\` returns 0
(excluding tests and node_modules).

**\`apps/planner/app/lib/brouter.ts\`** — \`while (true)\` in
\`readBodyWithCap\` tripped \`no-constant-condition\`. Replaced with
\`for (;;)\` which the rule explicitly allows. No behavior change.

**\`packages/gpx/src/parse.ts\`** — the sync \`parseGpx\` exported a
fallback path that did \`require(\"linkedom\")\` for non-browser sync
use, with an \`eslint-disable\` for \`no-require-imports\`. It was dead
code: \`packages/gpx/src/index.ts\` only re-exports \`parseGpxAsync\`,
and grepping the monorepo finds no caller of the sync version. Deleted
the function entirely; \`getDOMParser\` (the async helper) still serves
the async path with a clean ESM \`await import(\"linkedom\")\`.

Full repo: pnpm typecheck / lint / test all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:34:09 +02:00
Ullrich Schäfer
a724f862b8
chore(ts): drop two more redundant casts
- RouteMapThumbnail.client.tsx: `{ type: 'Feature', ... } as unknown
  as GeoJsonObject` → `as GeoJsonObject`. The literal already
  satisfies the type; the unknown bridge was unnecessary.

- use-yjs.ts:102: keep the coercion (y-websocket's `.on()` signature
  doesn't include the legacy `"synced"` event even though the
  runtime still fires it), but document why with a comment so future
  readers don't try to drop it.
2026-05-26 01:02:49 +02:00
Ullrich Schäfer
985ec54023
chore(ts): replace 7 \as unknown as\ shims with proper types
Most of the existing coercions are legitimate (Drizzle raw-SQL row
shapes, linkedom DOMParser interop, fit-file-parser's loose \`any\`
callback API) — leaving those is honest. The ones cleaned up here
were shims around APIs that have real types we just hadn't wired:

- **\`window.__leafletMap\`** (4 sites: MapHelpers.tsx, SessionView.tsx ×3)
  Added \`Window\` declaration in \`apps/planner/app/types/global.d.ts\`.
  Callers now use plain \`window.__leafletMap\` typed as
  \`L.Map | undefined\`.

- **\`L.markerClusterGroup\`** (PoiPanel.tsx) — leaflet.markercluster
  augments the global \`L\` namespace at runtime but ships no types.
  Added a \`declare module \"leaflet\"\` block in the same global.d.ts
  with a minimal signature for what we actually use.

- **\`L.DomEvent.preventDefault / .stop\`** taking a Leaflet event
  rather than a native one (PlannerMap.tsx, RouteInteraction.tsx,
  NoGoAreaLayer.tsx). Leaflet events carry the native event under
  \`.originalEvent\`; using that drops the cast entirely.

- **\`_creds as unknown as OAuthCredentials\`** orphan in
  wahoo/webhook.ts — \`_creds\` was unused inside the callback (the
  void-cast was a no-op preserving the type for documentation).
  Replaced with \`async ()\`, dropped the unused import.

Net: 26 \`as unknown as\` / \`as any\` sites → 19, all remaining ones
gated by external lib interop or Drizzle raw-SQL.

Full repo: pnpm typecheck / lint / test all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 01:02:25 +02:00
Ullrich Schäfer
e1c696d598
Merge branch 'main' into fix/planner-brouter-response-size 2026-05-26 00:53:52 +02:00