Skip to content

Fix builder leaderboard eligibility - #887

Merged
JoaquinBN merged 2 commits into
devfrom
JoaquinBN/fix-leaderboard-ranks
Jul 4, 2026
Merged

Fix builder leaderboard eligibility#887
JoaquinBN merged 2 commits into
devfrom
JoaquinBN/fix-leaderboard-ranks

Conversation

@JoaquinBN

@JoaquinBN JoaquinBN commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Show builders in leaderboard and profile ranking surfaces only after an accepted substantive Builder submission.
  • Exclude builder welcome, simple builder, GitHub-link markers, and the boilerplate-star task from Builder ranking eligibility and totals.
  • Keep the Builder journey role gate intact while making its point-free behavior explicit.

Summary by CodeRabbit

  • New Features

    • None
  • Bug Fixes

    • Builder leaderboard eligibility now relies on accepted submissions, improving who appears in builder rankings.
    • Builder journey social tasks (including the boilerplate GitHub-star) no longer contribute to builder leaderboard points.
    • Builder user stats now exclude the builder journey star-task from totals and counts.
    • Leaderboard recalculation now applies the same builder point exclusion rules consistently.
  • Tests

    • Added/expanded coverage for builder ranking eligibility and builder-journey exclusions across endpoints and recalculations.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Builder ranking now excludes configured builder-journey contribution and social-task slugs, and builder eligibility uses accepted SubmittedContribution records. Related tests and docstrings were updated to match the new scoring and lookup behavior.

Changes

Builder Ranking Exclusion and Eligibility

Layer / File(s) Summary
Ranking exclusions in scoring and recalculation
backend/leaderboard/models.py
Adds Builder exclusion slug lists and applies them in category scoring, social-task scoring, and full leaderboard recalculation.
Submission eligibility and stats filtering
backend/leaderboard/views.py, backend/users/views.py, backend/users/tests/test_builder_journey.py
Replaces builder eligibility checks with accepted SubmittedContribution queries, excludes builder-journey slugs from per-user stats, and updates builder journey docstrings.
Social-task leaderboard exclusions
backend/social_tasks/tests/test_leaderboard_integration.py
Adds integration tests that create the builder-journey GitHub-star task and assert its completions do not affect Builder category points or recalculation.
Builder eligibility and stats tests
backend/leaderboard/tests/test_stats.py
Reworks builder leaderboard lookup coverage around accepted submissions and adds user-stats coverage for excluding the builder-journey star task.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LeaderboardViewSet
  participant SubmittedContribution
  participant LeaderboardEntry
  LeaderboardViewSet->>SubmittedContribution: _builder_ranking_submissions(state=accepted)
  SubmittedContribution-->>LeaderboardViewSet: eligible_builder_submissions
  LeaderboardViewSet->>LeaderboardEntry: filter via Exists(eligible_builder_submissions)
  LeaderboardEntry-->>LeaderboardViewSet: builder leaderboard rows
Loading

Possibly related PRs

  • genlayer-foundation/points#835: Both PRs modify backend/leaderboard/views.py's builder leaderboard eligibility logic using Exists subqueries and excluded slug/type constants, with related eligibility tests.
  • genlayer-foundation/points#848: Both PRs change builder-related stats and gating in backend/leaderboard/views.py, including user-stats payload filtering tied to builder ranking rules.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adjusting builder leaderboard eligibility and ranking behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch JoaquinBN/fix-leaderboard-ranks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/leaderboard/models.py`:
- Around line 862-866: The builder contribution aggregation in the leaderboard
logic is still counting all contributions with task category builder, which lets
excluded builder slugs inflate total_points. Update the builder total
calculation in the contribution loop that uses stc['task__category__slug'] and
stc['points_awarded'] so it also skips the same excluded slugs used for builder
eligibility, or refactor to reuse a shared exclusion list. Make sure the guard
is aligned with the existing BUILDER_RANKING_EXCLUDED_SOCIAL_TASK_SLUGS check
and the surrounding leaderboard totals logic in models.py.

In `@backend/leaderboard/tests/test_stats.py`:
- Line 362: The test method
test_builder_lookup_uses_accepted_submission_ranking_eligibility is too large
and triggers the statement-count limit, so split its scenario coverage into
smaller tests. Refactor the existing logic into separate parametrized cases or
helper-driven tests for each variant (welcome-only, simple-only,
github-link-only, contribution-only, accepted) while keeping the shared setup in
reusable helpers so the behavior remains covered without one monolithic test.
- Around line 605-633: The leaderboard expectations in this test are outdated:
the builder entries returned by the relevant lookups are the two accepted
non-excluded submissions with stored ranks 4 and 5. Update the assertions in
test_stats.py around the builder lookup checks so the list response rank
sequence matches [4, 5], and adjust the non_submittable_user-related rank
expectation to 4 in the same test block.

In `@backend/social_tasks/tests/test_leaderboard_integration.py`:
- Around line 55-65: The builder-journey SocialTask setup is duplicated across
multiple tests, so extract the repeated SocialTask.objects.update_or_create
block into a shared helper or fixture and reuse it in the leaderboard
integration tests. Keep the helper centered around the existing builder_journey
task creation logic in test_leaderboard_integration.py, using
settings.BUILDER_JOURNEY_TASK_SLUG and the common defaults so the field list
stays consistent and only one place needs updates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2ddc5e75-ec2e-4ab9-a339-1570ca8f0b5a

📥 Commits

Reviewing files that changed from the base of the PR and between 549c731 and e5cad0e.

📒 Files selected for processing (6)
  • backend/leaderboard/models.py
  • backend/leaderboard/tests/test_stats.py
  • backend/leaderboard/views.py
  • backend/social_tasks/tests/test_leaderboard_integration.py
  • backend/users/tests/test_builder_journey.py
  • backend/users/views.py

Comment thread backend/leaderboard/models.py
self.assertEqual(response.data['total_points'], link_points)

def test_builder_lookup_uses_real_builder_ranking_eligibility(self):
def test_builder_lookup_uses_accepted_submission_ranking_eligibility(self):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Test method exceeds statement-count threshold (PLR0915).

76 statements in a single test hampers readability and debugging. Consider splitting per-variant scenarios (welcome-only, simple-only, github-link-only, contribution-only, accepted) into separate parametrized/helper-driven tests.

🧰 Tools
🪛 Ruff (0.15.20)

[warning] 362-362: Too many statements (76 > 50)

(PLR0915)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/leaderboard/tests/test_stats.py` at line 362, The test method
test_builder_lookup_uses_accepted_submission_ranking_eligibility is too large
and triggers the statement-count limit, so split its scenario coverage into
smaller tests. Refactor the existing logic into separate parametrized cases or
helper-driven tests for each variant (welcome-only, simple-only,
github-link-only, contribution-only, accepted) while keeping the shared setup in
reusable helpers so the behavior remains covered without one monolithic test.

Source: Linters/SAST tools

Comment thread backend/leaderboard/tests/test_stats.py Outdated
Comment thread backend/social_tasks/tests/test_leaderboard_integration.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/leaderboard/tests/test_stats.py (1)

502-543: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Missing direct lookup assertion for contribution_only_user.

_assert_builder_lookup_empty is called for role_only_user, welcome_only_user, simple_builder_user, and github_link_user, but not for contribution_only_user — the scenario of a raw Contribution without an accepted SubmittedContribution, which is central to this PR's eligibility fix. It's only indirectly checked via the aggregate list exclusion at line 535. Add a direct per-address lookup assertion to close the gap in case the address-scoped endpoint applies different filtering than the list endpoint.

✅ Proposed addition
         self._assert_builder_lookup_empty(role_only_user)
         self._assert_builder_lookup_empty(welcome_only_user)
         self._assert_builder_lookup_empty(simple_builder_user)
         self._assert_builder_lookup_empty(github_link_user)
+        self._assert_builder_lookup_empty(contribution_only_user)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/leaderboard/tests/test_stats.py` around lines 502 - 543, The builder
stats test is missing a direct address-scoped lookup check for
contribution_only_user, so add an explicit _assert_builder_lookup_empty call
alongside the existing role_only_user, welcome_only_user, simple_builder_user,
and github_link_user assertions in test_stats.py. Use the existing
_assert_builder_lookup_empty helper in the same test case to verify that
/api/v1/leaderboard/ with user_address for contribution_only_user also returns
no builder entry, covering the raw Contribution-only eligibility path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@backend/leaderboard/tests/test_stats.py`:
- Around line 502-543: The builder stats test is missing a direct address-scoped
lookup check for contribution_only_user, so add an explicit
_assert_builder_lookup_empty call alongside the existing role_only_user,
welcome_only_user, simple_builder_user, and github_link_user assertions in
test_stats.py. Use the existing _assert_builder_lookup_empty helper in the same
test case to verify that /api/v1/leaderboard/ with user_address for
contribution_only_user also returns no builder entry, covering the raw
Contribution-only eligibility path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3ae2f8d1-ff74-480d-a7fe-dceef1b631ea

📥 Commits

Reviewing files that changed from the base of the PR and between e5cad0e and 6d6e473.

📒 Files selected for processing (4)
  • backend/leaderboard/models.py
  • backend/leaderboard/tests/test_stats.py
  • backend/leaderboard/views.py
  • backend/social_tasks/tests/test_leaderboard_integration.py

@JoaquinBN
JoaquinBN merged commit 782b094 into dev Jul 4, 2026
3 checks passed
@JoaquinBN
JoaquinBN deleted the JoaquinBN/fix-leaderboard-ranks branch July 4, 2026 18:28
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