Files
summercms/.planning/phases/04-cli-scaffolding-i18n-and-mail/04-03-SUMMARY.md
Jakub Zych 3b476cbf55 docs(04-03): complete postcard mail plan
Tasks completed: 3/3
- Render and send one registered template through memory
- Register plugin layouts and publish the mailer at Boot
- Add config-selected log and SMTP delivery

SUMMARY: .planning/phases/04-cli-scaffolding-i18n-and-mail/04-03-SUMMARY.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 14:03:11 +02:00

6.6 KiB
Raw Blame History

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
04-cli-scaffolding-i18n-and-mail 03 mail
postcard
mail
goldmark
go-mail
smtp
wintercms
phase provides
04-cli-scaffolding-i18n-and-mail pact.HasMailTemplates, party.Activate Register-then-Boot order
phase provides
01-framework-kernel-foundation backpack.Publish/Lookup, compass mail.* and SUMMER_MAIL__ layering
postcard Mailer with Send(ctx, Message) through memory, log, and SMTP drivers
Winter-shaped template and layout parser (INI, ==, Markdown body)
Goldmark HTML with unsafe HTML disabled and header/address validation
hello plugin mail templates, -en sibling, and hello layout
04-04-tests
plugin-porting
I18N-03
added patterns
github.com/yuin/goldmark@v1.8.6
github.com/wneessen/go-mail@v0.8.1
html/template on Markdown then Goldmark HTML; substituted Markdown is the text part
HasMailTemplates catalogs validate at Boot and publish Mailer before Boot
mail.driver selects memory, log, or smtp with explicit TLS including opt-in NoTLS
created modified
postcard/templates.go
postcard/mailer.go
postcard/drivers.go
postcard/assets/default.htm
postcard/mailer_test.go
examples/hello/plugins/base/views/mail/hello.htm
examples/hello/plugins/base/views/mail/hello-en.htm
examples/hello/plugins/base/views/mail/layouts/hello.htm
examples/hello/config/mail.yaml
party/registry.go
party/registry_test.go
examples/hello/plugins/base/plugin.go
examples/hello/hello_test.go
go.mod
go.sum
Goldmark v1.8.6 is used without html.WithUnsafe; final HTML is rejected if script/iframe, event handlers, or javascript/vbscript/data schemes remain
postcard.Mailer is published after Register and before Boot; each HasMailTemplates catalog is validated at that plugin's Boot transition
mail.smtp.tls defaults to mandatory STARTTLS; none/notls is opt-in for Mailpit and is never inferred
Dotted names vendor.plugin::mail.name map to views/mail/<dot-path>.htm; short layout aliases resolve only within the owning plugin
Send takes the full dotted name including any -en suffix and performs no locale lookup
Driver errors return to Send with one postcard wrap and no retry; SMTP errors must not include credentials or bodies
I18N-03
6min 2026-09-18

Phase 4 Plan 03: postcard mail Summary

Winter-shaped mail templates and layouts render safe Markdown/HTML and send through memory, log, or go-mail SMTP selected by mail.*

Performance

  • Duration: 6 min
  • Started: 2026-09-18T11:56:07Z
  • Completed: 2026-09-18T12:02:31Z
  • Tasks: 3
  • Files modified: 15

Accomplishments

  • postcard parses INI headers, == separators, and Markdown bodies; html/template substitutes vars, Goldmark renders HTML, and the substituted Markdown is the text part
  • Plugins register dotted template names and short layout aliases; missing files and unknown layouts fail party: boot <plugin ID> with the full name
  • postcard.Mailer is app-scoped; hello sends golem15.hello::mail.hello and hello-en through backpack, using the plugin hello layout
  • mail.driver selects memory, log, or smtp (SUMMER_MAIL__ overrides); SMTP uses explicit TLS, address/CRLF checks, and context-aware go-mail send without retries

Task Commits

Each task was committed atomically:

  1. Task 1: Render and send one registered template through memory - b4fd833 (feat)
  2. Task 2: Register plugin layouts and publish the mailer at Boot - 1e51597 (feat)
  3. Task 3: Add config-selected log and SMTP delivery - 1b72456 (feat)

Plan metadata: (this commit)

Files Created/Modified

  • postcard/templates.go - Winter parser, catalog registration, Goldmark render, HTML safety
  • postcard/mailer.go - Message/Mailer, Activate, BootPlugin, config-selected driver
  • postcard/drivers.go - Driver interface plus memory, log, SMTP, and FailDriver
  • postcard/assets/default.htm - Neutral framework layout
  • postcard/mailer_test.go - render, layout, and driver smokes
  • party/registry.go - Publish mailer before Boot; validate catalogs at Boot
  • examples/hello/plugins/base/plugin.go - HasMailTemplates with hello and hello-en
  • examples/hello/plugins/base/views/mail/ - Distinct default-locale and -en templates plus hello layout
  • examples/hello/config/mail.yaml - memory driver and documented smtp/NoTLS shape
  • go.mod / go.sum - goldmark v1.8.6 and go-mail v0.8.1

Decisions Made

  • Goldmark stays on v1 (v2 is still a new line); unsafe HTML stays disabled and final HTML is re-checked
  • Default layout is internal (layout = default or omitted); plugins cannot alias default
  • TLS empty/mandatory maps to go-mail TLSMandatory; none/notls is explicit Mailpit opt-in; starttls is opportunistic only when named
  • Mailpit real SMTP receipt stays Plan 04 (D-19); this plan uses an in-process FailDriver and a closed-port SMTP error

Deviations from Plan

Auto-fixed Issues

1. [Rule 2 - Missing Critical] Three-section layout parser shipped with Task 1

  • Found during: Task 1 (embedded default layout)
  • Issue: The neutral default layout is header + text wrapper + HTML wrapper, so memory-driver HTML/text wrapping could not wait for Task 2
  • Fix: Parse two-== layouts in templates.go in Task 1; Task 2 still added plugin aliases, party Boot validation, and the hello layout
  • Files modified: postcard/templates.go, postcard/assets/default.htm
  • Verification: TestMailRenderSmoke asserts content-body from the default layout
  • Committed in: b4fd833 (Task 1 commit)

Total deviations: 1 auto-fixed (1 missing critical) Impact on plan: No behavior divergence from D-06–D-09 or D-18–D-21. Layout parsing was required to honor the Task 1 default-layout artifact.

Issues Encountered

None

User Setup Required

None - no external service configuration required. Production SMTP credentials stay in mail.* / SUMMER_MAIL__; Mailpit is Plan 04.

Next Phase Readiness

Ready for 04-04 (unit tests and Mailpit). Memory render, layout wrappers, named boot errors, log/SMTP driver contracts, and a failing-driver seam are in place. Do not treat -short as SMTP receipt.

Verification

  • go test ./postcard -run 'TestMailRenderSmoke|TestMailLayoutSmoke|TestMailDriverSmoke' -short -count=1 — PASS
  • go -C examples/hello test ./... — PASS
  • go vet ./... && go test ./... — PASS

Self-Check: PASSED


Phase: 04-cli-scaffolding-i18n-and-mail Completed: 2026-09-18