project-westside-email-agent updated 2026-04-25Westside Email Agent
Vision
A single agent + generic blast system that sends every branded Westside email type. New email types are added as data — audience query + EmailType + layout — not as new agents or new endpoint code. One agent, many email types, zero PRs to send a new email when its three pieces already exist.
User Stories
| Key | Story Note | Role | Success Metric |
|---|---|---|---|
agent-handles-emails |
story-westside-email-agent-agent-handles-emails | Admin (Lucas; Marcus via relay) | Lucas can send any email type with one CLI session, zero code changes, zero unapproved sends |
Additional stories will be added as new email types or workflow patterns surface. The single-story start is intentional — the existing infrastructure already covers the universal case.
Architecture
This project shares its backend architecture with westside-basketball. Diagrams already exist:
- arch-email — components (gmail-sdk, services/email.py, services/email_queries.py, services/outbox.py, brand.py, MJML templates, EmailLog), layouts (notification, action, announcement), MJML→compile→send flow, design decisions
- sop-email-send — 8-step universal workflow + contract enhanced gate + 11 rules (the canonical nuclear gate)
The dedicated triplet (arch-domain-westside-email-agent, arch-dataflow-westside-email-agent, arch-deployment-westside-email-agent) is intentionally not built — the existing arch-email already describes the system at the right level. Triplet can be backfilled if/when the agent's runtime layer diverges meaningfully from basketball-api's email layer.
Key Decisions
- Audience as data, not code path —
QUERY_REGISTRYin basketball-api already lets new audiences register without endpoint changes. Future: lift the registry from Python dict to DB table for non-engineer authoring. - Universal nuclear gate — sop-email-send's gate applies to ALL email types. No per-email-type gate logic.
- One agent, not per-type — westside-email-agent handles every email type. Separate agents (e.g. tournament-email-agent) were considered and rejected as duplicate scaffolding.
- Agent persona is local-only —
~/westside-email-agent/CLAUDE.mdis not in a Forgejo repo, parallel to other working-dir agents under~/westside-agency/.
Board
board-westside-email-agent — primary kanban for this project. Permanent, not time-boxed. Columns: backlog → todo → next_up → in_progress → qa → needs_approval → validation → done. Items reference Forgejo issues in basketball-api (since that's where email infrastructure code lives).
Status
| Component | Status | Notes |
|---|---|---|
POST /admin/email/blast |
Built | basketball-api/routes/admin.py:1233 — generic, validates query + email_type, supports test_email |
QUERY_REGISTRY |
Built (3 queries) | unsigned_contracts, incomplete_profiles, tournament_committed |
query_monthly_fee_due |
Missing | Tracked: basketball-api#512 |
| Layouts (action, notification, announcement, jersey-reminder) | Built | basketball-api/templates/email/compiled/ |
| EmailType enum | Built | basketball-api models — values per email type |
| EmailLog | Built | Automatic per send |
| Agent (CLAUDE.md, auth shortcut, safety rules) | Built | ~/westside-email-agent/CLAUDE.md (3.6KB) |
| arch-email + sop-email-send | Built | Canonical, active |
Today's blockers: contract reminder send is unblocked (existing infra). Monthly fee send waits on basketball-api#512.
Milestones
- TBD — first milestone will land when the contract send + monthly send are both completed and EmailLog confirms zero-delta delivery.
Repos
| Repo | Platform | Role | Status |
|---|---|---|---|
~/westside-email-agent/ |
local-only | Agent CLAUDE.md (no Forgejo repo, by design) | Active |
forgejo_admin/basketball-api |
Forgejo | Backend — blast endpoint, query registry, EmailLog, EmailType enum | Active |
forgejo_admin/westside-emails |
Forgejo | MJML template source (compiled HTML mounted into basketball-api) | Active |
Related
- project-westside-basketball — backend repo where email infrastructure lives
- project-westside-agency — orchestrator project (this agent registered as a slot)
- feedback_email_blast_nuclear_gate — gate provenance
- feedback_payment_email_e2e_validation — e2e validation requirement