- Shipped
- September 9, 2026 at 4:30 AM UTC
- Author
- Kamo
- Commit
- fdf9166
The leaderboard grouped every member holding an achievement row, so a member whose role denies VIEW_ACHIEVEMENTS — who cannot open the page, the trophy or the widget — was still published to colleagues by points and rank. Reported against kamocrm, where the "Members" role has rights 304-310 set to denied and one member had accumulated a LOITERING row off the session keepalive. The board now filters on VIEW_ACHIEVEMENTS in SQL. Doing it there rather than after the group-by keeps totalRanked honest and stops the query reading totals it would only discard. Filtering rather than deleting the stray rows is what makes it retroactive without deciding, on the member's behalf, that the time they spent never happened: the row waits for the day their organization grants the right. VIEW_ACHIEVEMENTS and not VIEW_ACHIEVEMENT_LEADERBOARD — the first is taking part, the second is being allowed to look, and a member who earns but may not read the board still belongs on it. existsByMemberIdAndRight is added for the award gate in SecurityService, which must ask on every write and holds no session to read the answer off; it rides the existing IX_MRA_MEMBER_RIGHT.