Files
Bannon Tanner f1c986eaf2 FIX: Clean up stranded PM notifications when access is revoked (#42418)
The notification list Guardian-filters inaccessible topics, but the
unread-badge counter (raw SQL COUNT) does not. When a user lost PM
access, stale notification rows kept inflating the badge — the menu
showed nothing new, but the count wouldn't clear.

Discourse already has `Jobs::DeleteInaccessibleNotifications` (used by
`TopicConverter` and `PostMover`). This PR:

- Wires it into `Topic#remove_allowed_user` (inline, Guardian-guarded so
users with group-based access are preserved),
`Topic#remove_allowed_group`, and `GroupManager#remove/bulk_remove`.
- Narrows the `GroupManager` enqueue to topics where removed users
actually have notifications, and passes `user_ids` so the job scopes its
work — prevents fan-out when a large group sits on many PMs.
- Rewrites the job: Guardian-check once per user (not per notification),
single batched `delete_all`, one publish_notifications_state` per user.
- Adds a post-deploy backfill migration to clean up existing orphaned PM
notifications.

Category-permission, trust-level, and direct `GroupUser#destroy` paths
(SSO, auto-groups) are left as follow-ups.


[`/t/311995`](https://meta.discourse.org/t/cant-clear-unread-notification-after-being-removed-from-a-pm/311995)

[`/t/384961`](https://meta.discourse.org/t/sticky-unread-reply-notification/384961)
2026-08-12 12:50:00 -05:00
..