A suite under tests/integration/broadcast-parity boots the app once per group, runs a write tool through a real MCP session the way the assistant attaches the registry, runs its REST twin on a twin scene, and records every broadcast. Per case it checks the exact events in order and count, that no MCP broadcast skips a socket (the asking tab hears its own change), that nothing is sent inside a transaction, that every payload parses with its registered schema, that REST sends the same sequence to the same room and recipients, and that MCP's keys cover REST's. A registry test lists the write tools as an MCP client sees them and fails on a tool without a row, a stale row, or an exemption without a reason; exemptions run too and must send nothing, and the tools still waiting for a case are frozen in a list that may only shrink. The new events the next changes send are registered now (member:updated, todo:reordered, trips:changed, settings:updated, tags:changed, notification:read-all, journey:updated, journey:deleted, atlas:changed); the client keeps them apart as awaiting a sender, and the journey page already leaves a journey that journey:deleted says is gone.
@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.