project-page active Westside Email Agent
project-westside-email-agent updated 2026-04-25

Westside 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 pathQUERY_REGISTRY in 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.md is 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