docs: document S2S DM close/reopen relay events

Add federation.md section 8b covering dm_close/dm_reopen relay events:
payload, outbound queueing via queueDmCloseRelay, inbound processDmCloseEvent/
processDmReopenEvent handlers (lookup-only identity resolution, silent
no-ops on missing channel/user/membership), and the processCreateEvent
closed-state reopen bug fix.

Update dm-system.md soft-close section with federation behaviour: relay
to peers for both close and reopen, relayed-message reopen in
processCreateEvent, and the federatedId-only guard for legacy DMs.
This commit is contained in:
Jannis Braun
2026-04-07 22:43:04 +02:00
parent f85bb4cca3
commit 28624343d0
2 changed files with 83 additions and 0 deletions
+9
View File
@@ -159,6 +159,15 @@ When a new message arrives in a DM channel, for each member with `closed = 1`:
This ensures closed DMs resurface automatically when new activity occurs.
### Federation
Close and reopen are relayed to all peer instances that hold a copy of the DM:
- **Close relay:** After setting `closed = 1` locally, `queueDmCloseRelay(channelId, userId, 'dm_close')` queues a `dm_close` outbox event. The receiving instance finds the channel by `federatedId`, resolves the acting user via `resolveLocalUser`, sets `closed = 1` on the local `dm_members` row, and broadcasts `dm_channel_closed`.
- **Reopen relay:** Explicit reopens (`POST /api/dm/:id/reopen`) queue a `dm_reopen` event. The receiving instance sets `closed = 0` and broadcasts `dm_channel_created` with a full channel payload.
- **Relayed-message reopen:** `processCreateEvent` (inbound message relay) also checks each recipient's `closed` flag and performs the same resurface sequence (`dm_channel_created``dm_message_created`) — mirroring `broadcastDmMessage`. This ensures messages relayed from a remote instance properly reopen closed DMs on the receiving instance.
- Only fires for DMs with a `federatedId`. Legacy local-only DMs (no `federatedId`) are unaffected.
### Frontend
- `spaceStore.closeDm(id)` calls `api.dm.close(id)` then removes the channel from `dmChannels` state