feat(notifications): keyword / highlight-word notifications (LC-304) #330
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-304-keyword-notifications"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Per-user highlight words: when a message contains one of your words, it is treated like an @mention (sidebar badge, row highlight, inbox/activity, and opt-in email/push), without anyone @-mentioning you.
Approach
Reuses the mention pipeline end-to-end. A new
resolve_targets_for_bodywrapper resolves@tokensthen appends members whose highlight word matches the body, deduped, beforereconcile_mentions. All 5 reconcile sites (post / edit / webhook / email-ingress / bridge) call it, so a keyword match becomes a normalmentionsrow and every downstream surface works with no change.Changes
server/migrations/auth/0027_notification_keywords.sql(new):notification_keywords(user_id, word, ...).server/src/db/notification_keywords.rs(new): list / all / add / remove / count; cap constants (25 words, 50 chars).server/src/routes/room.rs:resolve_targets_for_body+append_keyword_targets+keyword_matches_body(case-insensitive, word-bounded); the 5 sites swapped to the wrapper (4 new-message sites gate on!targets.is_empty(), edit stays unconditional so removals reconcile). Matching skips the author, non-members, and already-mentioned users; the member set is resolved only after a word hits the body.server/src/routes/settings.rs+views/settings.rs+partials/keyword_list.html: a "Highlight words" chip list under Notifications (POST /settings/keywords,POST /settings/keywords/delete, each re-rendering the fragment).server/locales/{en,es}/common.ftl: new UI strings.Notification eligibility reuses the existing per-mention opt-in; no new pref column, no new badge/highlight plumbing.
Testing
just check,just fmt,just test,just test-saasall pass.db_notification_keywords.rs(add/list/remove/idempotent/all) androutes_keyword_mentions.rs(member match inserts a mention; case-insensitive; word-boundary; author no self-notify; non-member not targeted).Not operator-visible (new table is internal; no env/config/contract change).
Each user can configure highlight words in Settings; when a posted or edited message in a room they can see contains one of their words, they get the same treatment as an @mention: a raised sidebar badge, a highlighted message row, an inbox/activity entry, and (if opted in) an email/push notification. The feature reuses the mention pipeline end-to-end. A new resolve_targets_for_body wrapper resolves @tokens (as before) and then appends members whose highlight word matches the body, deduped, before reconcile_mentions. All five reconcile sites (post, edit, webhook, email-ingress, bridge) call the wrapper, so a keyword match becomes a normal mentions row and every downstream surface works unchanged. Matching is case-insensitive and word-bounded ("deploy" matches "deploy" / "deploy!" but not "deployment"); the author never matches their own message; only room members are targeted (no access leak); the member set is resolved only after a word actually hits the body, so the common no-match path stays cheap. Words live in a new auth.db notification_keywords table (capped 25 per user, 50 chars each), managed via a chip list under Settings > Notifications (add / remove are their own HTMX posts that re-render the list fragment). Notification eligibility reuses the existing per-mention opt-in; no new pref column. #LC-304 #LC-305 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>