houserules/packages/server/src
Joey Yakimowich-Payne 109be25be6
feat(server): custom-modifier.register WS handler
T3 Wave 4 (T24). Adds wire protocol + server handler for registering
user-authored custom modifier descriptors on a room's per-engine
custom registry (ADR-4).

Protocol:
- CustomModifierDescriptorSchema (Zod v3 mirror of the chess-side
  schema; structural validation only — primitive-kind semantics stay
  client-side to avoid duplicating the primitive catalog across the
  zod v3/v4 boundary).
- 'custom-modifier.register' client message carrying { roomCode,
  descriptor }.
- 'custom-modifier.registered' server broadcast mirroring the same
  shape out to every connected client in the room.
- New error codes: CUSTOM_MODIFIER_INVALID, CUSTOM_MODIFIER_LIMIT.

Handler:
- Auth + room-match checks matching the rest of the WS surface.
- Lazy per-room Map<id, CustomModifierDescriptorWire> created on first
  register.
- Capacity cap at 10 distinct ids per room (T3 DoS guard). Re-register
  with the same id REPLACES without consuming a new slot.
- On success: broadcasts to every connected client (proposer included
  — confirms server-authoritative state).

6 integration tests (mock ServerWebSocket harness; same pattern as
ws.modifier-profile-update.test.ts): happy-path accept+broadcast,
same-id replace, 11th-distinct rejection, roomCode mismatch, no-auth
rejection, malformed descriptor (schema layer). All green; 1369 unit
tests pass. Engine-side wire-up (late-joiner mirroring, client client.ts
subscriber) deferred to T25/T26 UI work.
2026-04-19 20:01:11 -06:00
..
broadcast.test.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
broadcast.ts feat(server): custom-modifier.register WS handler 2026-04-19 20:01:11 -06:00
game-session.test.ts feat(server): add authoritative game session per room (P4.5) 2026-04-16 17:17:42 -06:00
game-session.ts feat(server): turn-boundary queue for modifier profile updates 2026-04-19 09:06:15 -06:00
index.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
layouts.test.ts feat(server): layout-aware room.create + resolved layout echoes (Phase C) 2026-04-18 20:01:01 -06:00
layouts.ts feat(server): layout-aware room.create + resolved layout echoes (Phase C) 2026-04-18 20:01:01 -06:00
logger.ts feat(server): scaffold Bun HTTP+WS server with health + logging (P4.1) 2026-04-16 17:03:42 -06:00
logging.test.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
logging.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
middleware.test.ts feat(server): add rate-limit, origin allow-list, message-size cap (P4.4) 2026-04-16 17:11:40 -06:00
middleware.ts feat(server): add rate-limit, origin allow-list, message-size cap (P4.4) 2026-04-16 17:11:40 -06:00
protocol.test.ts feat(server): modifier profile protocol schemas + error codes 2026-04-18 22:43:58 -06:00
protocol.ts feat(server): custom-modifier.register WS handler 2026-04-19 20:01:11 -06:00
reconnect.test.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
reconnect.ts feat(server): add reconnection with 60s grace + snapshot resume (P4.7) 2026-04-16 17:38:26 -06:00
room.create-profile.test.ts feat(server): room-create accepts profile 2026-04-18 22:55:24 -06:00
rooms.test.ts feat(server): add room registry with codes + tokens (P4.3) 2026-04-16 17:09:43 -06:00
rooms.ts feat(server): custom-modifier.register WS handler 2026-04-19 20:01:11 -06:00
ws.custom-modifier-register.test.ts feat(server): custom-modifier.register WS handler 2026-04-19 20:01:11 -06:00
ws.modifier-profile-consent.test.ts test(server): two-player consent flow (T3) 2026-04-19 09:25:48 -06:00
ws.modifier-profile-update.test.ts feat(server): turn-boundary queue for modifier profile updates 2026-04-19 09:06:15 -06:00