feat: add governed DSAR workflow
This commit is contained in:
@@ -18,7 +18,9 @@ from celery.signals import (
|
||||
|
||||
from govoplan_core.core.campaigns import (
|
||||
CAPABILITY_CAMPAIGNS_DELIVERY_TASKS,
|
||||
CAPABILITY_CAMPAIGNS_SCHEDULES,
|
||||
CampaignDeliveryTaskProvider,
|
||||
CampaignScheduleProvider,
|
||||
)
|
||||
from govoplan_core.core.calendar import (
|
||||
CAPABILITY_CALENDAR_OUTBOX,
|
||||
@@ -100,6 +102,7 @@ celery.conf.update(
|
||||
task_routes={
|
||||
"govoplan.campaigns.send_email": {"queue": "send_email"},
|
||||
"govoplan.campaigns.append_sent": {"queue": "append_sent"},
|
||||
"govoplan.campaigns.dispatch_schedules": {"queue": "default"},
|
||||
"govoplan.notifications.deliver": {"queue": "notifications"},
|
||||
"govoplan.notifications.deliver_pending": {"queue": "notifications"},
|
||||
"govoplan.mail.dispatch_outbox": {"queue": "mail"},
|
||||
@@ -132,6 +135,11 @@ celery.conf.update(
|
||||
"schedule": 60.0,
|
||||
"args": (None, 100),
|
||||
},
|
||||
"campaign-schedules-every-minute": {
|
||||
"task": "govoplan.campaigns.dispatch_schedules",
|
||||
"schedule": 60.0,
|
||||
"args": (None, 50),
|
||||
},
|
||||
"mail-outbox-every-five-seconds": {
|
||||
"task": "govoplan.mail.dispatch_outbox",
|
||||
"schedule": 5.0,
|
||||
@@ -555,6 +563,18 @@ def _campaign_delivery_tasks(
|
||||
return capability
|
||||
|
||||
|
||||
def _campaign_schedules(
|
||||
registry: PlatformRegistry | None = None,
|
||||
) -> CampaignScheduleProvider | None:
|
||||
registry = registry or _platform_registry()
|
||||
if not registry.has_capability(CAPABILITY_CAMPAIGNS_SCHEDULES):
|
||||
return None
|
||||
capability = registry.require_capability(CAPABILITY_CAMPAIGNS_SCHEDULES)
|
||||
if not isinstance(capability, CampaignScheduleProvider):
|
||||
raise RuntimeError("Campaign schedule capability is invalid")
|
||||
return capability
|
||||
|
||||
|
||||
def _notification_dispatch(
|
||||
registry: PlatformRegistry | None = None,
|
||||
) -> NotificationDispatchProvider:
|
||||
@@ -699,6 +719,52 @@ def _idm_assignment_lifecycle(
|
||||
return capability
|
||||
|
||||
|
||||
@celery.task(
|
||||
name="govoplan.campaigns.dispatch_schedules",
|
||||
bind=True,
|
||||
max_retries=0,
|
||||
)
|
||||
def dispatch_campaign_schedules(
|
||||
self,
|
||||
tenant_id: str | None = None,
|
||||
limit: int = 50,
|
||||
):
|
||||
"""Prepare due campaign drafts; delivery always remains a separate action."""
|
||||
|
||||
from govoplan_core.db.session import get_database
|
||||
|
||||
with get_database().SessionLocal() as session:
|
||||
registry = _platform_registry()
|
||||
defaults = {
|
||||
"selected": 0,
|
||||
"prepared": 0,
|
||||
"failed": 0,
|
||||
"completed": 0,
|
||||
"coalesced": 0,
|
||||
"campaign_ids": [],
|
||||
"operator_actions": [],
|
||||
}
|
||||
if not registry.has_capability(CAPABILITY_CAMPAIGNS_SCHEDULES):
|
||||
return defaults
|
||||
result = _run_tenant_worker_batches(
|
||||
registry,
|
||||
session,
|
||||
capability_name=CAPABILITY_CAMPAIGNS_SCHEDULES,
|
||||
tenant_id=tenant_id,
|
||||
operation=lambda effective_tenant_id: _campaign_schedules(
|
||||
registry
|
||||
).dispatch_due( # type: ignore[union-attr]
|
||||
session,
|
||||
tenant_id=effective_tenant_id,
|
||||
limit=limit,
|
||||
),
|
||||
defaults=defaults,
|
||||
work_state="new",
|
||||
)
|
||||
session.commit()
|
||||
return result
|
||||
|
||||
|
||||
@celery.task(name="govoplan.campaigns.send_email", bind=True, max_retries=0)
|
||||
def send_email(self, job_id: str):
|
||||
"""Send one explicitly queued campaign job.
|
||||
|
||||
Reference in New Issue
Block a user