* feat(vacay): support half vacation days (#552) Log a vacation day as a half day (0.5) as well as a full day and count it as such against the entitlement. A "Half day" mode joins the calendar toolbar on desktop and mobile; half days render as a diagonal half-fill in the day cell, and the used/remaining totals carry the fraction. Closes #552 * refactor(vacay): half-day as a per-person toggle with a corner badge The diagonal half-fill collided with the two-person split — one person's half day looked like two people off. Drop the diagonal: the cell fill keeps showing who is off, a half day gets a small corner ½ badge, and a hover tooltip lists who is off on that date and how much (only when a half day is present). Logging moves from a third mode to a Half-day toggle that applies to the selected person, on desktop and mobile. * feat(vacay): mark half days with an orange corner dot Swap the ½ badge for a small orange dot in the bottom-right corner, mirroring the blue trip dot — quieter in the grid, and the hover tooltip still spells out who is on a half day. * fix(vacay): make the fraction migration idempotent The crosswalk test replays the migration tail (rewind + re-run), which expects every later migration to be idempotent. Guard the vacay_entries ADD COLUMN behind a pragma_table_info check so the second run is a no-op. Also only set dayVisual's `half` flag when true, so full days keep their exact { background, numColor } shape for the mobile day-model unit test. * style(vacay): nudge the mobile day dots slightly inward The blue trip dot and orange half-day dot sat right in the cell corner on mobile; move both a touch toward the centre so they read cleaner.
@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.