feat(bridge): similarity scoring + room details + reply channel + contact fusion (#53, #55, #56, #57) #168

Merged
charles merged 7 commits from feat/53-55-56-57-bridge-ui into main 2026-04-06 02:35:08 +00:00
Owner

Summary

Implements four issues in the fractal-bridge crate:

#55 — Similarity scoring and merge suggestions (similarity.rs)

  • levenshtein_distance() and levenshtein_normalized() — normalized similarity in [0.0, 1.0]
  • similarity_score(a, b) — weighted score: display_name ×0.4, shared phone in native_id ×0.5, same bridge server ×0.1
  • MergeSuggestion { contact_a, contact_b, score }
  • suggest_merges(contacts, threshold) — returns pairs above threshold sorted by descending score
  • DEFAULT_MERGE_THRESHOLD: f64 = 0.6
  • Unit tests covering identical/empty strings, above/below threshold cases

#57 — Bridge detection in room details (room_bridge.rs)

  • RoomBridgeInfo { room_id, bridge_type, bot_user_id, detected_puppets }
  • detect_room_bridge(room_id, member_ids) — iterates members, calls BridgeType::detect(), majority-vote determines the room bridge type; falls back to BridgeType::Native
  • RoomBridgeDetails { info, linked_contact }

#53 — Reply channel selector (reply_channel.rs + contact.rs)

  • Added preferred_channel: Option<String> to UnifiedContact
  • ReplyChannel { user_id, bridge_type, display_name }
  • ReplyChannelSelector { contact }
  • available_channels(contact) — maps all identities to ReplyChannel
  • select_channel(contact, user_id) — updates preferred_channel

#56 — Contact fusion UI model (fusion.rs)

  • ContactFusionState enum: Idle, Selecting { candidates }, Confirming { a, b, score }, Done
  • ContactFusionModel { state, rejected_pairs } with propose_merge(), confirm(), reject(), reset()
  • merge_contacts(a, b) — unions identities (deduplicated by user_id), keeps display_name and id of the contact with the most identities
  • Unit tests for confirm/reject flows and deduplication

Files changed

  • crates/fractal-bridge/src/contact.rs — added preferred_channel field
  • crates/fractal-bridge/src/similarity.rs — new
  • crates/fractal-bridge/src/room_bridge.rs — new
  • crates/fractal-bridge/src/reply_channel.rs — new
  • crates/fractal-bridge/src/fusion.rs — new
  • crates/fractal-bridge/src/lib.rs — updated module declarations and re-exports

Closes #53, #55, #56, #57

## Summary Implements four issues in the `fractal-bridge` crate: ### #55 — Similarity scoring and merge suggestions (`similarity.rs`) - `levenshtein_distance()` and `levenshtein_normalized()` — normalized similarity in [0.0, 1.0] - `similarity_score(a, b)` — weighted score: display_name ×0.4, shared phone in native_id ×0.5, same bridge server ×0.1 - `MergeSuggestion { contact_a, contact_b, score }` - `suggest_merges(contacts, threshold)` — returns pairs above threshold sorted by descending score - `DEFAULT_MERGE_THRESHOLD: f64 = 0.6` - Unit tests covering identical/empty strings, above/below threshold cases ### #57 — Bridge detection in room details (`room_bridge.rs`) - `RoomBridgeInfo { room_id, bridge_type, bot_user_id, detected_puppets }` - `detect_room_bridge(room_id, member_ids)` — iterates members, calls `BridgeType::detect()`, majority-vote determines the room bridge type; falls back to `BridgeType::Native` - `RoomBridgeDetails { info, linked_contact }` ### #53 — Reply channel selector (`reply_channel.rs` + `contact.rs`) - Added `preferred_channel: Option<String>` to `UnifiedContact` - `ReplyChannel { user_id, bridge_type, display_name }` - `ReplyChannelSelector { contact }` - `available_channels(contact)` — maps all identities to `ReplyChannel` - `select_channel(contact, user_id)` — updates `preferred_channel` ### #56 — Contact fusion UI model (`fusion.rs`) - `ContactFusionState` enum: `Idle`, `Selecting { candidates }`, `Confirming { a, b, score }`, `Done` - `ContactFusionModel { state, rejected_pairs }` with `propose_merge()`, `confirm()`, `reject()`, `reset()` - `merge_contacts(a, b)` — unions identities (deduplicated by user_id), keeps display_name and id of the contact with the most identities - Unit tests for confirm/reject flows and deduplication ## Files changed - `crates/fractal-bridge/src/contact.rs` — added `preferred_channel` field - `crates/fractal-bridge/src/similarity.rs` — new - `crates/fractal-bridge/src/room_bridge.rs` — new - `crates/fractal-bridge/src/reply_channel.rs` — new - `crates/fractal-bridge/src/fusion.rs` — new - `crates/fractal-bridge/src/lib.rs` — updated module declarations and re-exports Closes #53, #55, #56, #57
charles deleted branch feat/53-55-56-57-bridge-ui 2026-04-06 02:35:08 +00:00
Sign in to join this conversation.
No description provided.