Add sticky current-user leaderboard row#182
Conversation
|
@shriya53 is attempting to deploy a commit to the codersogs-3057's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Hi @Ayush-Patel-56 , Could you please add the Thank you! |
Siddhartha-singh01
left a comment
There was a problem hiding this comment.
Thanks for the feature @shriya53 the sticky "YOUR RANK" idea is good, but there
are two critical issues with the implementation that block merge.
1. Critical: cache key isn't user-scoped, so users see each other's rank.
The cache key is leaderboard:${scope}:${scopeId}:${limit} shared across users.
But the cached response now contains currentUserRank, which is user-specific.
Concretely: User A loads the page → A's rank gets cached. User B loads → cache hit
→ B sees A's handle, avatar, XP, rank as B's own "YOUR RANK" card. That's a real
privacy leak.
Fix: either include user.id in the cache key, or (cleaner) cache only the shared
entries and compute currentUserRank per-request outside the cache:
const cached = await cacheGet<LeaderboardEntry[]>(cacheKey);
let entries: LeaderboardEntry[];
if (cached) { entries = cached; }
else { entries = /* compute */; await cacheSet(cacheKey, entries, TTL); }
const currentUserRank = await computeCurrentUserRank(db, user.id, scope, scopeId);
return ok({ entries, currentUserRank });2. Critical: loads every profile in the DB to find one user's rank.
select * from profiles order by xp desc with no LIMIT pulls every row, then does
findIndex in JS. At 1k users that's 1k rows transferred per request; it doesn't
scale. The DB can do this in one row:
SELECT count(*) + 1 AS rank
FROM profiles
WHERE xp > (SELECT xp FROM profiles WHERE id = $1);Or use ROW_NUMBER() OVER (ORDER BY xp DESC). Either returns exactly one row.
3. The current-user-rank query ignores scope and scopeId.
It always queries the global profiles table so a user viewing the "Python"
leaderboard sees their global rank in the "YOUR RANK" card, not their Python rank.
The sticky row will mismatch the displayed list. The rank query needs to apply the
same scope filters as the entries query.
Minor: await getServerSupabase() that function is synchronous, the await is
unnecessary. And a unit test for the currentUserRank logic (the existing
recommendations.test.ts is a good template) would be nice.
Once 1, 2, and 3 are fixed, this is ready to merge. The feature itself is welcome.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary
Adds a persistent “YOUR RANK” section to leaderboard views so users can always see their own ranking and XP even when they are outside the visible leaderboard range.
Also improves leaderboard data handling by extending the leaderboard action to return current-user ranking data separately instead of relying only on visible leaderboard entries.
Type of Change
Related Issue
Closes #78
What was changed?
Checklist