feat: orchestrate accountable Campaign work
Module Package Release / publish-packages (push) Successful in 13s
Module Package Release / publish-packages (push) Successful in 13s
This commit is contained in:
@@ -43,6 +43,13 @@ from govoplan_core.core.idm import (
|
||||
CAPABILITY_IDM_FUNCTION_ASSIGNMENTS,
|
||||
IdmFunctionAssignmentDirectory,
|
||||
)
|
||||
from govoplan_core.core.events import (
|
||||
EventActorRef,
|
||||
EventObjectRef,
|
||||
EventTenantRef,
|
||||
PlatformEvent,
|
||||
emit_platform_event,
|
||||
)
|
||||
from govoplan_core.core.notifications import (
|
||||
NotificationDispatchRequest,
|
||||
notification_dispatch_provider,
|
||||
@@ -127,7 +134,10 @@ def list_campaign_work_assignments(
|
||||
campaign = _get_campaign_for_principal(session, campaign_id, principal)
|
||||
_require_permission(principal, "campaigns:campaign:read")
|
||||
statuses = tuple(dict.fromkeys(item.strip() for item in assignment_status if item.strip()))
|
||||
if any(item not in {"open", "in_progress", "completed", "cancelled"} for item in statuses):
|
||||
if any(
|
||||
item not in {"open", "in_progress", "completed", "rejected", "cancelled"}
|
||||
for item in statuses
|
||||
):
|
||||
raise HTTPException(status_code=422, detail="Unsupported assignment status filter.")
|
||||
query = session.query(CampaignWorkAssignment).filter(
|
||||
CampaignWorkAssignment.tenant_id == principal.tenant_id,
|
||||
@@ -288,12 +298,20 @@ def transition_campaign_work_assignment(
|
||||
if payload.action == "cancel":
|
||||
raise HTTPException(status_code=403, detail="Only an assignment manager may cancel work.")
|
||||
_require_revision(assignment, payload.expected_revision)
|
||||
target_status = {"start": "in_progress", "complete": "completed", "cancel": "cancelled"}[payload.action]
|
||||
target_status = {
|
||||
"accept": "in_progress",
|
||||
"start": "in_progress",
|
||||
"complete": "completed",
|
||||
"reject": "rejected",
|
||||
"cancel": "cancelled",
|
||||
}[payload.action]
|
||||
if assignment.status == target_status:
|
||||
return _assignment_response(assignment)
|
||||
allowed = {
|
||||
"accept": {"open"},
|
||||
"start": {"open"},
|
||||
"complete": {"open", "in_progress"},
|
||||
"reject": {"open", "in_progress"},
|
||||
"cancel": {"open", "in_progress"},
|
||||
}
|
||||
if assignment.status not in allowed[payload.action]:
|
||||
@@ -306,7 +324,13 @@ def transition_campaign_work_assignment(
|
||||
session,
|
||||
assignment=assignment,
|
||||
principal=principal,
|
||||
event_kind={"start": "started", "complete": "completed", "cancel": "cancelled"}[payload.action],
|
||||
event_kind={
|
||||
"accept": "accepted",
|
||||
"start": "started",
|
||||
"complete": "completed",
|
||||
"reject": "rejected",
|
||||
"cancel": "cancelled",
|
||||
}[payload.action],
|
||||
details={"reason": payload.reason},
|
||||
)
|
||||
_notify_assignment(session, campaign=campaign, assignment=assignment, event_kind=payload.action)
|
||||
@@ -697,6 +721,51 @@ def _record_event(
|
||||
)
|
||||
session.add(event)
|
||||
session.flush()
|
||||
emit_platform_event(
|
||||
session,
|
||||
PlatformEvent(
|
||||
type="campaign.work.changed",
|
||||
module_id="campaigns",
|
||||
event_id=event.id,
|
||||
occurred_at=event.created_at,
|
||||
correlation_id=assignment.orchestration_correlation_id,
|
||||
causation_id=assignment.workflow_step_id,
|
||||
actor=EventActorRef(
|
||||
type="account",
|
||||
id=principal.account_id,
|
||||
label=_actor_label(principal),
|
||||
),
|
||||
tenant=EventTenantRef(id=assignment.tenant_id),
|
||||
subject=EventObjectRef(
|
||||
type="campaign_work_assignment",
|
||||
id=assignment.id,
|
||||
),
|
||||
resource=EventObjectRef(
|
||||
type="campaign",
|
||||
id=assignment.campaign_id,
|
||||
),
|
||||
classification="internal",
|
||||
payload={
|
||||
"campaign_id": assignment.campaign_id,
|
||||
"campaign_version_id": assignment.campaign_version_id,
|
||||
"assignment_id": assignment.id,
|
||||
"assignment_revision": assignment.resource_revision,
|
||||
"assignment_ref": (
|
||||
"campaign-work-assignment:"
|
||||
f"{assignment.id}:r{assignment.resource_revision}"
|
||||
),
|
||||
"outcome": event_kind,
|
||||
"status": assignment.status,
|
||||
"assignee_type": assignment.assignee_type,
|
||||
"assignee_id": assignment.assignee_id,
|
||||
"action_url": (
|
||||
f"/campaigns/{assignment.campaign_id}/work"
|
||||
f"?assignment={assignment.id}"
|
||||
),
|
||||
},
|
||||
),
|
||||
registry=get_registry(),
|
||||
)
|
||||
return event
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user