feat: phase (a) part 1 - outbox, providers, SMTP and SES, messaging bridge #6

Merged
KofTwentyTwo merged 2 commits from feature/phase-a-outbox into develop 2026-10-14 12:09:09 +00:00
2 Commits
Author SHA1 Message Date
james.maesandClaude Opus 5.5 ddcb3d1d71 fix: review findings on the outbox and transports
- email.send no longer implies email.view.
- Provider-level failures (missing or refused credentials, SES account
  errors) keep messages waiting without spending their retry budget and
  mark the provider unhealthy at once, instead of dead-lettering.
- Unbuildable messages dead-letter at once.
- SMTP sign-in over a plaintext connection is refused (loopback or an
  explicit flag excepted).
- One failing message or alert sink no longer stops the batch.
- CR/LF refused in provider sender fields and in MIME headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:41:31 -05:00
james.maesandClaude Opus 5.5 35b91aba98 feat: outbox, providers, SMTP and SES transports, and the messaging bridge
Phase (a) part 1 of docs/DESIGN.md: the email_ tables (provider,
message, attempt, template, version, brand, suppression) with Postgres
DDL; provider rows with env-var-name credentials; EmailService with
idempotency keys, suppression and same-transaction enqueue; the
dispatcher with unique-attempt claims, leases, backoff, dead letters,
rate limits and provider health; SMTP (jakarta.mail with auth, TLS and
timeouts) and SES (AWS SDK v2 sesv2 raw) transports; the QBIT_EMAIL
core messaging provider; Resend, Cancel, Send Now and Send Test Email
record actions; scheduled dispatch, maintenance and retention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:18:27 -05:00