Files
festipod/src/shared
Sylvain Duchesne cd2a45c254 feat(data): participantCount via Option B (deposit + owner materialization)
Remove the write-isolation violation: joinEvent/leaveEvent no longer write
participantCount on the event doc (a non-owner writing the owner's public doc —
illegitimate in NextGraph). The joiner/leaver only write their own protected
participation doc and DEPOSIT a marker into the event inbox (depositRegistration /
depositLeave).

The event OWNER's session materializes: it subscribes (inbox.watch, doc_subscribe —
no polling) to the inboxes of its OWNED events (ownedEventIds), and on each deposit
recomputes participantCount on its OWN event doc. The count is DERIVED, not
incremented: materializeAttendance derives the SET of distinct active registrations
(new-participant deduped by uid, MINUS leave-participant by regUid/fallback
eventId+userId), count = 1 (host self) + |active set|. A pure function of the inbox
→ broker re-syncs converge, never double-count nor resurrect (idempotent); the write
is guarded (only on change → no loop). Authoritative deleteParticipation preserved
(caveat_participation-deletion).

Because the owner writes its own PUBLIC event doc and every session subscribes to it
(P3), the count round-trips reactively to all — no reload. Owner-offline = eventual
(V1; a future @ng-eventually/service materializes on the owner's behalf).

Real 2-browser e2e (e2e-multibrowser.feature): B registers → A materializes → count
1→2 reactively (no reload) + unknown participant; B leaves → count →1. 14/14 green.
Gates: @data auth 4/4, @data isolation 4/4, build + tsc clean. Doctrine:
knowledge_context-internals (Option B section).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 09:24:55 +02:00
..