`mobileTrip.rtTruncated` interpolated a count into a sentence naming the stretch once, so at one truncated area it read "1 stretches". Two keys now, picked by the count, the shape this codebase already uses where a number changes its noun. Writing the singular turned up three plurals that were wrong at counts the old one-form key could never reach. Polish and Czech both had the genitive plural with a singular verb, which is right at five and wrong at two; Arabic had the 3 to 10 form, wrong at two and again from eleven. All three now put the count after a colon, where no form has to agree with it. Russian and Ukrainian were already correct at both, since their phrase leads with a locative, and were left alone. The eight languages that keep the singular noun after a numeral differ only in the numeral, which is what they should do.
@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.