Skip to content

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

Description

@herzog0

Context

First of four one-source-per-ticket changes. The engine and the admin buttons that drive it come from
earlier tickets; this one adds a single source iterator - the function the engine walks, yielding one
(member, thing) pair for every grant that should exist.

Three more terms from that earlier work are used below, because the tests turn on them. A backfill walks
a source and grants whatever is missing, never removing anything, which is what makes it safe to run
unattended. A reconcile walks the same source in both directions and also removes grants the source no
longer supports. Either can be pointed at one named source or run across all of them. The catalogue is
the set of achievement and badge definitions seeded into the database, which the engine needs a row in
before it can grant anything.

The only real question here is whether this is the right source at the right grain, because Boost holds
library authorship at two levels and the badge counts one of them. Library.authors is the library-level
relation, and this achievement counts libraries authored, which is what its thresholds (1 / 2 / 4 / 7 / 14)
are scaled for. A library with forty releases is one grant.

That distinction is the whole reason these sources get separate tickets rather than one: two other
achievements read closely related data at a different grain, and confusing them produces a member holding
diamond for one library.

Scope

  1. An iterator yielding (member, library) for every authorship, prefetching authors so the walk costs one
    query per batch of libraries rather than one per library.
  2. Register it against its achievement, which is also what makes it selectable wherever a single source can
    be named - both commands and the admin buttons. That list must be derived from what is actually
    registered rather than restated somewhere it can drift.
  3. Tests: the iterator itself, plus one end-to-end case - source data in, badge out.
  4. Now that a second source exists, add the two engine tests that only become meaningful with more than
    one: a run across all sources must not lose the others their grants because one achievement is missing
    from the catalogue, and a run pointed at one source must leave every other source's grants alone.

Out of scope

  • Per-version authorship. That is the Library Versioning achievement, a separate ticket.
  • Maintainership. Separate ticket.
  • Fixing the upstream authorship data (see below).
  • Running any of this on a schedule. Separate ticket.

Acceptance criteria

  • The iterator yields one pair per (member, library) authorship
  • The walk does not issue a query per library
  • The new source is selectable in the commands and the admin without the list being restated anywhere
  • A backfill of this source alone produces the expected grants and awards the badge
  • Reconciling immediately afterwards moves nothing
  • An achievement missing from the catalogue does not stop a run across all sources
  • A run pointed at one source leaves every other source's grants alone
  • Full suite green, pre-commit clean

Risks & considerations

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 moves the grants once it is fixed, which is exactly what the two-way sync is for.

Nothing runs automatically after this ticket - backfilling for real is the release-pipeline ticket.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions