Skip to content

Story #2576 :: Task: Wire the Library Authoring achievement to library authors - #2577

Open
herzog0 wants to merge 4 commits into
teo/2541-achievement-ingestionfrom
teo/2541-source-library-authoring
Open

Story #2576 :: Task: Wire the Library Authoring achievement to library authors#2577
herzog0 wants to merge 4 commits into
teo/2541-achievement-ingestionfrom
teo/2541-source-library-authoring

Conversation

@herzog0

@herzog0 herzog0 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Issue: #2576

Summary & Context

Wires the Library Authoring achievement to its source: Library.authors. One grant per
library a member authored, which is what the badge's thresholds (1 / 2 / 4 / 7 / 14) count.

First of four one-source-per-PR changes. This PR assumes the engine is already reviewed in #2573.

  • Figma link: n/a
  • Link to components/page: n/a

Changes

  • _iter_library_authoring yields (user, library) for every authorship, prefetching authors so
    the walk is one query per 500 libraries rather than one per library.
  • Registered in BACKFILL_ITERATORS, which is also what adds library-authoring to the
    --source choices.
  • test_iter_library_authoring (the iterator) and test_backfill_library_authoring (end to end:
    source data in, badge out).
  • Two engine tests that only become meaningful with a second source arrive here:
    test_backfill_skips_an_unseeded_source_on_a_full_run (one missing catalogue row must not cost
    the other sources their backfill) and test_reconcile_scopes_to_the_named_source (--source
    must not prune a source it was not given).

‼️ Risks & Considerations ‼️

  • The grain is per library, not per version - library-versioning is the per-version
    one. A library with 40 releases is one authoring grant.
  • Authorship comes from the upstream libraries.json, which is known to be dirty: 78
    LibraryVersion rows carry a placeholder 'various ' author. That is an upstream data problem
    tracked separately; reconciliation will move the grants once it is fixed, which is exactly what
    the two-way sync exists for.
  • Nothing runs automatically yet: the scheduled sweep is the release-pipeline PR.

Screenshots

n/a - no UI.

Peer-review testing steps

All of it is doable from the admin. Setup: just load_production_data, just migrate, and docker compose up so a worker is
there to pick the buttons up.

  1. The source is wired. /admin/badges/badge/ - the Library Author row's Automatic column
    is now a tick and its ladder reads 1 / 2 / 4 / 7 / 14. On the base branch that tick is a cross.

  2. Give yourself an authorship. /admin/libraries/library/ -> pick a library with a long release
    history -> add your own user to Authors -> Save.

  3. Backfill from the admin. /admin/badges/userachievement/ -> Backfill achievements, with
    Source set to Library Authoring. The status line finishes in place; no reload needed.

  4. The grant points at the right row. Filter that changelist by Achievement: Library Authoring.
    Your row's Source column links to the library you edited - click through and confirm you are in
    its Authors list. /admin/badges/userbadge/ now shows you holding Library Author / Bronze,
    because the ladder starts at 1.

  5. The grain is per library, not per version. /admin/libraries/libraryversion/, filtered to that
    same library, lists many versions. You still have exactly one Library Authoring grant. Click
    your name from either badge changelist for the per-member page: it should read one valid grant and
    1 to go to Silver.

  6. Re-running adds nothing. Press Backfill achievements on the same source again, then open
    /admin/badges/achievementsyncrun/: two library-authoring rows, the second with Added 0, both
    naming you under Triggered by.

  7. A backfill cannot take it away. Remove yourself from the library's Authors and press
    Backfill again - the grant and the badge are still there. That is the additive command behaving
    as designed, and the reason the release pipeline is allowed to run it unattended.

  8. A reconcile can. Press Reconcile achievements with Source on Library Authoring. The
    preview reports one removal before anything happens; Apply, and the grant is deleted while the Bronze
    row on /admin/badges/userbadge/ is revoked rather than removed - badges keep their history. Its
    Revocation notes name the run, its Count at revocation reads 0, and the run row on
    /admin/badges/achievementsyncrun/ shows Removed 1.

  9. Scoping. Redo steps 2-3, remove yourself from Authors again, then press Reconcile with
    Source left on Code Commits. The commit run must leave your now-unsupported authoring grant
    alone; only a run pointed at Library Authoring or All sources may prune it.

On a database with no other library authorship, step 8 refuses rather than deletes: the preview says
nothing can be removed, does not offer Apply, and explains that a source yielding nothing at all is more
likely a broken import than a genuinely empty one. Add a second authorship and it proceeds. That guard is
worth seeing once, since it is the only thing standing between a failed upstream import and a mass
revocation.

Self-review Checklist

  • Tag at least one team member from each team to review this PR
  • Link this PR to the related GitHub Project ticket

Backend

  • Black + Ruff clean
  • No new models or migrations
  • Full suite green: 1334 passed / 43 skipped

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c034112-ddc4-48f9-8482-e8bf8c261b4e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@herzog0 herzog0 linked an issue Aug 5, 2026 that may be closed by this pull request
8 tasks
@julhoang
julhoang self-requested a review August 11, 2026 00:08
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from 7004d7a to e771045 Compare August 11, 2026 15:16
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from e771045 to 1ad2f26 Compare August 11, 2026 16:47
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from 1ad2f26 to 49cd64c Compare August 11, 2026 17:13
Comment thread badges/sources.py Outdated
Comment on lines +28 to +30
for library in Library.objects.prefetch_related("authors").iterator(chunk_size=500):
for user in library.authors.all():
yield user, library

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

1/ For this query, we're currently counting sub-libraries, and I wanted to double-check whether that's intentional.

There's a constant called SUB_LIBRARIES that lists 25 sub-libraries, which are skipped when Admin generates library reports. If we applied the same filter here (Library.objects.exclude(key__in=SUB_LIBRARIES)), 41 authors would drop a tier.

I think it comes down to a product decision: do we want sub-library authorship counted alongside the main library, or only once? Personally I'm fine either paths, I just want to make sure it's a deliberate choice!

2/ Should we also filter out deleted users here and everywhere we compute these badges and achievement? 🤔

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi @herzog0 , I wanna come back to point 2 here since I'm seeing a bit of downstream effect – I think that we should skip computing achievements and badge granting for deleted users and also unclaimed users (e.g. @example.com accounts). Granted we can just hide the badge icons in the FE, but I feel like stopping them at the BE source is much better. Does this seem reasonable to you?

@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from 49cd64c to ff85cf5 Compare August 11, 2026 17:59
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from ff85cf5 to 52dc86d Compare August 13, 2026 14:44
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch 2 times, most recently from 2d84be0 to b314bd1 Compare August 14, 2026 19:57
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch 6 times, most recently from 390baed to d6592bf Compare August 18, 2026 14:28

@julhoang julhoang left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks great to me, thanks @herzog0 !

@javiercoronadonarvaez javiercoronadonarvaez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from d6592bf to 6d202f5 Compare August 21, 2026 14:48
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from 6d202f5 to 3a6471b Compare August 24, 2026 13:40
@herzog0
herzog0 force-pushed the teo/2541-source-library-authoring branch from 3a6471b to f9c5b66 Compare August 24, 2026 19:22
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.

Task: Wire the Library Authoring achievement to library authors

3 participants