feat(campaigns): add accountable work assignments
Module Package Release / publish-packages (push) Successful in 14s

This commit is contained in:
2026-08-22 00:50:03 +02:00
parent c2f083e5f6
commit 2630498026
23 changed files with 3011 additions and 15 deletions
+53
View File
@@ -19,6 +19,8 @@ from govoplan_campaign.backend.db.models import (
CampaignSchedule,
CampaignShare,
CampaignVersion,
CampaignWorkAssignment,
CampaignWorkAssignmentEvent,
ImapAppendAttempt,
PostboxDeliveryAttempt,
PrintOutputAttempt,
@@ -102,6 +104,8 @@ class CampaignDsarProviderTests(unittest.TestCase):
Campaign.__table__,
CampaignShare.__table__,
CampaignCollaborationEntry.__table__,
CampaignWorkAssignment.__table__,
CampaignWorkAssignmentEvent.__table__,
CampaignVersion.__table__,
CampaignJob.__table__,
CampaignIssue.__table__,
@@ -437,6 +441,7 @@ class CampaignDsarProviderTests(unittest.TestCase):
self.session.commit()
self.provider = CampaignDsarProvider()
self.subject = DsarSubjectRef(
account_id=self.account.id,
membership_id=self.user.id,
email="subject@example.test",
)
@@ -455,6 +460,54 @@ class CampaignDsarProviderTests(unittest.TestCase):
{topic.id for topic in manifest.documentation},
)
def test_search_includes_account_assignment_and_immutable_lifecycle_evidence(self) -> None:
now = datetime.now(timezone.utc)
assignment = CampaignWorkAssignment(
id="work-assignment-subject",
tenant_id="tenant-1",
campaign_id=self.campaign.id,
purpose="Review the individualized notice",
status="open",
assignee_type="account",
assignee_id=self.account.id,
assignee_label_snapshot="Subject",
assignee_resolution_state="resolved",
resolution_provenance={"policy_code": "assignment_does_not_grant_access"},
resolution_checked_at=now,
assigned_by_user_id=self.other_user.id,
assigned_by_label_snapshot="Other",
)
event = CampaignWorkAssignmentEvent(
id="work-assignment-event-subject",
tenant_id="tenant-1",
campaign_id=self.campaign.id,
assignment_id=assignment.id,
event_kind="assigned",
actor_user_id=self.other_user.id,
actor_label_snapshot="Other",
status_snapshot="open",
assignee_type_snapshot="account",
assignee_id_snapshot=self.account.id,
assignee_label_snapshot="Subject",
resolution_state_snapshot="resolved",
)
self.session.add_all((assignment, event))
self.session.commit()
records = self.provider.search_subject(
self.session,
tenant_id="tenant-1",
subject=self.subject,
)
work = next(item for item in records if item.resource_type == "campaign_work_assignment")
history = next(item for item in records if item.resource_type == "campaign_work_assignment_event")
self.assertIn("assignee_id", work.data["match_fields"])
self.assertEqual("Review the individualized notice", work.data["purpose"])
self.assertFalse(work.immutable_evidence)
self.assertTrue(history.immutable_evidence)
self.assertIn("accountable institutional work history", history.retention_reason)
def test_search_is_tenant_scoped_minimized_and_recipient_specific(self) -> None:
records = self.provider.search_subject(
self.session,