Skip to content

Exclude private players from rankings#130

Merged
JanMikes merged 1 commit into
mainfrom
exclude-private-players-from-rankings
Apr 21, 2026
Merged

Exclude private players from rankings#130
JanMikes merged 1 commit into
mainfrom
exclude-private-players-from-rankings

Conversation

@JanMikes
Copy link
Copy Markdown
Member

@JanMikes JanMikes commented Apr 21, 2026

Summary

The result image (cached PNG, shared on social media), the post-submit recap page, the player profile, the compare-players page, and the global pairs/groups ladders all counted private puzzlers in their rank totals and positions. This PR makes the ranking SQL ignore private players, with one exception: the subject of the ranking is always included so a private user still sees their own rank on their own pages.

  • `GetRanking` (used by recap, result image, player profile, comparison, `PlayerSolvedPuzzles` / `MostSolvedPuzzles` / `RecentActivity`): JOIN `player` in the `BestTimes` CTE and require `(is_private = false OR id = :playerId)`. The subject (`:playerId`) is exactly the player whose rank is shown — no new parameter needed.
  • `GetFastestPairs` / `GetFastestGroups` (global `LadderTable`): `HAVING bool_or(p.is_private = false)` on the puzzlers aggregate, so a team is shown only if at least one member is public — matching `PuzzlesSorter::filterOutPrivateProfiles` for an anonymous viewer and the existing solo `GetFastestPlayers` behavior.
  • `GetPlayerRatingRanking`: same subject exception in `playerPosition` and `allForPlayer` so a private player can see their own MSP-Rating; `ranking()`/`totalCount()`/`distinctCountries()` (global views) are unchanged and still hide private players entirely.

`PuzzleTimes` already filters per-viewer via `PuzzlesSorter::filterOutPrivateProfiles($grouped, $loggedPlayerId)` (with the logged-user exception), so its query stays untouched.

Test plan

New / extended PHPUnit tests cover:

  • `GetRankingTest`: public subject excludes a private peer from rank/total; private subject sees self in own rank; non-solver returns null.
  • `GetFastestPairsTest`: a mixed (one public + one private) team is still shown; flipping the public puzzler to private hides both fixture pair entries.
  • `GetPlayerRatingRankingPrivacyTest`: seeded `PlayerElo` rows; `ranking()`/`totalCount()` drop a now-private player; `playerPosition()` for that private subject still returns their rank; `allForPlayer()` for the private subject includes self in rank/total; other public peers' positions renumber correctly when a peer is hidden.

Manual smoke (post-merge):

  • As a public solver on a puzzle that has a faster private peer, open `/cas-pridan/{timeId}` — "Rank X of Y" should drop by one (or more) vs. before. The matching `/result-image/{timeId}` PNG agrees on next regeneration (existing cached PNGs persist for up to 1 month at `players/{playerId}/results/{timeId}.png`).
  • Log in as a private user, submit a time, open the recap — own rank visible with self counted.
  • `/ladder` pairs/groups tabs no longer show fully-private teams.
  • `/msp-rating` as a private logged-in user shows the personal position chip.

🤖 Generated with Claude Code

Result image, recap, profile and ladder rankings counted private
puzzlers in the totals and positions. Filter them out across the
ranking SQL, with one exception: the subject of the ranking is always
included so a private player still sees their own rank on their own
pages.

- GetRanking: JOIN player and require (is_private = false OR id = subject)
  in both allForPlayer and ofPuzzleForPlayer
- GetFastestPairs / GetFastestGroups: HAVING bool_or(p.is_private = false)
  so the global ladder hides teams whose puzzlers are all private
- GetPlayerRatingRanking: same subject exception in playerPosition and
  allForPlayer; the global ranking()/totalCount()/distinctCountries are
  unchanged

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JanMikes JanMikes merged commit b43dd98 into main Apr 21, 2026
5 checks passed
@JanMikes JanMikes deleted the exclude-private-players-from-rankings branch April 21, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant