Files
TX/artifacts/api-server/tests
riyadhafraa 1b40d7dc00 fix(executive-meetings): lock down attendee save payload (#221)
Why:
Task #220 added a client-only `_sid` field on attendee rows so React
DnD can identify rows. The two client save sites already enumerate
wire fields explicitly and never serialize `_sid`, but nothing
prevents a future refactor from accidentally leaking it. The server
was zod-default lenient (silently strips unknowns), so a regression
would either be silently absorbed (bad — silent contract drift) or
land in a future JSONB metadata column without anyone noticing.

What changed:
- `attendeeSchema` in artifacts/api-server/src/routes/executive-meetings.ts
  is now `.strict()`. Any unknown attendee key (including `_sid` or
  any future client-only field) is rejected with HTTP 400 instead of
  being silently stripped. The schema is reused by all three
  attendee-bearing endpoints (POST /executive-meetings,
  PATCH /executive-meetings/:id, PUT /executive-meetings/:id/attendees),
  so all three are covered by one change.

Tests:
- Added three API tests in
  artifacts/api-server/tests/executive-meetings.test.mjs:
  1. POST /executive-meetings with attendee carrying `_sid` returns
     400 and the error mentions the rejected key.
  2. PATCH /executive-meetings/:id with attendees carrying `_sid`
     returns 400 AND the meeting's existing attendee list is
     preserved (no partial mutation).
  3. PUT /executive-meetings/:id/attendees with attendee carrying
     `_sid` returns 400 AND the seeded attendee is unchanged.

Verification:
- Full API test suite: 207/207 green (was 204/204 before; +3 new).
- No client-side change needed: existing `saveAttendeeName` (~L943
  in artifacts/tx-os/src/pages/executive-meetings.tsx) and the
  manage-dialog save (~L4004) already project to the documented
  wire shape (`name, title, attendanceType, sortOrder, kind`).
- Architect review: addressed the one gap (PATCH coverage) by
  adding test #2 above; verdict resolved.

Out of scope cleanup:
- Marked the descriptions of stale tasks #172 and #179 as STALE
  (both PDF tests pass and PDF export works in current main).
  Final cancellation left to the user.
2026-04-30 19:16:00 +00:00
..