A via cuts a drive into one routed leg per waypoint pair. Folding them back onto the stop pair summed the metres and seconds but kept the first piece's printed texts and end point, and the phone reads the texts first: a drive into the next day of 3.9 mi in 14 min showed 1.9 mi in 6 min. Every choice under "Other ways" writes vias, so every choice ran into it. The pieces are now merged by one shared helper that writes the texts from the sums in the reader's unit, for a day's own run, for the drive between two days and in the server's plan; the drive between two days is asked for again when the unit changes, as a day's run already is. On the desk a refused way was said in the bar's status line and again in a toast laid over that line. The desk keeps the status line; the phone, whose bar has no room for the sentence, keeps the toast.
@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.