Files
TREK/shared
Maurice 9ce6eed9ad feat(places): export a trip as GPX (#1907)
* feat(places): hand a trip back as GPX

TREK reads GPX but never wrote it, so a planned trip could not reach the offline
map or the handheld it was planned for. The importer already fixes the mapping:
a wpt is a place, a rte or trk is a place with route_geometry, so writing is that
reversed. Days have no import counterpart and become routes of their stops in
order, which is the part that puts a plan on a device.

XMLBuilder comes from the same fast-xml-parser the importer parses with, so
nothing new is pulled in.

* feat(dayplan): a GPX button beside PDF and ICS

Scopes are worded by what someone wants on their device rather than by the GPX
element: the whole trip, just the places for an offline map, just the days to
follow a plan. An empty trip says so instead of reporting a failed download.

* feat(mobile): GPX in the export sheet, which is no longer calendar-only

The sheet held the PDF export next to the calendar entries and was still called
Export Calendar; with GPX beside them the name was simply wrong.

* i18n(dayplan): translate the GPX export into all locales

* docs(map): document the GPX export

* fix(dayplan): drop the GPX tooltip and centre both export menus

The tooltip sat under the cursor exactly where the menu opens, so hovering the
button produced both at once. The label lives on as an aria-label. Both menus
now open centred under their button instead of hanging off its right edge.
2026-08-12 12:45:29 +02:00
..
2026-06-16 22:22:45 +02:00
2026-06-18 20:13:30 +02:00
2026-06-16 22:22:45 +02:00
2026-06-16 22:22:45 +02:00
2026-06-16 22:22:45 +02:00
2026-06-16 22:22:45 +02:00

@trek/shared

Single source of truth for TREK's API contracts, expressed as Zod schemas and consumed by both the server (request validation + inferred DTO types) and the client (typed requests/responses).

This package is part of the incremental NestJS + React 19 migration (see the "Brownfield Rewrite" board). It is intentionally dormant until modules start importing it — adding it changes nothing for users.

Rules

  • One folder per domain: src/<domain>/<domain>.schema.ts (+ .spec.ts).
  • Domain-agnostic building blocks live in src/common/.
  • A route is only considered migrated once its contract lives here.
  • Schemas are the source of truth; server DTOs and client types are inferred from them (z.infer<typeof schema>), never hand-duplicated.

Consumption (dev)

Both apps resolve @trek/shared to this package's TypeScript source:

  • Server (tsx): via paths in server/tsconfig.json.
  • Client (vite): via resolve.alias in client/vite.config.ts (+ paths for the type-checker).

Production packaging (Docker / workspace wiring) is introduced in card F2, when the server first depends on this package at runtime. Until then prod builds are untouched.

Not yet here

The canonical error envelope is finalised in card F5 (it must match TREK's current Express error responses byte-for-byte), so it is deliberately not invented in F1.