Implement room:conversation:{conversationId} (typing, receipts, presence, fanout optimization) and room:user:{userId} (cross-device account events). Rooms are ephemeral and rebuildable from Postgres+Redis on restart. They optimize fanout but the authoritative delivery decision still validates conversation_members.
Acceptance criteria:
- Rooms reconstructable after a gateway restart
- Typing/receipts use rooms; message delivery still verifies membership
- No security decision relies solely on room membership
Implement
room:conversation:{conversationId}(typing, receipts, presence, fanout optimization) androom:user:{userId}(cross-device account events). Rooms are ephemeral and rebuildable from Postgres+Redis on restart. They optimize fanout but the authoritative delivery decision still validatesconversation_members.Acceptance criteria: