The Tours tab's list of the trip's tours gains a button beside the GPX import: take a tour over from another trip. Its dialog lists the tours of the user's other trips, searched by name and filtered by trip and type, each with its trip and the measures it has (time, distance, ascent; one it lacks is left out, a paddle tour's climb too). Choosing one shows it on a map with where it comes from, its type, distance, time, heights and number of waypoints, and the name it gets in this trip, its own name to start with. The note under the name says the copy is a tour of this trip of its own, on no day yet, and that later changes stay apart. Only the button in the foot takes it over. The new tour then comes into the trip's lists and map and opens in the editor, unless the editor holds unsaved work, which it never replaces. Nothing is written before the confirm, and closing writes nothing. The library is online only: offline, or when the list fails, the dialog says so and offers to try again; a list cut at 100 tours says to search or filter. A tour taken over names its source in its provenance: "Taken over from" with the trip and the tour as they were called then.
@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): viapathsinserver/tsconfig.json. - Client (
vite): viaresolve.aliasinclient/vite.config.ts(+pathsfor 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.