Depends on: [setup-auto-confirm.md](setup-auto-confirm.md) (provides `email_configured?/0` and warning banner)
## Context
After the setup wizard auto-confirm work, SMTP is configurable via env vars only. Self-hosted users shouldn't need to restart the server or touch env vars to configure email. This plan adds an admin settings page for email delivery with support for popular Swoosh adapters, stored in the Settings table with encrypted secrets.
## Design
### Precedence chain
```
Env vars (SMTP_HOST etc.) > DB settings > Local adapter (dev default)
```
If `SMTP_HOST` is set, env vars win — the admin UI shows the config as read-only with a note that it's controlled by environment variables. If no env vars, the admin can configure everything from the UI. If nothing is configured, falls back to `Swoosh.Adapters.Local`.
### Supported adapters
Start with the popular ones that cover 95%+ of use cases. Each has a simple config shape:
The UI renders dynamically from this registry. Secret fields use `put_secret/2` and show masked hints via `secret_hint/1`. Non-secret fields use `put_setting/3`.
### Storage in Settings table
Uses the existing key-value Settings table:
| Key | Type | Example |
|-----|------|---------|
| `email_adapter` | string | `"postmark"` |
| `email_relay` | string | `"smtp.example.com"` |
| `email_port` | integer | `587` |
| `email_api_key` | encrypted | (encrypted via Vault) |
| `email_password` | encrypted | (encrypted via Vault) |
This is wrapped in a `Berrypod.Mailer.load_config/0` function, called from:
-`Application.start/2` (boot)
- The admin settings save handler (runtime update without restart)
### Updating `email_configured?/0`
The helper from setup-auto-confirm.md already checks if the adapter is not `Swoosh.Adapters.Local`. No changes needed — once the admin configures an adapter via the UI, `Application.get_env` returns the new adapter and the function returns `true`.
| `lib/berrypod_web/components/layouts/admin.html.heex` | Link banner to settings page, add nav entry |
| `assets/css/admin/components.css` | Styles for email settings form |
| Tests (3 new files) | Mailer, adapters, LiveView |
## Verification
1.`mix precommit` passes
2. No env vars set: admin UI at `/admin/settings/email` shows adapter dropdown, can configure Postmark with API key, save, `email_configured?()` returns true, warning banner disappears
3. With `SMTP_HOST` set: admin UI shows SMTP config read-only with "controlled by environment variables" note
4. "Send test email" delivers to admin's address
5. Server restart: config reloaded from DB, email still works
6. Adapter change: old config cleared, new adapter's fields shown, save applies immediately