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
- 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.
- 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.
- Tests: the iterator itself, plus one end-to-end case - source data in, badge out.
- 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
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.
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.authorsis the library-levelrelation, 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
(member, library)for every authorship, prefetching authors so the walk costs onequery per batch of libraries rather than one per library.
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.
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
Acceptance criteria
Risks & considerations
Authorship comes from the upstream
libraries.json, which is known to be dirty: 78LibraryVersionrowscarry 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.