MJML email service: branded templates + thin sender integration #134
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#134
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-wkq→ Phase 11 (Girls Tryout) → discovered scope → new capabilityTriggered by jersey email images fix (MinIO CDN). Existing 825-line email.py has hardcoded HTML in Python f-strings — not enterprise.
Repo
forgejo_admin/westside-emails(new repo) +forgejo_admin/basketball-api(integration)User Story
As an admin, I want to send branded email announcements so that parent comms are professional and consistent
As an admin, I want to edit email content and preview before sending so that I don't need a developer for copy changes
As a parent, I want to receive a branded email with jersey ordering link so that I can order without bringing cash
As a parent, I want to receive clear email communications with action links so that I never miss a deadline
Context
All four user stories are documented on the Westside project page under User Roles & Stories. Current email system embeds 825 lines of inline-CSS HTML inside Python f-strings in
services/email.py. Every copy change (dates, locations, pricing) requires a code change, PR, deploy. No preview capability. Brand styles duplicated across 4 email functions. Not reusable across projects.MJML is the industry-standard enterprise solution for email templating. Write semantic markup (
mj-section,mj-button), compile to battle-tested inline-CSS HTML that renders in Gmail, Outlook, Apple Mail. Templates live in their own repo, decoupled from API code.File Targets
New repo:
westside-emailssrc/base-layout.mjml— shared brand wrapper (header, footer, colors)src/jersey-reminder.mjml— first template: girls jersey ordering remindersrc/tryout-announcement.mjml— port existing announcement emailsrc/confirmation.mjml— port existing registration confirmationsrc/roster-export.mjml— port existing roster emailsample-data/jersey-reminder.json— sample data for previewpackage.json— mjml CLI dependencypreview/— local preview serverbasketball-api changes:
src/basketball_api/services/email.py— replace f-string HTML with template loader + string replace + sendsrc/basketball_api/routes/admin.py— update email endpoints to use templatesFiles the agent should NOT touch:
src/basketball_api/routes/jersey.py— Stripe checkout logic, unrelatedsrc/basketball_api/routes/webhooks.py— Stripe webhook handler, unrelatedAcceptance Criteria
npm run buildin westside-emails, MJML compiles to HTML indist/dist/jersey-reminder.htmlin a browser, it renders the branded email with placeholder markers{{name}},{{jersey_url}}etc..mjmlfile, I can preview changes without touching Python codeTest Expectations
npx mjml src/*.mjml -o dist/exits 0 with valid HTML outputnpm run build && npm run previewfor visual checkConstraints
{{variable}}markers are literal strings in compiled HTML — basketball-api does simple string replacement at send timeChecklist
Related
project-westside-basketball— project page with user stories this fulfillsplan-wkq— parent plan