docs(campaign): document aggregate report baseline
This commit is contained in:
@@ -144,10 +144,14 @@ paths, storage keys, worker claim tokens, and raw provider diagnostics require
|
|||||||
the dedicated diagnostic permission and must not leak through ordinary campaign,
|
the dedicated diagnostic permission and must not leak through ordinary campaign,
|
||||||
version, job, or report responses.
|
version, job, or report responses.
|
||||||
|
|
||||||
The current Campaign Report Web UI additionally requires recipient-read access
|
Campaign now provides a separate aggregate **Reports** surface for readers with
|
||||||
and does not yet hide every action control that the actor lacks. The server
|
`campaigns:report:read` and access to the campaign. It loads only the safe
|
||||||
still authorizes each action, but an aggregate-only reader UI remains open
|
aggregate projections, applies small-cell suppression, and offers no recipient
|
||||||
work; do not promise that experience from `campaigns:report:read` alone.
|
rows, drill-down, filtering, export, or delivery actions. The recipient-aware
|
||||||
|
**Campaign Report** still requires recipient-read access and does not yet hide
|
||||||
|
every action control that the actor lacks. The server authorizes each action,
|
||||||
|
but permission-aware action visibility on that detailed surface remains open
|
||||||
|
work; do not confuse it with the aggregate reader experience.
|
||||||
|
|
||||||
### Deliver and resolve outcomes
|
### Deliver and resolve outcomes
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
@@ -364,6 +365,18 @@ def test_aggregate_report_task_never_implies_recipient_detail_or_export_authorit
|
|||||||
assert "export" in topic.metadata["verification"].lower()
|
assert "export" in topic.metadata["verification"].lower()
|
||||||
|
|
||||||
|
|
||||||
|
def test_handbook_distinguishes_shipped_aggregate_reports_from_detailed_report_gaps() -> None:
|
||||||
|
handbook = " ".join(
|
||||||
|
(
|
||||||
|
Path(__file__).resolve().parents[1] / "docs" / "CAMPAIGN_HANDBOOK.md"
|
||||||
|
).read_text(encoding="utf-8").lower().split()
|
||||||
|
)
|
||||||
|
|
||||||
|
assert "aggregate-only reader ui remains open" not in handbook
|
||||||
|
assert "separate aggregate **reports** surface" in handbook
|
||||||
|
assert "permission-aware action visibility on that detailed surface remains open work" in handbook
|
||||||
|
|
||||||
|
|
||||||
def test_static_campaign_handbook_has_unique_ids_help_contexts_and_no_planned_resend_claim() -> None:
|
def test_static_campaign_handbook_has_unique_ids_help_contexts_and_no_planned_resend_claim() -> None:
|
||||||
from govoplan_campaign.backend.manifest import get_manifest
|
from govoplan_campaign.backend.manifest import get_manifest
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user