Files
HiveGrid-Wireframes/hivegrid-cloud/docs/feature-manifests/transactional-mail.json
T

124 lines
4.2 KiB
JSON

{
"schemaVersion": "1.0",
"id": "transactional-mail",
"title": "Transactional Mail",
"classification": "core",
"status": "proposed",
"owner": "core-pruning",
"description": "System email required for authentication, invitations, account notifications, and billing operations.",
"rationale": [
"Password resets, invitations, and system notifications are core operational requirements.",
"Newsletter, inbound, and marketing email should not be bundled with transactional mail."
],
"codeAreas": [
"apps/web/app/modules/emails",
"apps/web/app/application/emails",
"apps/web/app/utils/services/emailService.ts",
"apps/worker/src/jobs/workflow-trigger-native-executor.ts",
"apps/worker/src/jobs/transactional-mail-outbox.ts",
"apps/worker/src/jobs/transactional-mail-outbox-bootstrap.ts",
"apps/worker/src/handlers.ts",
"packages/queue",
"packages/mail",
"@toolctrl/mail"
],
"dependencies": [],
"consumers": [
"auth-tenancy",
"billing",
"workflow-engine",
"plugin-candidates"
],
"integration": {
"ownership": "system-only",
"surfaces": {
"adminRoutes": [],
"tenantRoutes": [],
"publicRoutes": [],
"apiRoutes": []
},
"configuration": {
"admin": [
"Transactional mail templates and Mailjet settings"
],
"tenant": [],
"environment": [
"MAILJET_API_KEY",
"MAILJET_FROM_EMAIL",
"MAILJET_FROM_NAME",
"MAILJET_WEBHOOK_SECRET",
"MAILJET_SECRET_KEY",
"TRANSACTIONAL_MAIL_OUTBOX_REQUIRED"
],
"secrets": [
"Mail provider API keys are platform/admin-owned, never tenant-owned."
]
},
"workers": {
"required": true,
"queues": [
"outbox.mail",
"toolctrl.email"
],
"jobs": [
"mail.transactional.* outbox bridge",
"workflow email block mail.transactional.send producer",
"send-transactional-email"
],
"notes": [
"Transactional mail must be drained by an operator-owned permanent Coolify worker-mail resource with WORKER_QUEUE_GROUP=mail in each deployed environment.",
"Production worker-mail resources should set TRANSACTIONAL_MAIL_OUTBOX_REQUIRED=true so startup and /readyz fail when the outbox.mail bridge cannot subscribe.",
"This manifest records the runtime requirement; it is not live-environment proof that any specific Coolify target currently has worker-mail deployed or healthy.",
"Web and API containers either enqueue direct transactional mail jobs or publish mail.* outbox events; they must not be treated as mail consumers. The mail worker must run as a separate worker resource alongside worker-general, worker-import, worker-webhook, and worker-plugin.",
"Worker-native workflow email blocks publish mail.transactional.send outbox events; worker-general handles workflow execution while worker-mail remains the only transactional mail consumer.",
"Dependent manifests must declare any additional queue use beyond the core toolctrl.email send-transactional-email job."
]
},
"externalProviders": [
"mailjet"
],
"permissions": [
"admin.emails.*"
],
"auditEvents": [
"mail.template.updated",
"mail.provider.updated"
],
"billingImpacts": [],
"uat": [
"Password reset, invitation, and verification emails can be sent through the selected provider."
]
},
"boundaries": {
"mustKeep": [
"Password reset emails",
"Invitation emails",
"Verification and system emails required by core flows"
],
"mayMoveToPlugin": [
"Email marketing and newsletter abstractions",
"Inbound email handling",
"Provider adapters beyond Mailjet"
],
"mustNotTouch": [
"Chatbot or marketing email surfaces owned by parallel workers"
]
},
"pruning": {
"phase": "1",
"action": "keep",
"notes": [
"Mailjet is the only transactional runtime provider.",
"Removed legacy transactional adapters are not maintained as runtime adapters."
]
},
"validation": {
"source": [
"docs/feature-inventory.md",
"docs/ops/worker-queues.md",
"docs/improvement-plan/OPERATOR-CHECKLIST.md"
],
"lastReviewed": "2026-05-28"
}
}