deriveDriveWarnings takes a two-slot "does this stop refuel" pair, slot 0 for the stop a leg leaves and slot 1 for the stop it reaches, and the assembler hard-coded slot 1 to false. The suppression the model was written and tested for could therefore never fire through it: a day that reaches a charger 700 km in reported running dry at the charger, and a run of warnings that should collapse to one stayed at full length. Pinned by a spec of its own now, since the wrapper had none. The server's plan built each leg by spreading the whole run's segment and then overriding only its metres and seconds, so every leg of a multi-stop run carried the run's distance text, its duration text and its polyline midpoint: leg one of a 480 km day reported 100 km with "480 km" printed beside it. The four texts and the midpoint are per leg now, in the reader's own unit rather than the router's hard-coded kilometres, which also ends a response that mixed miles in its day labels with kilometres in its legs.
@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.