Review: Admin blast endpoint /email/blast (re-review)
Verdict: READY
Re-review of board item #752 (forgejo_admin/basketball-api#295). Previous review:
review-752-2026-04-03 (NEEDS_REFINEMENT). Three items were raised; all three are now resolved.Previous Findings Resolution
- [x]
[SCOPE]arch-email note created —arch-emailexists in pal-e-docs with sections: Overview, Components, Layouts, Email Flow, Decisions. Traceability triangle complete. - [x]
[BODY]Explicit### Blockerssection added to issue body — clearly states "This ticket CANNOT be built until both upstream tickets are merged and deployed" with references to #293 and #294. - [x]
[LABEL]blocked-by:293andblocked-by:294labels added to board item #752. Uses Forgejo issue numbers (not board item IDs). Acceptable — issue numbers are the canonical reference.
Template Completeness
- [x] Type — Feature
- [x] Lineage — depends on MJML system + send_templated_email() tickets; supersedes board item #724
- [x] Repo — forgejo_admin/basketball-api
- [x] User Story — clear admin-wants-blast-endpoint story
- [x] Context — explains current hardcoded pattern, decision to genericize, query registry design
- [x] Blockers — explicit hard blocker section referencing #293 and #294
- [x] File Targets — specific create/modify/do-not-touch paths
- [x] Acceptance Criteria — 7 testable conditions
- [x] Test Expectations — 5 unit tests with run command
- [x] Constraints — query return shape, placeholder format, auth dependency, pattern matching
- [x] Checklist — PR opened, tests pass, no unrelated changes
- [x] Related — project link, arch note, superseded ticket, dependency tickets
Traceability
- [x] story:WS-S7 label — "As an admin, I want to send branded email announcements so that parent comms are professional and consistent"
- [x] story:WS-S7 note verified — found in project-westside-basketball user-stories section (Admin stories)
- [x] story:WS-S22 label — "As a parent, I want to receive clear email communications with action links so that I never miss a deadline"
- [x] story:WS-S22 note verified — found in project-westside-basketball user-stories section (Parent stories)
- [x] arch:email label — email architecture component
- [x] arch note verified —
arch-emailnote exists in pal-e-docs (project: westside-basketball). Sections: Overview, Components, Layouts, Email Flow, Decisions. - [x] Forgejo issue — forgejo_admin/basketball-api#295, open
File Targets
- [x]
src/basketball_api/services/email_queries.py— to create. Does not exist yet. Parent directoryservices/exists with 10 existing modules. Correct. - [x]
src/basketball_api/routes/admin.py— verified exists. Hasrequire_admindependency (line 48), existing email endpoints at/email/profile-reminder(line 438),/email/roster-export(line 487),/email/tryout-announcement(line 551), and/email/jersey-reminder(line 847). Good placement for new endpoint. - [x]
src/basketball_api/services/email.py— listed as NOT to touch. Confirmed: hasload_email_template()(line 1107). Correct boundary. - [x]
contract_tokencolumn — verified on Player model (models.pyline 232), unique constraint exists - [x]
contract_signed_atcolumn — verified on Player model (models.pyline 229) - [x]
EmailLogmodel — verified at models.py line 363
Repo Placement
Correct. Issue filed on
forgejo_admin/basketball-api, all file targets are in that repo. Single-repo scope.Dependencies
- [x] Board item #750 (Issue #293: MJML email system) — in backlog. Hard blocker, documented in Blockers section and via
blocked-by:293label. - [x] Board item #751 (Issue #294: send_templated_email()) — in backlog. Hard blocker, documented in Blockers section and via
blocked-by:294label. - [x] Board item #724 (Contract reminder email endpoint) — superseded by this ticket per Lineage. No conflict.
Dependencies are now fully documented in three places: Lineage section, Blockers section, and board item labels. Execution order is clear: #293 first, then #294, then #295.
Acceptance Criteria
7 acceptance criteria — all specific and programmatically verifiable. Test run command is concrete:
pytest tests/test_admin_email.py -v. No changes from previous review.Blast Radius
Low. Single endpoint addition, no schema changes. Existing 4 email endpoints explicitly excluded. Query registry is a new self-contained pattern.
load_email_template() is a pure function — safe to call. Rollback is straightforward.Decomposition Assessment
2 file targets (1 create, 1 modify) across 1 repo. 7 AC tightly coupled to a single endpoint. Estimated agent time: 3-4 minutes. No decomposition needed.
Recommendation
No action needed. All three items from the previous review have been resolved. Ticket is ready for execution once blockers #293 and #294 are merged.