Implement governed hybrid campaign delivery

This commit is contained in:
2026-08-02 13:58:37 +02:00
parent b38597f2be
commit 7733265cc8
40 changed files with 2531 additions and 122 deletions
+14 -7
View File
@@ -28,12 +28,14 @@ provider contract. Reporting owns the global `/reports` route. Campaign keeps
its module-local `/campaigns/reports` view and does not claim the global route
when Reporting is absent.
Generated EML is durable execution material, not a node-local runtime cache.
Campaign stores it through Core's shared object-storage contract under opaque
Campaign-owned keys; database job rows retain the expected size, digest, and
Message-ID. Workers resolve and verify the object before delivery. Build
failure compensates objects written before database commit, and retention keeps
the database reference when object deletion fails so cleanup can be retried.
Generated EML and printable artifacts are durable execution material, not a
node-local runtime cache. Campaign stores EML through Core's shared
object-storage contract under opaque Campaign-owned keys. Templates returns a
bounded artifact or a Files-managed artifact for printable output. Database job
rows retain the expected hashes and provenance. Workers resolve and verify the
frozen evidence before delivery. Build failure compensates objects written
before database commit, and retention keeps database references when object
deletion fails so cleanup can be retried.
## Dependencies
@@ -41,10 +43,15 @@ The module has one required runtime dependency:
- `govoplan-core` for platform services, auth, RBAC, DB/session lifecycle, migrations, and WebUI shell integration
Files and mail are optional module integrations declared in the campaign manifest:
Files, Mail, Distribution Lists, Templates, and Postbox are optional module integrations declared in the campaign manifest:
- `govoplan-files` enables managed attachment selection, frozen file-version evidence, and managed-file usage tracking. Server/API campaigns require this integration for attachments and never resolve caller-supplied local filesystem paths. Legacy file-oriented loading remains available only to explicitly trusted operator/library workflows.
- `govoplan-mail` owns reusable profiles, encrypted SMTP/IMAP credentials, delivery policy checks, connection tests, and transport execution. Campaign JSON stores only `server.mail_profile_id`; inline transport settings and credentials are rejected. Without Mail, campaigns can still be authored, but profile validation and real delivery are unavailable.
- `govoplan-dist-lists` expands reusable governed audiences. Campaign freezes the exact list revision, provider evidence, candidates, and explicit per-recipient primary/fallback route into its own version.
- `govoplan-templates` validates and renders published label, envelope, letter, and list-layout templates for postal or internal-mail delivery. Generated output is hash-bound to its template, inputs, actor, route decisions, and Campaign version.
- `govoplan-postbox` resolves exact or organization-derived Postbox targets and records provider acceptance and receipt evidence. It remains optional; Mail-only and print-only campaigns do not require it.
Hybrid delivery never treats an opt-in as an implicit duplicate-send instruction. The Campaign author selects one primary route per recipient and may select a supported fallback. A fallback runs only after the first channel rejects before acceptance; accepted or outcome-unknown effects stop cross-channel retry. Printable output is generated once during build, optionally persisted through Files, reviewed with the exact Campaign version, and accepted idempotently per recipient job during delivery.
Public campaign, version, job, and report responses expose business data and
delivery evidence, but never process-local paths, storage-backend keys, or