Mail outbox and SMTP delivery service #12

Closed
opened 2026-07-04 14:52:01 +02:00 by fable-5 · 0 comments
Collaborator

Context

Verification and reset mails (and later notifications) are sent reliably via an outbox table with retry (ADR 0002/0007).

Scope

Implement MailModule: mail_outbox Prisma model, enqueue(to, templateKey, params, locale) API, a worker loop (interval job) sending via SMTP (nodemailer, config from env), exponential backoff (max 5 attempts, then failed), and layout-light HTML+text templates rendered with the API i18n instance (de/en). Provide dev-mode delivery to console + a MailHog service in the dev Compose overlay.

Acceptance criteria

  • with SMTP down, mails stay queued and are delivered after it returns (test with MailHog stop/start)
  • templates render in both languages; links use APP_BASE_URL
  • failed-after-retries mails are visible via a log warning and a failed status
  • no secrets in logs; SMTP config validated at startup

Technical notes

  • ADR 0007, data-model.md (mail_outbox), ADR 0012 for template texts.
  • Templates for this story: verify-email, reset-password (used by #13/#15).

Dependencies

Depends on #3, #5.

Size: ~1.5 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context Verification and reset mails (and later notifications) are sent reliably via an outbox table with retry (ADR 0002/0007). ## Scope Implement `MailModule`: `mail_outbox` Prisma model, `enqueue(to, templateKey, params, locale)` API, a worker loop (interval job) sending via SMTP (nodemailer, config from env), exponential backoff (max 5 attempts, then `failed`), and layout-light HTML+text templates rendered with the API i18n instance (`de`/`en`). Provide dev-mode delivery to console + a MailHog service in the dev Compose overlay. ## Acceptance criteria - [ ] with SMTP down, mails stay queued and are delivered after it returns (test with MailHog stop/start) - [ ] templates render in both languages; links use `APP_BASE_URL` - [ ] failed-after-retries mails are visible via a log warning and a `failed` status - [ ] no secrets in logs; SMTP config validated at startup ## Technical notes - ADR 0007, data-model.md (`mail_outbox`), ADR 0012 for template texts. - Templates for this story: `verify-email`, `reset-password` (used by #13/#15). ## Dependencies Depends on #3, #5. **Size**: ~1.5 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M1 — Accounts & authentication milestone 2026-07-04 14:52:01 +02:00
fable-5 added the
backend
label 2026-07-04 14:52:01 +02:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#12
No description provided.