pub fn catch_up_dm_conversation(
conn: &mut Connection,
room_id: &str,
messages: &[LegacyDmMessageImport],
receipts: &[LegacyDmReadReceipt],
) -> Result<DmMigrationCounts, MatrixStoreError>Expand description
A catch-up pass for an ALREADY migrated room (P15) — the binary crate’s
own matrix_migration module calls this both from a live legacy DM
send’s bridge (routes::dm::create_message, right after its own insert
commits) and from a boot pass over a conversation
room_by_legacy_dm_id already finds a room for. messages (already
filtered by the caller to exclude anything already in
legacy_dm_message_map, ordered ascending by legacy_message_id) lands
as new org.example.legacy_dm timeline events plus their
legacy_dm_message_map rows; then each of receipts advances that
reader’s m.read receipt — never moved backwards
([upsert_receipt_in_tx]’s own guarantee, the SAME one a live /receipt
call gets) — all in ONE transaction. Reuses the exact per-event helpers
migrate_dm_conversation itself uses, so a caught-up room’s rows are
indistinguishable from ones a fresh migration (or a live Matrix send)
would have produced.
Each receipt.up_to_legacy_message_id is resolved via
legacy_dm_message_event_id against the FULL map (this transaction’s
own just-inserted rows are visible to it too, same connection) — not just
this call’s own messages — because the caller’s own read-position query
considers EVERY read message in the conversation, including ones a
PRIOR pass already imported (a message read only after it was already
bridged must still move the receipt here; manager review, P15). A target
this catch-up’s own messages did not just insert AND that is not yet in
the map at all (should not happen — a receipt only ever targets a message
that exists) is skipped rather than erroring, same defensive posture
migrate_dm_conversation’s own receipt loop takes.