feat: implement go/smtp module — lifecycle, health, and email provider #1
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Overview
Implement the
go/smtpmodule following the standard go-kit module pattern: a single*Clienttype returned byNew()that satisfieslauncher.Component,health.Checkable, and the module's ownsmtp.Senderinterface.SMTP is infrastructure — it must attach to the launcher lifecycle and report health. Inline implementation inside a consuming project (e.g. iron-dough-api) is explicitly out of scope.
Module structure
Config
smtp.Configowns its own struct with env tags. Consuming projects embed this type directly:Interfaces
*Clientalso implementslauncher.Component(Start/Stop) andhealth.Checkable(Check). Callers depend only on the subset they need — the health registry only seesCheckable, services only seeSender.Message and Attachment
No-op mode
When
Config.Hostis empty,New()returns a no-opSenderthat logs a warning and returnsnilon everySendcall. This allows the restaurant to run without configuring SMTP — email failure must never block a transaction.Health check
health.CheckableHost:Port(or sends SMTP NOOP) to verify reachabilitydegraded(notdown) — email is non-critical infrastructurehealthyTemplate helper
A thin
Templatewrapper around stdlibhtml/templatefor HTML email rendering. Rendering is intentionally separate fromSend— the caller renders a template to a string and puts it inMessage.Body. This keepsSendunit-testable without template involvement.Wiring example (consuming project)
Acceptance criteria
smtp.Configstruct with env tags; no config defined outside this moduleNew(cfg Config) *Client— returns no-op whencfg.Hostis empty*Clientimplementssmtp.Sender,launcher.Component,health.CheckableMessagesupportsTo,CC,BCC,ReplyTo,Subject,Body,ContentType,AttachmentsAttachment.Dataisio.Reader(not[]byte)degraded(notdown) when SMTP host is unreachableTemplatewrapper overhtml/templatewithParseFS+RendernilonSendSendwith no-op client, health check degraded path, template rendering