Marketing Module Technical Specifications
Campaign orchestration with Wilson Score A/B testing, visual journey automation, newsletter subscription management, multi-provider email sending with deliverability monitoring, GDPR-compliant anonymization, domain authentication, global suppression management, RFM segmentation, one-click unsubscribe, per-subscriber dynamic content, double opt-in, and AI visibility tracking.
System Metrics
Dispatch throughput
Configurable rate limit per campaign, batched across concurrent BullMQ workers — peak dispatch 10K+ msgs/sec
A/B testing method
Wilson score lower bound at 95% confidence
Email providers
SendGrid, Mailgun (US/EU), Resend, Postmark, SMTP, Console (dev)
SMS providers
AWS SNS, Twilio
Template engine
MJML → standards-compliant HTML
GDPR
SHA-256 PII anonymization (irreversible)
Domain authentication
Automatic SPF/DKIM/DMARC selector detection, graded A–F
Architecture Overview
The Marketing module orchestrates the following capability domains:
- Campaigns — orchestration and Wilson Score A/B testing
- Automation — visual journey execution
- Newsletters — subscription management, CSV import
- Email providers — multi-provider send abstraction with automatic failover
- Deliverability — webhook ingestion, bounce/complaint handling
- Dispatch queue — high-throughput batch delivery
- GDPR — SHA-256 anonymization, consent management
- AI visibility — AI-powered subject line optimization
- SMS — AWS SNS / Twilio dispatch
- Domain authentication — SPF/DKIM/DMARC pre-flight checks
- Suppression — global suppression list management
- RFM scoring — Recency/Frequency/Monetary segmentation
- Double opt-in — confirmation flow, token management
- Unsubscribe — RFC 8058 one-click handling
- Dynamic content — per-subscriber personalization
Campaign dispatch is queue-backed, ensuring reliable delivery even during server restarts.
Campaign Orchestration & A/B Testing
Campaigns move through a straightforward lifecycle: draft, resolve recipients from a segment, pre-process content (merge variables, inject tracking, select a variant), queue the send, and track results as they come in.
Campaign send flow:
- Validate — campaign exists, status is not already "completed" or "sending"
- Guard against double-sends — a duplicate launch (double-click or retry) can't re-enqueue the entire subscriber list
- Set status to "sending" — before queueing jobs
- Resolve recipients from the target segment
- Pre-process content — template variables replaced, tracking tokens injected, variant selected
- Create send records — one per recipient, created upfront so results can be tracked as they arrive
- Batch and dispatch — recipients are chunked into isolated batches so one bad batch never affects the rest of the send
Wilson Score A/B testing: Rather than comparing raw open-rate percentages, each variant's true performance is estimated as a 95%-confidence lower bound. A variant only wins when its lower bound clearly beats the alternative's — not just when its raw rate happens to be higher.
Auto-selection criteria: A winner is only auto-selected once the leading variant's confidence interval clearly beats the runner-up's, with a meaningful lead — never from a raw percentage difference alone. This prevents auto-selecting a result that isn't statistically meaningful.
Batch Dispatch Architecture
Design philosophy: Campaigns are split into batches. Each batch is dispatched as an independent unit of work — failures are isolated per batch, not per campaign, so one bad batch never takes down an entire send.
Workers are stateless: Content is fully pre-processed before queueing — subject lines, HTML, and tracking tokens are all resolved ahead of time. Workers receive a ready-to-send recipient list; there's no additional database lookup at send time, which keeps dispatch fast and predictable.
Rate limiting: Configurable messages-per-second limit, tuned per deployment.
Retry: Multiple attempts with exponential backoff. Persistently failing sends are captured for manual review and retry rather than silently dropped.
Tracking tokens: Each send gets a unique, unguessable tracking token used to match open/click webhook events back to the specific recipient.
Journey Execution Engine
Visual builder, real execution: The journey builder isn't just a diagram — every node you place on the canvas maps to a persisted, resumable step that's evaluated against live subscriber events.
Enrollment lifecycle:
- Enroll — validates the automation is active, checks for an existing enrollment (respecting re-enrollment settings), creates the enrollment, and processes the first step
- Process — executes the current step and advances; a recursion guard protects against infinite loops from misconfigured condition nodes
- Resume — when a wait/delay step's timer fires, execution resumes automatically from the saved position
- Exit — marks the enrollment exited and logs the reason to history
Reliability: Automations run with configurable concurrency. Failed steps are captured and surfaced for manual inspection and retry rather than silently dropped — a transient failure never quietly loses a subscriber's place in a journey.
Step types executed:
- Email step — render template, send, log analytics
- SMS step — compose, send, track delivery
- Wait step — schedule a delayed resume, set enrollment status to "waiting"
- Condition step — evaluate a boolean, branch to true/false path
- Goal step — set enrollment status to "completed"
- Webhook step — fire HTTP POST to an external endpoint
- Exit step — mark enrollment exited
Subscription & CSV Import
Subscribe flow:
- Find or create the subscriber
- Check for an existing subscription to this newsletter
- If already subscribed and active, no duplicate subscription is created
- If double opt-in is required, generate a 72-hour confirmation token and set status to "pending"
- Otherwise, create the subscription as active
CSV import with consent: Bulk imports parse a CSV (first row as headers), record the required consent text for each subscriber, and set status to "pending" (double opt-in) or "active" (admin import with confirmation skipped). Exports use the same format.
Key behaviors:
- Confirmation tokens are unique, unguessable, and expire after 72 hours
- Expired tokens are rejected at confirmation time — stale confirmations require re-subscribing
- Re-subscribing a previously unsubscribed contact resets their status to "pending"
Multi-Provider Abstraction
Multi-provider architecture: Configure SendGrid, Mailgun, Resend, Postmark, SMTP, or Console (dev). The active provider is set per-tenant. Switching providers requires no code change — just a settings update.
Send flow:
- Suppression check — never blocks on a database error (fail-open); on failure the check is logged and the send proceeds
- Load the active provider configured for the tenant
- Dispatch via the provider-specific adapter
Provider test flow: Send a diagnostic email to the configured sender address, measure latency, and persist the result (success, latency, error) for visibility in the admin UI.
Batch send: Iterates all recipients, collects results, and never aborts the whole batch on a single failure — each failure is logged individually.
RFC 8058 List-Unsubscribe-OneClick: Every send includes headers that Gmail, Yahoo, and Outlook honor for one-click unsubscribe — no landing page visit required.
Domain Authentication — SPF/DKIM/DMARC Pre-Flight
Automatic selector detection: Common DKIM selector patterns used by major providers are probed automatically, so you don't need to know your provider's exact selector name in advance.
Scoring: SPF, DKIM, and DMARC are each checked; a stricter DMARC policy (reject, then quarantine, then monitor-only) earns a higher score, as does a passing SPF record and a validating DKIM selector.
Grades:
- A — SPF + DKIM + DMARC pass → proceed immediately
- B — SPF + DKIM pass, DMARC none → proceed with warning
- C — SPF or DKIM failing → block + alert admin
- F — Domain not configured → block + prevent send
Fast repeat checks: Results are cached briefly so rapid campaign launches aren't slowed down by redundant DNS lookups.
GDPR — SHA-256 Anonymization
Right-to-be-forgotten without data destruction: Hard-deleting a subscriber would corrupt historical campaign metrics. Instead, PII fields are hashed with SHA-256 — metrics remain intact, and the original PII is mathematically irrecoverable.
Deletion request: Subscriber and subscription records tied to identity are removed; send-level analytics are anonymized rather than deleted, preserving aggregate campaign performance without retaining any identifying information.
Data export: All data associated with a subscriber can be exported as JSON, satisfying the GDPR Article 20 right to data portability.
Consent tracking: Every subscriber's consent text is recorded — what they consented to and when — supporting GDPR Article 7 compliance.
Recency/Frequency/Monetary Scoring
| Score | Recency (days since last engagement) | Frequency (opens + clicks) | Monetary (lifetime value) |
|---|---|---|---|
| 4 | ≤ 7 | 20+ | $500+ |
| 3 | 8–30 | 10–19 | $100–499 |
| 2 | 31–90 | 4–9 | $20–99 |
| 1 | 91+ | 0–3 | $0–19 |
Data Model
The marketing data model covers campaign definitions and A/B variants, subscriber profiles with RFM scores and GDPR anonymization state, per-recipient send records with tracking tokens, open/click/bounce analytics, automation and enrollment state, newsletter and subscription records, provider configuration, the global suppression list, bounce and complaint records, domain authentication results, AI-generated subject line variants, and outgoing webhook delivery logs.
Key Architecture Decisions
Queue backend
Distributed job queue (BullMQ) — configurable per-campaign rate limiting, persistent jobs survive server restarts
A/B testing math
Wilson score lower bound — Prevents false winners from small sample sizes
GDPR compliance
SHA-256 anonymization — Metrics intact, PII irrecoverable — no data loss
Email providers
Multi-adapter abstraction — Tenant configures provider; code never changes
Suppression
Fail-open design — Never block a campaign on a database hiccup
Automation engine
Persisted execution graph — Visual nodes map directly to resumable steps
Automation concurrency
Configurable per deployment — Tuned to your sending volume
Domain auth caching
Short-lived cache — Prevent DNS rate limiting on rapid launches
Re-enrollment
Configurable per automation — Some journeys once-only, others repeatable
Unsubscribe
RFC 8058 One-Click — Gmail/Yahoo/Outlook one-click, no webpage visit required