A check-out is the LATEST the room has to be handed back, never the earliest anybody may drive on, so it says nothing the chain can use. It shaped four things it had no business shaping: the departure the day was built from, the length the rail printed for a booked night, a day-selector and a clock field in the stop dialog, and the branch that sent a night's STAY badge to the booking form because its length was not editable here. All four go. The booking keeps its check-out; it is a booking detail and lives under Days, where it is entered. What replaces it is the thing that was always the honest answer: how long you stand there. That is the traveller's own statement rather than a deadline, and a stay running past midnight now carries the clock into the morning after — a stop pinned before it ends keeps its hour and collects the late finding, as it would from any leg it cannot make. A stay spanning whole days walks the clock forward over them. An ordinary evening hands on nothing: the night between two days is not a wait somebody is serving out. The stay dialog goes to a full day rather than four hours, since it is now the only place a night is given its hours, and offers eight and twelve as presets. Every stop answers the same question the same way. Overlay panels lose the skeleton placeholder. It was drawn in the page flow, so the first time each dialog was ever opened a pale block flashed under the planner and never again once its chunk was cached.
@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.