Admin blast endpoint: /email/blast with layout + query + data params #295
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api#295
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Depends on MJML system + send_templated_email() tickets (same session). Supersedes board item #724 (contract reminder email endpoint).
Repo
forgejo_admin/basketball-apiUser Story
As an admin,
I want to send templated email blasts to defined audiences by specifying layout and content,
So that new email campaigns don't require new endpoints or code changes.
Context
Current pattern: each email blast has its own endpoint (
/email/profile-reminder,/email/jersey-reminder) with hardcoded query logic and response models. The contract reminder blast doesn't exist yet.Decision: one generic
/email/blastendpoint with a query registry. Predefined audience queries return per-recipient data. Admin specifies layout, content, and query name. Per-recipient placeholders (player_name, contract_url) merge into the template.The
test_emailquery param safety valve is proven and stays — limits send to one recipient for testing.The first query is
unsigned_contracts: parents with acontract_tokenon their player but nocontract_signed_attimestamp.Architecture reference:
arch-emailin pal-e-docs.Blockers
This ticket CANNOT be built until both upstream tickets are merged and deployed:
forgejo_admin/basketball-api#293— MJML email system (compiled templates must exist at/app/templates/email/compiled/)forgejo_admin/basketball-api#294—send_templated_email()function (this endpoint calls it)Do NOT start work on this ticket until #293 and #294 are merged to main.
File Targets
Files to create:
src/basketball_api/services/email_queries.py— query registry withunsigned_contractsqueryFiles to modify:
src/basketball_api/routes/admin.py— addPOST /email/blastendpointFiles NOT to touch:
/email/profile-reminderand/email/jersey-reminderendpoints — stay for nowsrc/basketball_api/services/email.py— usessend_templated_email()from prior ticketAcceptance Criteria
POST /email/blastaccepts JSON body with layout, email_type, query, subject, data, optional test_emailunsigned_contractsquery returns parents whose players have contract_token but no contract signaturetest_emailparam limits send to one matching recipient{"sent_count": N, "errors": [...]}require_admindependency)Test Expectations
test_emailsends to one recipient onlysent_count: 0unsigned_contractsquery returns correct players (signed excluded, unsigned included)pytest tests/test_admin_email.py -vConstraints
list[dict]with at minimum{"email": str, "name": str}{{key}}replacement per-recipientrequire_admindependencyChecklist
Related
project-westside-basketball— westside projectarch-email— architecture referenceScope Review: NEEDS_REFINEMENT
Review note:
review-752-2026-04-03Ticket is well-scoped with complete template, verified file targets, and solid acceptance criteria, but has three refinement items before it can move to execution:
arch-emailarchitecture note does not exist in pal-e-docs. Create it to complete the traceability triangle.blocked-by:751,750label (or equivalent) to make the dependency chain machine-readable on the board.Scope Review: READY
Review note:
review-752-2026-04-03-r2Re-review after refinement. All three items from previous review (
review-752-2026-04-03) resolved: arch-email note created, explicit Blockers section added, blocked-by labels applied. Traceability triangle complete. File targets verified. Ready for execution once #293 and #294 are merged.