Phase 2: Core Send API — POST /send, templates, email log #3
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
plan-pal-e-mail→ Phase 2Repo
forgejo_admin/pal-e-mailUser Story
As a platform service
I want a centralized email API with Gmail OAuth, CDN templates, and brand wrapping
So that all projects (westside, mcd-tracker, etc.) can send branded emails through one service
Context
Phase 1 deployed pal-e-mail with /healthz, Postgres (email_log table via alembic), writable Gmail OAuth PVC, Woodpecker CI, and ArgoCD. Phase 2 adds the actual email sending: POST /send with multi-tenant Gmail OAuth, template fetching from MinIO CDN, brand wrapper (extracted from basketball-api), and an email log query API. The gmail-sdk-ldraney package handles OAuth token management and Gmail API calls. Templates are fetched via httpx from MinIO CDN with simple {{key}} placeholder replacement.
File Targets
Files to create:
src/pal_e_mail/schemas.py— Pydantic request/response models (SendRequest, SendResponse, LogEntry, LogResponse)src/pal_e_mail/services/__init__.py— empty package initsrc/pal_e_mail/services/sender.py— GmailClient cache, send_email() orchestration + EmailLog writingsrc/pal_e_mail/services/template.py— fetch_template(), brand_wrapper(), html_to_plain_text()src/pal_e_mail/routes/__init__.py— empty package initsrc/pal_e_mail/routes/send.py— POST /send endpointsrc/pal_e_mail/routes/log.py— GET /log endpointtests/test_send.py— send endpoint tests (mocked gmail-sdk + httpx)tests/test_template.py— template service teststests/test_log.py— log query testsFiles to modify:
src/pal_e_mail/main.py— include send and log routersFiles NOT to touch:
src/pal_e_mail/models.py— EmailLog schema from Phase 1 already has all needed fieldssrc/pal_e_mail/database.py— no changes neededsrc/pal_e_mail/config.py— already has gmail_secrets_dir and minio_cdn_base_urlalembic/— no migration neededAcceptance Criteria
Test Expectations
cd ~/pal-e-mail && .venv/bin/pytest tests/ -vConstraints
Checklist
Related
project-pal-e-mail— parent projectplan-pal-e-mail— parent planservices/email.pylines 332-380 — brand wrapper sourceclient.py— GmailClient and GmailAPIError API