Release govoplan-campaign v0.1.28: stabilize saving, review and delivery recovery
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-09-08 01:32:26 +02:00
parent 1b32427813
commit c51fc180fb
111 changed files with 6905 additions and 980 deletions
+218 -5
View File
@@ -186,6 +186,11 @@ configured timeout. Opening the link never completes the Workflow.
password generator keeps its candidate separate from the form until **Use
password** is explicitly confirmed. Copying a candidate does not save or
submit it.
If legacy transport data is reported, choose **Migrate selected Mail
profile**, including when the existing profile selection is unchanged.
Follow a locked version's supported unlock or editable-successor action
before migration. Migration is explicit and audited, never sends mail, and
requires validation, build, and review again.
6. Save the editable version, validate the relevant sections, and resolve every
blocking issue. Warnings remain explicit review decisions.
7. Build the exact messages and inspect recipient, addressing, template,
@@ -195,11 +200,77 @@ If a selected optional module is absent, Campaign remains loadable and explains
which function is unavailable. It must not fail startup because Mail, Files, or
Addresses is not installed.
Opening or leaving Template without editing does not change the saved HTML or
mark the page dirty. Visual/source inspection and read-only changes likewise
do not require a save. Actual saves send only client-owned editor metadata. Review
and approval evidence remains server-owned and cannot be overwritten by an
ordinary editor save. Omitting that readable evidence from a save does not
delete it; normal version-lock and invalidation rules remain authoritative.
### Preserve recipient address order
In an individual or global address dialog, use the up/down actions to arrange
the addresses, then choose **Save** in the dialog. The campaign draft keeps that
order; saving no longer alphabetically sorts it. Duplicate email addresses keep
their first position, and pasted addresses append in their entered order.
The first individual To address is also the primary name/email shown in the
recipient row. Use the page's **Save** to persist the campaign draft. A rejected
page save keeps the reordered draft for an explicit retry. **Cancel** in the
dialog discards only its unconfirmed changes.
### Permit Legacy ZipCrypto as an explicit compatibility exception
AES remains the secure default. Campaign **Settings**, **Policies**, and
**Attachments** expose the effective archive policy, configuration links for
authorized administrators, and **Reload archive policy**.
1. A policy administrator opens **Administration → SYSTEM → Campaign archive
encryption**, enables **Legacy ZipCrypto**, and saves. The controls work
before the first system override exists; opening defaults alone does not
create an override or unsaved changes. Changing this global ceiling requires
both `system:settings:write` and `admin:policies:write`; tenant policy
authority alone cannot loosen it.
2. Check tenant and owner policy restrictions. Lower scopes may narrow, never
loosen, inherited methods and password-delivery channels.
3. The Campaign actor also needs `campaigns:archive:use_legacy_zipcrypto` and
edit access to the selected version. Policy administration does not replace
that dedicated permission.
4. Return to Campaign, reload archive policy, and select **Legacy ZipCrypto**
under **Attachments → ZIP attachments**. Acknowledge weak encryption, enter
an operational reason of at least 10 characters, and select an allowed
separate password-delivery channel.
5. Save, validate, build, and review. Policy/configuration saves never send
mail; delivery remains a separate action.
Legacy remains blocked while Policy is unavailable. Neither an encryption
error nor an incompatible client causes automatic fallback from AES to
ZipCrypto. The build retains policy and acknowledgement evidence but never the
password; see the manifest topic `campaigns.archive-encryption-governance`.
Mail migration and ZIP corrections can be saved in either order. A Mail-only
migration preserves unchanged ZIP settings without granting permission to use
them or adding acknowledgement evidence. An archive correction with unchanged
Mail references preserves legacy transport server-side until its separate,
explicit migration. Changes to ZIP settings still require the current policy
and any dedicated legacy permission; changes to Mail references still require
authorized migration. Validate, build and review again after both repairs.
A save and the following workspace refresh are separate operations. A failed
refresh does not undo a committed save or clear the last usable workspace.
Keep any newer unsaved edits, inspect the refresh error, and use Reload to fetch
the current state. Responses for an earlier campaign, version or signed-in
identity cannot overwrite the current workspace.
### Review and complete review
The reviewer should verify the immutable candidate that will be delivered, not
just the authoring form:
If a legacy Mail migration notice appears, follow **Open Mail settings** for
that exact version, complete migration, and validate and build again. Review
stays read-only until migration is resolved and does not repeatedly request
an attachment preview that the legacy transport boundary must reject.
1. Confirm purpose, owner, selected version, and recipient count.
2. Inspect blocking errors, warnings, exclusions, and recipients requiring
review.
@@ -223,6 +294,67 @@ the required action, the responsible role, and the workspace to open. The
review summary keeps reviewed and remaining counts visible; a completed review
acknowledges the group items and remains bound to the current build token.
Save each individual acceptance to persist its reason and reviewed state before
completing the entire review. Wait for acknowledgement; reloading then resumes
that build's saved progress. If saving fails or conflicts, the pending note
remains available for an explicit retry rather than becoming a false success.
This small save only loads the selected persisted jobs: it does not rebuild
messages, materialize attachments, or reload the whole workspace. Another
reviewer's existing decisions and attribution remain intact. Partial progress
does not enable delivery; final completion still checks the complete build.
Use **Accept similar review conditions** to record the same decision for a
counted selection of currently loaded matching messages. The server defines
eligible categories from the complete combination of overridable conditions;
the UI does not interpret a warning badge as permission to override. Select
one category, inspect the listed recipients, deselect any exceptions and enter
a common reason (required for attachment exceptions). A submission contains
at most 200 explicit message IDs. When more remain, save this selection and
reopen the dialog; the counts never imply acceptance of unloaded messages or
other categories. The reason is recorded separately against each selected
message's frozen evidence. A failed save retains the selection and reason for
an explicit retry, while a changed build prevents stale acceptance. This
action neither sends messages nor completes the final review gate. Hard
blockers cannot be accepted this way. Deliberate policy exclusions and
attachment rules that explicitly permit zero matches remain informational
and do not require review decisions.
An optional rule with explicit `missing_behavior: continue` may yield no files
without creating review work; that outcome remains informational evidence.
Required attachment and hard-block policies cannot be weakened by this setting.
The separate policy for sending a wholly attachment-free message still applies.
Rebuild existing messages after changing attachment policy; historical build
evidence is not rewritten.
The incremental review API uses `merge_progress: true`, the acknowledged
`base_revision`, and `build_token` set to the public `review_build_token`.
It merges exact reviewed keys/decision job IDs for the current build, with an
optional `decision_category_key` to bind a grouped acceptance. The safe review
reference is available without diagnostic access; raw build tokens remain
diagnostic data. Stale build/revision or simultaneous writes return HTTP 409
without overwriting progress. Normal review authorization and audit apply.
Accepted or expected attachment conditions remain satisfied in **Confirm and
send** for the same build. Raw missing/ambiguous source counts remain visible
for context; they are not a second approval gate. Reviewed-stage mock delivery
uses `use_reviewed_build: true`: it verifies the existing execution seal,
completed review, frozen job issues and EML integrity, and current Mail transport
before capturing anything in the mock mailbox. It uses those stored messages,
not freshly rendered replacements, and never mutates Campaign delivery state.
Stale review, changed inputs, changed bytes or changed transport stop the test
before captures or requested mailbox clearing. The authoring/mock-preview API
keeps its existing transient-build default; `include_needs_review` does not
bypass frozen review checks.
Validation details and repeated-file lists use the shared DataGrid pagination
controls so every item is reachable. Related missing-rule causes and their
attachment-free policy outcomes appear together, with the technical evidence
still expandable. Built messages have four operational states: **Ready**,
**Needs review**, **Blocked**, and **Excluded**, plus an explanatory column.
Accepted explicit decisions are Ready; warnings awaiting acknowledgment remain
Needs review. This presentation does not remove or rewrite frozen issues or
audit evidence.
This evidence is the Campaign input to separation-of-duties policy. Generic
approve/reject chains, delegation, substitutions, escalation, and signatures
belong to the optional Approvals capability. Campaign must not claim an
@@ -279,7 +411,7 @@ At a minimum:
ordinary batches; the durable progress remains visible after leaving and
returning to Review and send.
2. Use **Send now** only when the exact persisted eligible build is within the
effective synchronous limit shown by the UI. The default deployment limit
effective synchronous limit shown by the UI. The unchanged default limit
is 25 recipient jobs. The backend repeats the count and preflights every
message and the Mail profile revision before contacting SMTP.
3. Treat `smtp_accepted` as protected from ordinary retry.
@@ -302,10 +434,24 @@ Pause stops new eligible work but cannot undo a provider effect already in
progress. Cancel marks work that has not yet produced a protected SMTP outcome;
it cannot recall accepted mail.
The deployment ceiling is configured with
`GOVOPLAN_CAMPAIGN_SYNCHRONOUS_SEND_MAX_RECIPIENTS` (0 disables Send now; the
accepted range is 0500). A tenant may only narrow that ceiling with
`tenant.settings.campaign_delivery_policy.synchronous_send_max_recipients`.
Configure **Administration → SYSTEM → Campaign delivery** with
`system:settings:read/write`. The default stays 25, but an administrator may
explicitly choose 0500, for example 200 for a 183-recipient-job run. Zero disables
Send now. **TENANT → Campaign delivery** uses `admin:policies:read/write` and may
only narrow the inherited system policy. Clearing an override restores
inheritance. An explicitly configured deployment ceiling
`GOVOPLAN_CAMPAIGN_SYNCHRONOUS_SEND_MAX_RECIPIENTS` remains authoritative; the
implicit default does not prevent a system administrator choosing a larger
bounded value. Save changes only this setting, preserves unrelated settings,
checks a revision token including inherited policy, and records before/after
configuration history and audit. Failed saves retain the draft; conflicting
saves require explicit reload/reconciliation. Policy edits never send mail or
change existing reviews or approval requirements.
This limit applies to one interactive Send now request, not campaign size or
worker batching. Larger interactive requests run longer and can meet proxy
timeouts. Queue for workers is independent and requires enabled, healthy
Redis/Celery infrastructure; changing the numeric limit does not start workers.
The effective value and source are returned by the protected delivery-options
API, recorded for successful/rejected synchronous commands, and stated in the
configured handbook topic.
@@ -466,6 +612,73 @@ create an editable successor.
## Operations and recovery
### Interactive delivery and Sent-folder progress
Send now and workerless Report retry/continue use a compact blocking progress
dialog, as does inline append-to-Sent. It refreshes saved counters only, not the
whole campaign behind the overlay. Successful, pending, in-progress, failed,
uncertain and excluded messages are shown separately; a currently sending or
appending message therefore does not disappear between totals. Read errors keep
the last known counters. After a connection interruption, processing may still
be running; inspect saved evidence before repeating any action. A successful
write is not reclassified as failed when its later display refresh fails.
The recipient-aware Report shows all frozen To, Cc and Bcc addresses, not only
the primary row identity. Address order and recipient-read authorization remain
unchanged. SMTP/IMAP diagnostics use translated status-list filters.
Without workers, explicitly retry eligible failures or continue unattempted
jobs through Report. Each request uses the canonical job/attempt recovery
boundary and is limited by the effective synchronous policy. Accepted and
uncertain SMTP outcomes remain protected. Active abandoned claims require an
expired durable lease, proven stopped/replaced owner, current revision and
valid original evidence before recovery can mark them unknown. A separate
evidence-note reconciliation is required before retrying. A timeout alone is
never proof of non-delivery. See the delivery runbook for required permissions
and operational limitations.
Append-to-Sent is scoped to the selected version and reuses a bounded Mail-owned
connection/folder resolution (default 100 messages or 300 seconds), while
performing one sequential APPEND and all current checks per message. Uncertain
appends are never automatically repeated, and repairing Sent never resends SMTP.
Link required files before locking. Lock and validate waits for attachment
matches, rechecks them immediately before locking, and asks for Link and lock
confirmation if new unlinked files are found. A locked version cannot acquire
new attachment links; use an editable version and validate/build/review again.
### Fortschritt, Wiederherstellung und Dateiverknüpfungen
Jetzt senden, synchrone Wiederholung/Fortsetzung im Bericht und Kopieren nach
Gesendet verwenden einen kompakten sperrenden Fortschrittsdialog. Nur gespeicherte
Zähler werden aktualisiert, nicht der Arbeitsbereich im Hintergrund. Erfolgreich,
ausstehend, in Bearbeitung, fehlgeschlagen, ungewiss und ausgeschlossen bleiben
getrennt sichtbar. Bei Lesefehlern bleiben die letzten Werte erhalten. Nach einer
getrennten Verbindung kann die Verarbeitung weiterlaufen; prüfen Sie Nachweise,
bevor Sie erneut handeln. Ein bestätigter Versand wird durch einen nachfolgenden
Anzeigefehler nicht nachträglich als fehlgeschlagen dargestellt.
Der empfängerbezogene Bericht zeigt alle eingefrorenen An-, Cc- und Bcc-Adressen
in ihrer Reihenfolge. Leseberechtigungen bleiben unverändert. SMTP und IMAP
verwenden übersetzte Zustandslisten zum Filtern.
Ohne Worker können bekannte Fehler ausdrücklich wiederholt und unversuchte
Aufträge begrenzt fortgesetzt werden. Die wirksame synchrone Grenze, gespeicherte
Aufträge, Prüfungen, Freigaben und Wiederherstellungsnachweise bleiben verbindlich.
Angenommene und ungewisse SMTP-Ergebnisse werden nicht blind wiederholt. Die
Wiederherstellung aktiver, verlassener Aufträge benötigt eine abgelaufene Sperre,
nachweislich gestoppte/ersetzte Laufzeit und gültige ursprüngliche Nachweise. Sie
setzt ausschließlich auf ungewiss; vor Wiederholung sind externe Nachweise und
ein getrennter Abgleich mit Notiz erforderlich. Zeitablauf allein genügt nicht.
Kopieren nach Gesendet betrifft nur die ausgewählte Version. Mail verwendet die
Verbindung und Ordnerauflösung begrenzt wieder (Standard: 100 Nachrichten oder
300 Sekunden), prüft aber jede Nachricht erneut und führt APPEND nacheinander
aus. Ungewisse Ergebnisse werden nicht automatisch wiederholt. Verknüpfen Sie
benötigte Dateien vor dem Sperren; eine frische Prüfung fragt bei unverknüpften
Treffern nach Verknüpfen und sperren. Gesperrte Versionen benötigen zum Ändern
eine bearbeitbare Version mit erneuter Validierung, Build und Prüfung.
### Health to observe
- database and migration health;