Email — Domain Model
The Email module owns four entities, each backed by its own bitemporal Universe in the module’s database partition. Tenant and user references are soft — cross-service identifiers carried as values, with no foreign keys or shared transactions (Cross-Universe rule).
EmailConfiguration
Section titled “EmailConfiguration”The per-tenant configuration that grants a tenant the right to send. Identifies which Postmark Server and Sender Signature the platform uses for the tenant, the domain those sends originate from, and the DNS records that bind that domain to the signature. A tenant has at most one sendable configuration at a time (canSend() true). Its lifecycle is non-trivial — see Lifecycle.
Selected fields:
| Field | Notes |
|---|---|
sendingDomainSlug | Caller-supplied DNS label. The full sending domain {slug}.{partition}.ardamails.com is synthesized at read time from the slug + the partition’s PartitionMailZoneName; the FQDN is not persisted. Validated [a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?; unique among non-removed configurations per partition; permanent. |
signature.fromLocalPart | Local-part of the fixed From address (default noreply). The full From is {fromLocalPart}@{sendingDomain}. |
signature.fromName, signature.replyToEmail | Friendly name; optional reply-to (any domain). |
postmarkServerId, signatureId, webhookId | Postmark resource identifiers. |
serverTokenEncrypted | Per-tenant Postmark Server token, encrypted at rest (per-partition key via ESO); decrypted only at send time. |
dns.dkim, dns.returnPath | The DKIM TXT and Return-Path CNAME records (name + value) Postmark returned, as published into Route 53. |
webhookRoutingToken | Opaque per-configuration token (DQ-017). |
operational + administrative status; verificationStartedAt / verifiedAt | Lifecycle position and verification timestamps. Verification flags themselves are transient (not persisted) — collapsed into verifiedAt. |
partition is not a persisted field — it is resolved from the hosting environment (the PartitionMailZoneName export).
EmailJob
Section titled “EmailJob”A single transactional send attempt — the contract for “send this message to this recipient on behalf of this tenant.” Owns the wire-level send payload and tracks the post-send lifecycle. Three sealed subtypes: Queued (created), Sent (Postmark accepted), Failed (rejected on send or retries exhausted). Webhook-driven statuses (DELIVERED, BOUNCED, COMPLAINED, INCONSISTENT) are applied as read-side projections onto the persisted row.
Selected fields: configurationEId (soft ref), recipient (canonicalized lowercase), replyToEmail?, subject, htmlBody? / textBody? (at least one required), attachments (ordered, inline base64), postmarkMessageId?, attemptCount, errorClass?.
No
fromLocalPartonEmailJob. The From address is fixed by the configuration signature; there is no per-send override (see the module overview).
SuppressionEntry
Section titled “SuppressionEntry”A per-tenant record that a recipient must not be sent to. Created on hard bounce, spam complaint, or a Postmark-console subscription change. A send to a suppressed recipient is rejected (403) before any Postmark call. Tenant-scoped — suppression for tenant A never affects tenant B. See Webhook ingestion.
EmailEvent
Section titled “EmailEvent”An append-only record of a Postmark webhook signal (delivery, bounce, complaint, open, click) for an EmailJob. Open/click engagement events are recorded without advancing job status. Identity for de-duplication follows Postmark’s per-event-type uniqueness rules.
Copyright: © Arda Systems 2025-2026, All rights reserved