[Feature] Use reusable Distribution Lists as immutable Campaign recipient sources #4

Closed
opened 2026-07-14 20:08:41 +02:00 by zemion · 1 comment
Owner

Problem / User Need

One reusable Distribution List must supply multiple Campaigns while each Campaign freezes its own recipients, chosen channels, merge data, review state, and delivery evidence.

Decisions

  • Definitions are live and versioned; every Campaign version stores an immutable expansion snapshot.
  • List entries and provider references have stable IDs/revisions.
  • Provider-neutral metadata stays with the list. Campaign-specific fields, overrides, channel routing, review state, and outcomes stay in Campaign.
  • Derived lists are explicit revision-pinned definitions; there is no implicit live inheritance cascade.
  • Expansion reports missing, stale, inaccessible, ambiguous, cyclic, suppressed, and policy-blocked entries before freeze.
  • Campaign detects revision drift but never silently mutates an already built version.
  • Hybrid delivery is explicit per recipient. Preference/opt-in informs the Policy decision but never silently means multi-channel duplicate delivery.

Scope

  • List source picker, parameter entry, preview, freeze, deliberate refresh, and drift explanation.
  • Preserve list/revision/entry/provider references and applied channel decisions in recipient rows.
  • Reconcile provider/list changes and matching conflicts without module imports.
  • Integrate with Campaign build invalidation and #90 hybrid review/output.

Acceptance Criteria

  • One list supplies multiple campaigns and every frozen recipient is traceable to list revision and entry ID.
  • Campaign enrichment never mutates the reusable list.
  • Refresh is explicit and invalidates downstream build/review state where required.
  • Selected route/fallback and the reasons for unavailable channels are auditable.
  • Both modules remain independently installable.

Parent: #5. Depends on #1-#3 and #7. Related: GovOPlaN/govoplan-campaign#90.

## Problem / User Need One reusable Distribution List must supply multiple Campaigns while each Campaign freezes its own recipients, chosen channels, merge data, review state, and delivery evidence. ## Decisions - Definitions are live and versioned; every Campaign version stores an immutable expansion snapshot. - List entries and provider references have stable IDs/revisions. - Provider-neutral metadata stays with the list. Campaign-specific fields, overrides, channel routing, review state, and outcomes stay in Campaign. - Derived lists are explicit revision-pinned definitions; there is no implicit live inheritance cascade. - Expansion reports missing, stale, inaccessible, ambiguous, cyclic, suppressed, and policy-blocked entries before freeze. - Campaign detects revision drift but never silently mutates an already built version. - Hybrid delivery is explicit per recipient. Preference/opt-in informs the Policy decision but never silently means multi-channel duplicate delivery. ## Scope - List source picker, parameter entry, preview, freeze, deliberate refresh, and drift explanation. - Preserve list/revision/entry/provider references and applied channel decisions in recipient rows. - Reconcile provider/list changes and matching conflicts without module imports. - Integrate with Campaign build invalidation and #90 hybrid review/output. ## Acceptance Criteria - One list supplies multiple campaigns and every frozen recipient is traceable to list revision and entry ID. - Campaign enrichment never mutates the reusable list. - Refresh is explicit and invalidates downstream build/review state where required. - Selected route/fallback and the reasons for unavailable channels are auditable. - Both modules remain independently installable. Parent: #5. Depends on #1-#3 and #7. Related: GovOPlaN/govoplan-campaign#90.
zemion added codex/ready
status
ready
and removed
status
triage
codex/needs-human
labels 2026-07-31 11:41:50 +02:00
zemion changed title from [Feature] Reusable distribution lists as campaign recipient sources to [Feature] Use reusable Distribution Lists as immutable Campaign recipient sources 2026-07-31 14:49:45 +02:00
Author
Owner

Implemented and pushed.

  • Campaign b38597f: optional dist_lists.source / dist_lists.expand integration, source picker, parameter/channel preview, immutable idempotent freeze, campaign-local recipient materialization, provider/list/entry/channel/exclusion provenance, explicit route ambiguity, drift warning and deliberate refresh.
  • Distribution Lists d1c994f: integration boundary and implementation-plan documentation.
  • Core fe62fd4: release-graph and optional-interface contract coverage.

Verification:

  • Campaign backend suite: 82 tests passed.
  • Distribution Lists suite: 10 tests passed.
  • Campaign import WebUI tests passed.
  • Integrated Core WebUI TypeScript check passed.
  • Affected Core module discovery and release-catalog tests passed.

Campaign enrichment does not mutate a reusable list. Non-email recipients remain frozen but inactive until Campaign #90 supplies a compatible output path. Saving an explicit refresh uses the existing Campaign content invalidation path.

Implemented and pushed. - Campaign b38597f: optional dist_lists.source / dist_lists.expand integration, source picker, parameter/channel preview, immutable idempotent freeze, campaign-local recipient materialization, provider/list/entry/channel/exclusion provenance, explicit route ambiguity, drift warning and deliberate refresh. - Distribution Lists d1c994f: integration boundary and implementation-plan documentation. - Core fe62fd4: release-graph and optional-interface contract coverage. Verification: - Campaign backend suite: 82 tests passed. - Distribution Lists suite: 10 tests passed. - Campaign import WebUI tests passed. - Integrated Core WebUI TypeScript check passed. - Affected Core module discovery and release-catalog tests passed. Campaign enrichment does not mutate a reusable list. Non-email recipients remain frozen but inactive until Campaign #90 supplies a compatible output path. Saving an explicit refresh uses the existing Campaign content invalidation path.
zemion removed the codex/ready
status
ready
labels 2026-08-02 17:32:11 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: GovOPlaN/govoplan-dist-lists#4