Goal: Invitation Mail Server
Wire the deployment of a partition-level system email server into partition
creation and update, and deliver the common-module library classes that
let any Module / Component send emails through it — analogous to how
common-module provides the classes any Module / Component uses to access a
database. The first intended consumer is the invitation flow (today the
inviting user must copy/paste the invitation message); adopting the capability
in accounts is a follow-up project, not part of this one.
Linear Tickets
Section titled “Linear Tickets”- PDEV-1235 — Provision and Wire a system email server for invitations without Copy/Paste: Provision a system email server during partition creation/update and provide the sending capability so invitation emails can be sent by the system directly. (High priority; no further description on the ticket — scope is defined by this project’s documents.)
Repositories
Section titled “Repositories”| Repository | Role | Planned Changes |
|---|---|---|
infrastructure | Partition provisioning (CDK, amm.sh) | Provision the system email server (domain system.{partition}.{base}) as part of partition creation/update, extending the Phase-4 partition-email deliverables (stacks/purpose/partition-email.ts, amm.sh email steps); deliver the server token to consuming components as a secret |
common-module | Shared Kotlin library | Primary code deliverable: email-sending library classes usable by any Module / Component, configured from the partition-provisioned secret (analogous to the database-access classes) |
operations | Backend component | Runtime wiring needed for components to consume the capability (e.g., Helm/ESO secret projection, configuration surface); exact scope determined during design |
documentation | Project artifacts + current-system docs | Project documents under roadmap/system/messaging/invitation-mail-server/; updates to current-system runtime/OAM email pages |
Success Criteria
Section titled “Success Criteria”- Creating or updating a partition provisions (idempotently) the partition’s
system email server on domain
system.{partition}.{base}, with its server token generated at deployment and delivered to consuming components as a secret — never stored in the database. common-modulepublishes library classes with which any Module / Component can send email through the partition’s system server, demonstrated by an integration-tested sending path.- Provisioning is repeatable and drift-checked consistently with the existing partition-email infrastructure.
- All changes ship with tests, CHANGELOG entries, and documentation updates per repository conventions.
Context
Section titled “Context”Current invitation flow — documented in
Invite User to Tenant.
The Invitation entity lives in the Accounts component; on invite the system
generates an invitation URL and a sample message that the inviting user must
send manually (MVP2 constraint 2). This project delivers the sending
capability; the follow-up accounts adoption project retires the manual step.
Email infrastructure — this project builds directly on the completed email-integration project:
- Phase 4 (Runtime Platform Updates) landed per-partition mail sub-zones
(
{partition}.ardamails.com), per-partition Postmark account-token and encryption-key secrets, and IAM roles — provisioned throughamm.shandstacks/purpose/partition-email.tsininfrastructure. - Phase 5a shipped the supporting
common-moduleAPIs (TokenCipher, idempotency helpers,AppError.Application,sanitizeHeader). - Phase 5b shipped the
ShopAccess/Emailmodule inoperations(per-tenant Postmark server provisioning, sending, webhook handling).
What is missing: a system-owned email server per partition for administrative mail, provisioned as part of partition creation/update rather than tenant onboarding, and a reusable library through which any component sends mail with it.
Deliberate simplification vs. per-tenant email. The per-tenant path (email-integration DQ-012) encrypts tenant server tokens in the database because tenants are created at runtime. The system server has no per-tenant configurability: its token is generated at partition deployment, delivered to the components that need it as a secret, and never stored in the database — so none of the token-encryption machinery applies to this project.
Standing decisions that do apply (see the email-integration decision log):
- Mail root domain
ardamails.com, parametrized everywhere (DQ-009). The system sending domain is fixed at design time assystem.{partition}.{base}withbase = ardamails.com. - Secret delivery via
op→amm.sh→ CFNNoEchoparameter → Secrets Manager → ESO (documented in secret-delivery-pattern). - Operator surfaces integrated into
amm.sh, not standalone CLIs (DQ-R1-022).
In Scope
Section titled “In Scope”- System email server provisioning (domain
system.{partition}.{base}) as part of partition create/update (infrastructure). - Server-token generation at partition deployment and delivery to consuming components as a secret.
common-moduleemail-sending library classes usable by any Module / Component.- Runtime wiring in
operationsneeded to consume the capability, as the design requires. - Documentation: project artifacts, current-system updates, operator notes.
Out of Scope
Section titled “Out of Scope”accountschanges — adopting the capability in the invitation flow is a follow-up project; MVP2 constraint 2 of Invite User to Tenant is retired there, not here.- Per-tenant email capabilities and token encryption (delivered by email-integration Phase 5b; not applicable to the system server).
- New corporate/marketing sending domains (Phase 3 scope).
- Changes to the invitation lifecycle (states, transitions, entities).
- Frontend changes.
Constraints
Section titled “Constraints”- Follow the established email-integration architecture: thin-wrapper Postmark
constructs,
amm.shidempotency/security rules, secret-delivery pattern, CFN stack-name immutability. - The system sending domain is
system.{partition}.{base}with the base domain parametrized (ardamails.comtoday, per DQ-009). - The system server token is never stored in the database; it reaches consumers only as a deployment-delivered secret.
- No breaking changes to the deployed partition-email stacks; changes must
cdk diffclean-or-additive against deployed partitions. - Rollout follows the established partition order:
dev → {stage || demo} → prod. - Postmark accounts: production partitions on
PostmarkProd, non-production onPostmarkNonProd.
Reference Documents
Section titled “Reference Documents”- Invite User to Tenant — current invitation flow (Accounts component); its manual-send constraint is retired by the follow-up adoption project
- Email Integration project — parent architecture, phases, decision log
- Email Integration phases — Phase 4/5b deliverables this project extends
- Secret delivery pattern — credential flow for partition secrets
Copyright: (c) Arda Systems 2025-2026, All rights reserved
Copyright: © Arda Systems 2025-2026, All rights reserved