1.9 KiB
1.9 KiB
F-152 — Architecture Decision Record
Status
Accepted.
Context
Two customer-facing emails are missing: (1) a welcome email on registration, and
(2) an order-confirmation email on successful payment. The admin order-transition
flow already sends emails via sendOrderStatusEmail (nodemailer + SMTP read
from store_settings), but the automated paths bypass it: the payments webhook
uses a no-op OrderEventPublisher, and RegisterUser has no mailer at all.
Decision
Reuse the existing store_settings SMTP pattern instead of introducing a new
email provider, to keep blast radius low and stay consistent with
SettingsPasswordResetMailer / sendOrderStatusEmail.
- Order confirmation: export
sendOrderStatusEmailfromorders/index.ts(it is already used internally byorders.routes) and call it from the payments webhook route handler onPaymentSucceeded. This keeps the email in the route handler (ownsdeps.pool), mirroring the admin-transition route. - Welcome email: add a
WelcomeMailerport to identity with aSettingsWelcomeMailerinfra adapter modeled 1:1 onSettingsPasswordResetMailer.RegisterUsertakes an optional mailer and swallows failures so registration never blocks on email. - EmailTemplate: register
account_createdin the notifications domain +LoggingEmailProviderbody/subject maps so the admin dispatch endpoint stays consistent.
Consequences
- identity module stays self-contained (models existing password-reset mailer).
- Best-effort semantics: email/SMTP failures log a warning and never fail the registration or payment webhook.
- Idempotency on the payment side comes from the existing payment-event dedup; we only email when outcome.kind === 'processed' for PaymentSucceeded.
- Out of scope: email-verification gating and refactoring the admin-transition mailer into the notifications provider.