Skip to content

feat(messages): mention counting, read-state sync & space_id in unreads#27

Merged
krazyjakee merged 1 commit into
masterfrom
feat/read-state-sync-and-mentions
Jun 10, 2026
Merged

feat(messages): mention counting, read-state sync & space_id in unreads#27
krazyjakee merged 1 commit into
masterfrom
feat/read-state-sync-and-mentions

Conversation

@krazyjakee

Copy link
Copy Markdown
Contributor

Summary

  • Parse @everyone/@here and @username mentions server-side (no regex crate — hand-rolled parser in src/mentions.rs), resolve handles to space members, and persist mention_everyone + mentions JSON on each message.
  • Increment a durable per-channel mention counter for every mentioned member so unread mention badges survive restarts and reconnects.
  • Add space_id to the unread payload in both the gateway READY and GET /users/@me/read-states, so multi-server clients can route a notification to the correct space.
  • Broadcast a targeted read_state.update gateway event on POST /channels/{id}/ack, so reading on one device clears the unread badge on the user's other sessions.

Details

  • src/mentions.rs (new): parse_mentions(content) returns ParsedMentions { everyone, usernames }. Guards @ against email domains, restricts handle chars to [A-Za-z0-9_], case-insensitive everyone/here, deduped usernames. 4 unit tests.
  • src/db/members.rs: resolve_mention_user_ids maps usernames → member IDs scoped to the space.
  • src/db/messages.rs: create_message parses + resolves + stores mention data (signature unchanged).
  • src/routes/messages.rs: apply_mention_counts increments the per-channel counter for each mentioned non-author after message creation (both JSON and multipart paths).
  • src/db/read_states.rs + src/routes/read_states.rs: space_id threaded through UnreadChannel and the REST payload; targeted read_state.update broadcast on ack (carries no space_id, so it is not muted-channel-suppressed).

Deliberately out of scope (follow-ups)

  • @everyone/@here currently set the message flag only; they do not bulk-increment every member's counter (avoids a large-space write amplification footgun) and are not yet gated behind a mention-everyone permission.

Test plan

  • cargo test — 122 passing (incl. 4 new mention-parser tests)
  • Manual: send @user message, verify mention_count increments and persists across reconnect
  • Manual: ack on one session, confirm read_state.update clears badge on another session

🤖 Generated with Claude Code

Parse @everyone/@here and @username mentions server-side, resolve handles
to space members, and persist mention_everyone + mentions on each message.
Increment a durable per-channel mention counter for each mentioned member
so unread badges survive restarts.

Add space_id to the unread payload (READY + REST) so multi-server clients
can route notifications to the right space. Broadcast a targeted
read_state.update on ack so reading on one device clears the badge on the
user's other sessions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant