Marketing vs transactional emails (gränsdragning)
At a glance
Marketing vs transactional emails draws a hard line between the two email categories: transactional (event-driven, no consent needed, no tracking) and marketing/newsletter (campaign-driven, double-opt-in, fully tracked). They share one delivery layer and one suppression list, but every other policy — quotas, quiet hours, unsubscribe, audit — is enforced separately so each remains compliant on its own merits.
How it works
All outbound mail flows through one EmailDistributor abstraction with two methods: send_transactional and send_bulk. Both call the same backend (Mailjet, Azure Communication Services, or the Null backend in dev), but the distributor stamps each message with its category, which drives downstream policy.
Transactional sends respond to a user action — booking confirmations, reset links, license renewal reminders — and their legal basis is GDPR 6.1b/6.1f (contract performance and legitimate interest). They need no separate consent, carry no marketing tracking pixels, dispatch immediately, ignore quiet hours, and use Jinja templates versioned with the codebase. Marketing sends require GDPR 6.1a consent verified through double-opt-in (DOI), batch through a campaign-dispatcher with throttle_per_hour (default 5000/h), pause between 22:00 and 07:00 recipient-local unless overridden with fresh-auth, and use MJML-source templates editable in the system console with live preview.
The two streams share one critical resource: the suppression list. A hard bounce or spam complaint from a transactional message blocks future marketing to the same address, and vice versa — protecting deliverability across the whole platform. Conversely they have completely separate audit trails: notification.* actions in sys_audit_entries for transactional, newsletter.* actions for marketing. That separation makes it trivial for a compliance officer to audit one category without bleed from the other.
Unsubscribe semantics differ. Marketing emails always include RFC 8058 one-click unsubscribe plus a preference-center link and per-list opt-out. Transactional emails generally do not — you cannot unsubscribe from your booking confirmation — except for explicitly optional transactional categories like ranking-change pings, where users can opt out granularly. Tracking is off by default for transactional (privacy first); marketing carries opens via pixel and clicks via redirect, plus heatmap data feeding the newsletter analytics. Logging is separate too: transactional writes to notification_logs, marketing writes to a dedicated newsletter_events pipe with cohort and engagement analytics.
Key capabilities
- Single EmailDistributor abstraction with explicit send_transactional and send_bulk methods
- Shared suppression list across both categories to protect deliverability
- Separate quotas and rate-limits per category (transactional unthrottled, marketing throttled)
- Recipient-local quiet hours on marketing only, with fresh-auth override
- Separate audit actions (notification.* vs newsletter.*) for clean compliance review
- DOI consent and RFC 8058 one-click unsubscribe enforced on every marketing message
- Tracking disabled on transactional, full opens/clicks/heatmaps on marketing
In practice
A federation runs both flows side by side. A member books a regional course at 23:15 — the booking-confirmation transactional email arrives within seconds, ignoring the 22:00 quiet-hour cutoff because it is service-critical. The next day the federation's newsletter editor schedules a Friday campaign through the newsletter engine; the campaign-dispatcher honours the 5000/h throttle and pauses sends to recipients in time zones where it is night.
A complaint from one recipient writes to the shared suppression list — that address is now safe from both newsletters and the optional ranking-change pings, but still receives mandatory transactional confirmations like password resets. A compliance officer audits the year by filtering sys_audit_entries on newsletter.* actions only, with zero noise from transactional traffic.
Features in this subsystem
5| ID | Status | Features |
|---|---|---|
| F09.09.01 | Shipped | Delad EmailDistributor-abstraktion — send_transactional vs send_bulk-metoder i samma interface, samma backend (Mailjet/ACS/Null) ✅ PL-T152 |
| F09.09.02 | Shipped | Delad suppression-lista (newsletter_suppressions) — hard-bounce/complaint från transactional blockerar även marketing till samma adress och vice versa ✅ PL-T152 |
| F09.09.03 | Shipped | Separata quota/rate-limits — transactional har ingen throttle, marketing cap:ar via campaign throttle_per_hour ✅ PL-T152 |
| F09.09.04 | Shipped | Quiet-hours-policy — marketing-sends pausar 22:00–07:00 recipient-local; transactional oberörda; override kräver fresh-auth ✅ PL-T152 |
| F09.09.05 | Shipped | Separata audit-actions i sys_audit_entries — notification.* för transactional, newsletter.* för marketing; gör det trivialt att revidera varje typ för sig ✅ PL-T152 |