Context
Why this document exists
FR-24 (Daily Digest) cannot be scoped without a baseline map of what the platform already sends
The problem
- No existing documentation on which events trigger notifications
- Email and in-platform systems are separate and partially undocumented
- FR-24 requires knowing the full event map before designing a queue
- FR-16 (preferences UI) requires knowing all toggleable notification types
What we did
- Queried
/community/v1/notifications/preferences — 10 email toggles found
- Queried
/buddypress/v1/notifications — live notification types confirmed
- Queried
/buddypress/v1/components — active components verified
- Cross-referenced all platform interactions with notification paths
- All 6 developer questions answered (Q17-a through Q17-g)
Infrastructure
Two parallel notification systems
An event can trigger one, both, or neither — they are independent
In-platform notifications
🔔
- Bell icon counter in the nav
- Scrollable notification feed
- Endpoint:
buddypress/v1/notifications
- Confirmed types: group_updated, new_membership_request, friendship_accepted, like_post
Issue: group_updated fires for every admin backend action — 86 notifications stacked in test account. Bell noise is significant.
Email notifications
📧
- Triggered on event via BuddyPress hooks
- Controlled by
notification_* user meta keys
- 10 registered toggles — user can turn each on/off
- Welcome/reset emails use a separate code path (custom plugin)
Empty string "" in user meta = platform default = send. Confirmed by Lucas (Q17-a).
Infrastructure
10 email notification toggles (current)
Verified via GET /community/v1/notifications/preferences on the Coopers test account
| Preference key |
Plain-language meaning |
Default |
notification_activity_new_mention | Someone @-mentioned you in a post or comment ⚠ should be send | no ← fix |
notification_activity_new_reply | Someone replied to your activity | no |
notification_messages_new_message | You received a new direct message | send (default) |
notification_friends_friendship_request | You received a connection request | send (default) |
notification_friends_friendship_accepted | Your connection request was accepted | no |
notification_groups_invite | You were invited to a group | send (default) |
notification_groups_group_updated | A group you belong to was updated | send (default) |
notification_groups_admin_promotion | You were promoted to group admin | send (default) |
notification_groups_membership_request | A member requested to join your group | send (default) |
notification_membership_request_completed | Your group membership request was accepted/rejected | send (default) |
Empty string = system default = send. 6 of 10 keys are empty on test account — meaning those emails are being sent unless users have explicitly opted out. @mention key is currently "no" — must be changed to "" to enable by default. Action for Lucas.
Gap Analysis
Events with no confirmed email path
Platform fires these — but no email key exists
| Gap |
Priority |
Risk |
| Welcome / account created email — no preference key registered |
P0 |
First impression; delay implies failure |
| Platform invitation email — no preference key registered |
P0 |
Acquisition moment — must always send |
| Password reset / security emails — no preference key (must be non-opt-out) |
P0 |
Critical — delay is unacceptable |
| @mention via custom endpoint — key exists but separate code path may bypass it |
P1 |
Confirm with Lucas that wiring is correct |
| Connection rejection — no notification at all (intentional?) |
P1 |
Confirmed intentionally silent by Lucas ✓ |
| Backend group member addition — bell fires for all members (noise), no email |
P2 |
Bell noise for all members. No email spam risk. FR5.4 |
| Post like — in-platform bell fires, no email key exists |
P3 |
Low urgency. Confirmed: no email today (Q17-b ✓) |
P0 items (welcome, invite, reset) use a separate code path — confirmed by Lucas: wp-community-additional-functionality/includes/classes/email/email.php. They will not be affected by digest logic.
Strategy
Four delivery modes
Urgency and relationship determine which mode an event receives
Instant
Sent within seconds
Email fires immediately on event. Reserved for time-sensitive, personal, or trust-critical moments.
Batched
Per conversation thread
Multiple events in the same thread grouped into one email, sent ~1h after first trigger. Reduces email storm from busy threads.
Digest
Once daily
Accumulated over 24h, sent once daily. Skipped if nothing queued. Reduces email volume while keeping users informed.
Suppressed
In-platform only
No email ever sent. Event shows in the bell notification feed only. For high-volume, low-urgency signals.
Note on timezone: Digest delivery at "8am user local time" is not possible — timezone is not stored per user (Q17-e ✓). Digest must use a fixed server time until timezone storage is implemented.
Strategy — Transactional
Transactional emails — always instant, never opt-out
These are not notifications — they are security and onboarding critical paths
| Event | Mode |
| Welcome / account created | Transactional |
| Platform invitation | Transactional |
| Password reset request | Transactional |
| Account verification | Transactional |
Must not appear in the digest. Must not be suppressible by notification settings. Must always send, even if the user has opted out of all notifications.
Already isolated. Lucas confirmed these use a separate code path (email.php in the custom plugin) — they are not wired through the notification_* user meta system.
Strategy — Mapping
Notification delivery by event type
Instant for personal urgency · Digest for admin and informational · Suppressed for noise
Instant — high personal urgency
| Event | Mode |
| New direct message | Instant |
| Connection request (to Mentor / Area Manager) | Instant |
| First comment on your post | Instant |
| @mention in post or comment 🔔 bell + email — confirm with Lucas | Instant |
| Promoted to group admin | Instant |
Suppressed — in-platform only
| Event | Mode |
| Post likes | Suppressed |
| Profile updates (others) | Suppressed |
| Group creation / joins by others | Suppressed |
| Connection request rejected | Silent |
Digest — low urgency, batching friendly
| Event | Mode |
| Connection request (to Member / Recipient) | Digest |
| Connection request accepted | Digest |
| Group membership request (admin) | Digest |
| Group membership approved/rejected | Digest |
| Group invite | Digest |
| Group details updated | Digest |
| 2nd+ comments on same post | Batched |
Discovery — weekly cadence
| Event | Mode |
| "People you may know" suggestions | Weekly |
Strategy — Roles
Delivery view by role
Area Managers and Mentors receive the most volume — digest is especially valuable for them
| Role |
Key instant events |
Digest appropriate? |
| Candidate / Member |
Welcome, DMs, @mentions, first comment on post |
Yes — low volume |
| Recipient (MED-EL User) |
Welcome, DMs, @mentions, first comment, connection requests |
Yes — moderate volume |
| Mentor |
All of the above + connection requests from Candidates (→ instant) |
Mostly yes — Candidate requests excepted |
| Area Manager |
All of the above + group membership requests |
Strongly yes — high volume |
| Super Admin |
System-level — MED-EL to define separately |
N/A |
Key insight: Area Managers managing multiple area groups are at the highest risk of notification overload. Digest is the most impactful feature for their experience.
Implementation
FR-24 — Daily Digest: what backend needs to build
Seven components — all required before digest can go live
| # | Component |
| 1 | Queue system — digest events write to queue instead of firing mailer directly |
| 2 | Cron job — daily sweep of queue per user; skip users with 0 events |
| 3 | Email template — one "Daily Summary" email with conditional sections |
| 4 | Transactional separation — welcome/reset/verification bypass queue entirely |
| 5 | Instant exceptions — DMs, @mentions, first comments, Candidate→Mentor requests bypass queue |
| 6 | Timezone fallback — fixed server time until per-user timezone is implemented |
| 7 | User preference toggle — "Daily Digest: on/off" in Account Settings (default: on) |
New preference keys needed
notification_digest_enabled — yes/no, default yes
notification_digest_time — HH:MM in server time, default 08:00 (optional until timezone is available)
FR-16 (preferences UI) can be scoped in parallel — it needs the full toggle list from this audit to build the settings screen. Both features share the same foundation.
Status
All dev questions resolved
Q17-a through Q17-g — confirmed with Lucas via API and code review
| # |
Question |
Status |
| Q17-a | What does empty "" mean in notification meta? | ✓ Answered |
| Q17-b | Is like_post sending an email today? | ✓ Answered |
| Q17-c | Where is the welcome/registration email code path? | ✓ Answered |
| Q17-d | Does /comments/mention use the standard mention key? | ✓ Answered |
| Q17-e | Is timezone stored per user? | ✓ Answered |
| Q17-f | Is connection rejection intentionally silent? | ✓ Answered |
| Q17-g | Which hook fires when admin adds user to group from WP backend? | ✓ Answered |
This audit is complete. FR-24 and FR-16 can now be scoped and briefed to Lucas. No blocking questions remain on the notification side.