Generic send_templated_email() + EmailType migration (contract_offer, contract_reminder) #294
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#294
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 email system ticket (same session). Part of email architecture overhaul scoped 2026-04-03.
Repo
forgejo_admin/basketball-apiUser Story
As a developer,
I want one generic send function that takes a layout name and data dict,
So that new email types don't require new Python functions.
Context
Currently every email type has its own function (80-150 lines).
send_confirmation_email(),send_profile_reminder_email(),send_jersey_reminder_email(), etc. The pattern is identical: build HTML, call gmail_sdk, log to EmailLog. Only the content differs.Decision: one
send_templated_email()function handles all sends. Layout name maps to a compiled MJML template. Data dict fills{{key}}placeholders. EmailLog records the type.Also need
contract_offerandcontract_remindervalues in the EmailType enum for the contract email wave.Existing functions stay untouched — this ticket adds the new path alongside them. Migration of old functions is future work.
File Targets
Files to modify:
src/basketball_api/services/email.py— addsend_templated_email()function (~30 lines)src/basketball_api/models.py— addcontract_offer,contract_reminderto EmailType enumalembic/versions/— new migration adding enum valuesFiles NOT to touch:
src/basketball_api/routes/admin.py— blast endpoint is a separate ticketAcceptance Criteria
send_templated_email(tenant, layout="action", data={...}, to=email, subject=subj, email_type=EmailType.contract_reminder, db=db)sends a branded emailEmailType.contract_offerandEmailType.contract_reminderexist in enumTest Expectations
send_templated_email()calls gmail_sdk and creates EmailLog on successsend_templated_email()logs failure and returns None on gmail errorpytest tests/ -k "test_templated_email or test_models" -vConstraints
get_gmail_client(tenant, db=db)for OAuthload_email_template()for template renderingChecklist
Related
project-westside-basketball— westside projectScope Review: NEEDS_REFINEMENT
Review note:
review-751-2026-04-03Ticket is well-scoped with all template sections present, verified file targets, and correct traceability to WS-S7 and WS-S22. Single fixable issue:
arch-emailarchitecture note exists in pal-e-docs. 8+ board items referencearch:emailbut the backing note is missing. Createarch-emailto document the email subsystem (send functions, EmailType enum, EmailLog, template loading, Gmail OAuth).Dependencies verified: #293 (MJML templates) is a soft dependency (not blocking code merge, but blocking production use). #295 (blast endpoint) correctly identified as downstream consumer.
Scope Review: READY
Review note:
review-751-2026-04-03-r2Re-review after arch-email note creation. All template sections present, traceability triangle complete (WS-S7, WS-S22, arch-email verified), file targets confirmed, dependencies mapped. Ready for dispatch.