Repository navigation
feat: cap the leaderboard at the department's top 50 - #22
Merged
Merged
Conversation
The leaderboard read every note in its department and sorted them in memory. Scoping it to one department already cut that by roughly the number of departments, but it is still one document read per note in the department every time the tab opens, and the sort runs in the listener callback on the main thread. Firestore now does both: orderBy(ratingSum) descending, limit 50. The client-side sortedByDescending goes away, and the query needs a composite index on department + ratingSum, added alongside the feed's. Capped rather than paged, and worth being explicit about why. A leaderboard is a "top N" view by nature; paging one out to rank 300 is machinery for a question nobody asks. It is also not an access restriction — every note stays reachable through the feed, which is the path to the content. This screen ranks it. LeaderboardAdapter derives each rank from list position, which assumed a sorted list. That assumption is now held by the query rather than by a call in the repository, so the comment says where it comes from. Not verified here: the index and the query behind it. The fakes stop at the repository interface and this machine has no credentials for a live project — the gap the README already records for every Firebase repository. Android suite: 114 tests, unchanged, all passing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The leaderboard read every note in its department and sorted them in memory. Scoping it to one department already cut that by roughly the number of departments, but it is still one document read per note every time the tab opens — and the sort runs in the listener callback, on the main thread.
Firestore now does both:
orderBy(ratingSum)descending,limit(50). The client-sidesortedByDescendinggoes away.Capped rather than paged
A leaderboard is a "top N" view by nature; paging one out to rank 300 is machinery for a question nobody asks.
It is also not an access restriction — every note stays reachable through the feed, which is the path to the content. This screen ranks it.
New index
department+ratingSum(descending), added tofirestore.indexes.jsonalongside the feed's. Without it the query fails withFAILED_PRECONDITIONand the leaderboard never opens.One assumption made explicit
LeaderboardAdapterderives each rank from list position, which assumed a sorted list. That assumption is now held by the query rather than by a call in the repository, so the comment says where it comes from.Verification
Android suite: 114 tests, unchanged, all passing.
assembleDebugandlintDebugpass.Not verified here: the index and the query behind it. The fakes stop at the repository interface and this machine has no credentials for a live project — the gap the README already records for every Firebase repository.
🤖 Generated with Claude Code