Skip to content

R4: declared, templated, golden-tested mailers; per-mail send transactions - #219

Merged
can3p merged 16 commits into
masterfrom
claude/zealous-shannon-ieo14d
Oct 10, 2026
Merged

can3p merged 16 commits into
masterfrom
claude/zealous-shannon-ieo14d

Conversation

@can3p

@can3p can3p commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Wave R4 (refactor). Merge with a merge or rebase merge, not a squash. Each commit is one task.

What changed

  • Mail contract (pkg/mail/mail.go): each mail is declared in its own file with a typed input, in-memory samples and embedded templates. Subject and text go through text/template, HTML through html/template. mail.All() is the registry. Outgoing is folded into mail.Envelope. No call site builds a mail body with fmt.Sprintf anymore.
  • All 14 mails converted: the 9 user mails, plus the 5 admin notifications, which move from pkg/admin into pkg/mail as Admin…. pkg/admin keeps only ClonedCustomRecovery.
  • Goldens: TestMails_Goldens writes one golden per sample. Every pre-existing golden changed only in whitespace when it moved to templates. Afterwards, samples got a site with a root, so links are now absolute (https://pcom.test), and the post-prompt-answer sample's post id became post-2. Each constructor has a _MatchesSample test.
  • Preview: /dev/mail shows every sample. It is mounted only with --dev-routes / DEV_ROUTES, which is off by default and on in docker-compose.yml and .env.example.
  • Sender: dbsender sends each due mail in its own transaction (it used to send the whole batch in one, so a failed update resent everything). The retry schedule is --email-retry-intervals, default 10s,60s,30m, with the same attempt count as before.
  • Plan: the job queue is a new wave, R8 (docs/plan/r8.md), which takes over open question Q9.
  • Docs: architecture, testing, running, gogo-extraction, AGENTS.md and the wave-run skill updated; history in docs/archive/history/r4.md.

Checks

🤖 Generated with Claude Code

https://claude.ai/code/session_01UmD6gdC2ENrRcg4XZVZuxd


Generated by Claude Code

claude added 15 commits October 7, 2026 22:33
R4 gets its task table: a mail contract with typed inputs, samples,
text/html templates and per-sample goldens; the 14 mails converted in
parallel; a /dev/mail preview behind a DEV_ROUTES flag; and the mail
sender moved to one transaction per mail. The job queue becomes its own
wave, R8, which takes over Q9.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UmD6gdC2ENrRcg4XZVZuxd
…ry, sample goldens

LoginCode and ConfirmSignup are the reference conversions. Their goldens
differ only in whitespace.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UmD6gdC2ENrRcg4XZVZuxd
Comment samples are literal inputs rather than built by the constructors'
own mapper; samples use a site with a root, so a constructor that ignores
its site fails; the post-prompt-answer sample tells the post id from the
prompt's post id; the send-error test that exercised no mail code moves to
the posts service as a rollback test; redundant admin asserts are dropped.
Golden changes: links gain https://pcom.test, and post_prompt_answer's
unique id is post-2.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UmD6gdC2ENrRcg4XZVZuxd
Comment thread docs/running.md Outdated
@can3p
can3p merged commit bbad911 into master Oct 10, 2026
8 checks passed
@can3p
can3p deleted the claude/zealous-shannon-ieo14d branch October 10, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants