Skip to content

fix(leaderboard): use competition ranks for all-time ties - #655

Merged
IvGolovach merged 1 commit into
junhoyeo:mainfrom
IvGolovach:codex/leaderboard-rank-ties-20260601
Jun 4, 2026
Merged

fix(leaderboard): use competition ranks for all-time ties#655
IvGolovach merged 1 commit into
junhoyeo:mainfrom
IvGolovach:codex/leaderboard-rank-ties-20260601

Conversation

@IvGolovach

@IvGolovach IvGolovach commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Preserve database-computed all-time ranks in leaderboard list responses instead of recalculating rank from page offset.
  • Use competition ranking for all-time ties across list, search, and embed rank queries.
  • Keep deterministic tie ordering for display while ensuring equal metric totals receive equal ranks.

Why

All-time leaderboard ties could display inconsistent ranks depending on whether the user was looking at the paginated list, search results, or embed/profile-adjacent rank data. The SQL already has the right place to compute stable rank semantics, so this change makes ranking authoritative at the query layer and avoids client-side offset recalculation that breaks ties.

Diff scope

  • packages/frontend/src/lib/leaderboard/getLeaderboard.ts: computes all-time ranks with SQL RANK() and preserves those ranks in list/search responses while keeping deterministic secondary ordering outside the rank expression.
  • packages/frontend/src/lib/embed/getUserEmbedStats.ts: computes embed rank windows on the selected metric only, so tied totals share a rank consistently.
  • packages/frontend/__tests__/lib/getLeaderboardAllTime.test.ts: adds coverage for competition ranks and tied list/search behavior.
  • packages/frontend/__tests__/lib/getUserEmbedStats.test.ts: adds coverage proving embed rank SQL does not include deterministic display tie-breakers inside the rank window.

Branch integrity

  • Base branch: main.
  • Validated base SHA: a86e688d620939d2c973c6d5625baa815ea223d7.
  • Ahead/behind: 0 behind / 1 ahead against origin/main.
  • Merge base: a86e688d620939d2c973c6d5625baa815ea223d7.
  • Fast-forward safety: origin/main is an ancestor of this branch.

Commit integrity

  • Introduced commit: 85bbd9767d87c7095852f6fe8448b691bb2a7d97 fix(leaderboard): use competition ranks for all-time ties.
  • The PR contains one logical change scoped to all-time leaderboard/embed tie rank semantics and regression coverage.
  • Ledger: not applicable - not required for this change family.
  • Version: not applicable - not required for this frontend runtime change.

Diff hygiene

  • git diff --name-status origin/main...HEAD: only leaderboard/embed rank logic and focused tests changed.
  • git diff --check origin/main...HEAD: PASS, no output.

Validation mode and proof

Mode 2 - narrow runtime change, because the diff changes focused frontend leaderboard/embed query semantics without touching auth, migrations, deployment tooling, or broader API contracts.

  • TDD red proof: bun x vitest run __tests__/lib/getLeaderboardAllTime.test.ts failed before the implementation because all-time list/search SQL lacked authoritative competition ranks and tied rows could receive offset-derived ranks.
  • TDD red proof: bun x vitest run __tests__/lib/getUserEmbedStats.test.ts failed before the implementation because embed rank windows included secondary tie-breakers in the rank expression.
  • bun x vitest run __tests__/lib/getLeaderboardAllTime.test.ts __tests__/lib/getLeaderboard.test.ts __tests__/lib/getUserEmbedStats.test.ts __tests__/api/usersProfile.test.ts: PASS, 4 files and 22 tests.
  • bun x eslint src/lib/leaderboard/getLeaderboard.ts src/lib/embed/getUserEmbedStats.ts __tests__/lib/getLeaderboardAllTime.test.ts __tests__/lib/getUserEmbedStats.test.ts: PASS, no output.
  • git diff --check origin/main...HEAD: PASS, no output.
  • Not run: full frontend test suite - not required for selected validation mode because targeted leaderboard, profile, and embed tests cover the changed rank semantics; required remote CI will run after the PR is opened.

Required remote gates

Pending - GitHub Actions, Vercel, and mergeability checks will run after the PR is opened.

Migration notes

Not applicable - no database migration changed.

Runtime safety

The change only alters rank calculation semantics for existing leaderboard/embed reads. It does not change stored usage data, submission totals, auth behavior, or write paths. Deterministic ordering remains in place for display stability, but it no longer changes the rank assigned to tied totals. No invariant regression introduced.

Documentation integrity

Not applicable - no docs, commands, or runbooks changed.

Rollback plan

Rollback: revert this PR. DB downgrade: not applicable. Data repair: not applicable. Operational caveats: reverting would restore inconsistent all-time tie ranks across leaderboard views.

Known residual risks

Remote CI and GitHub mergeability are pending until the PR is opened. This PR intentionally keeps existing deterministic display ordering, so users with tied totals can still appear in a stable order while sharing the same competition rank.


Summary by cubic

Fixes inconsistent all-time leaderboard ranks for ties by using competition ranking (RANK()) and returning the DB-computed rank. Ranks now match across list, search, and embeds while keeping stable display order.

  • Bug Fixes
    • Use SQL RANK() for all-time ranks in packages/frontend/src/lib/leaderboard/getLeaderboard.ts; keep secondary deterministic ordering outside the rank and return the DB rank instead of offset.
    • Compute embed ranks by the selected metric only in packages/frontend/src/lib/embed/getUserEmbedStats.ts so tied totals share the same rank.
    • Add tests for consistent competition ranks across list, search, and embed in packages/frontend/__tests__/lib/getLeaderboardAllTime.test.ts and packages/frontend/__tests__/lib/getUserEmbedStats.test.ts.

Written for commit 85bbd97. Summary will update on new commits.

Review in cubic

Validation
* Validation tier: Tier 2 - Narrow Runtime Change, focused frontend leaderboard/embed rank semantics.
* bun install --frozen-lockfile: PASS
* bun x vitest run __tests__/lib/getLeaderboardAllTime.test.ts __tests__/lib/getUserEmbedStats.test.ts: PASS, 10 tests
* bun x vitest run __tests__/lib/getLeaderboardAllTime.test.ts __tests__/lib/getLeaderboard.test.ts __tests__/lib/getUserEmbedStats.test.ts __tests__/api/usersProfile.test.ts: PASS, 22 tests
* bun x eslint src/lib/leaderboard/getLeaderboard.ts src/lib/embed/getUserEmbedStats.ts __tests__/lib/getLeaderboardAllTime.test.ts __tests__/lib/getUserEmbedStats.test.ts: PASS
* git diff --check: PASS
* git diff --cached --check: PASS
* Ledger: not applicable - not required for selected validation tier/change family.
* Version: not applicable - not required for selected validation tier/change family.
* Not run: full frontend test suite - not required for selected validation tier.

Rollback
* git revert HEAD
@vercel

vercel Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tokscale Ready Ready Preview, Comment Jun 1, 2026 4:09am

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

@IvGolovach
IvGolovach merged commit f564ede into junhoyeo:main Jun 4, 2026
7 checks passed
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.

2 participants