- Ya
- 28 Agosti 2026, 01:01 UTC
- Mwandishi
- Kamo
- Ahadi ya
- 04894ac
A notification kind belongs to an app — a lead callback is Leads, a meeting reminder is Meetings — but raise() asked only whether the member had muted it. So a member with no Leads app was still written a lead callback whenever somebody else's process raised one for them, and the site drew a filter and a mute switch for a kind they could never receive. Gated now by the two questions that gate the app's own door in the navigation: does the organisation have the app, and does this member hold the app's viewing right. Suppressed the way a mute is — not written, not published, not counted — rather than written and hidden, because a row nobody may see is a row that surfaces the day the app is switched on, dated last March. The app is never named twice. Each kind names a RoleRightType and the right carries its own ServiceType, so this rule and the one the site states in **************** cannot drift into disagreeing about which app a kind belongs to: neither of them says. Two queries at most whatever the size of the fan-out — one for the right across every recipient, one per distinct organisation for the app. NotificationAccessRepository lives here rather than in the shared library for the reason MessageListIndexRepository does: only the notification hub asks the question in this shape, and a shared-library release is a change to every service that depends on it. The organisation comes off each member's own rights row rather than off the request, because the request's organisation id is optional and a fan-out can cross organisations. Fail-closed on a materialised table: MEMBER_RIGHTS_APPLIED stale for a member means that member quietly stops being told things, which is quieter than the bug it replaces but harder to notice. Every suppression logs at debug with the member, the kind and the right that was missing.