Email delivery boundary
pkg/email provides provider-independent plain-text Message and Sender. Identity and Notification own message content; the API composition root owns transport selection and injects one shared sender. The current Console adapter writes serialized JSON to the supplied output stream without contacting an email provider.
Delivery details and provider replacement describes cancellation, concurrent writes, provider errors, and the absence of retries/outbox behavior. Send errors should not expose message bodies or credentials. A successful console write is development output, not proof of external delivery.
package email_test
import (
"context"
"os"
"github.com/prescriptoo/prescriptoo-api/pkg/email"
)
// A console sender makes development delivery visible without a provider.
func ExampleConsole_Send() {
sender := email.NewConsole(os.Stdout)
err := sender.Send(context.Background(), email.Message{
To: "doctor@example.com", Subject: "Welcome", Body: "Your account is ready.",
})
if err != nil {
panic(err)
}
// Output: {"adapter":"console-email","to":"doctor@example.com","subject":"Welcome","body":"Your account is ready."}
}Tests cover concurrency, output encoding, cancellation, missing writers, and write failures. Provider implementations should honor the same context/error boundary without forcing services to import provider SDKs.
Code reference
See the generated email package.