Add governed automation contracts

This commit is contained in:
2026-07-28 15:02:42 +02:00
parent baa2143a26
commit 26ae034153
10 changed files with 539 additions and 0 deletions

View File

@@ -4,6 +4,10 @@ from celery import Celery
from govoplan_core.core.campaigns import CAPABILITY_CAMPAIGNS_DELIVERY_TASKS, CampaignDeliveryTaskProvider
from govoplan_core.core.calendar import CAPABILITY_CALENDAR_OUTBOX, CalendarOutboxProvider
from govoplan_core.core.dataflows import (
CAPABILITY_DATAFLOW_TRIGGER_DISPATCHER,
DataflowTriggerDispatcher,
)
from govoplan_core.core.module_management import load_startup_enabled_modules, startup_candidate_module_ids
from govoplan_core.core.modules import ModuleContext
from govoplan_core.core.notifications import CAPABILITY_NOTIFICATIONS_DISPATCH, NotificationDispatchProvider
@@ -29,6 +33,7 @@ celery.conf.update(
"govoplan.notifications.deliver": {"queue": "notifications"},
"govoplan.notifications.deliver_pending": {"queue": "notifications"},
"govoplan.calendar.dispatch_outbox": {"queue": "calendar"},
"govoplan.dataflow.dispatch_triggers": {"queue": "dataflow"},
},
worker_prefetch_multiplier=1,
task_acks_late=True,
@@ -39,6 +44,11 @@ celery.conf.update(
"schedule": 60.0,
"args": (None, 100),
},
"dataflow-triggers-every-minute": {
"task": "govoplan.dataflow.dispatch_triggers",
"schedule": 60.0,
"args": (100,),
},
},
)
@@ -86,6 +96,18 @@ def _calendar_outbox() -> CalendarOutboxProvider | None:
return capability
def _dataflow_trigger_dispatcher() -> DataflowTriggerDispatcher | None:
registry = _platform_registry()
if not registry.has_capability(CAPABILITY_DATAFLOW_TRIGGER_DISPATCHER):
return None
capability = registry.require_capability(
CAPABILITY_DATAFLOW_TRIGGER_DISPATCHER
)
if not isinstance(capability, DataflowTriggerDispatcher):
raise RuntimeError("Dataflow trigger dispatcher capability is invalid")
return capability
@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.
@@ -149,3 +171,29 @@ def dispatch_calendar_outbox(self, tenant_id: str | None = None, limit: int = 50
result = dict(provider.dispatch_due(session, tenant_id=tenant_id, limit=limit))
session.commit()
return result
@celery.task(
name="govoplan.dataflow.dispatch_triggers",
bind=True,
max_retries=0,
)
def dispatch_dataflow_triggers(self, limit: int = 100):
"""Drain durable Dataflow trigger deliveries and due schedules."""
from govoplan_core.db.session import get_database
with get_database().SessionLocal() as session:
provider = _dataflow_trigger_dispatcher()
if provider is None:
return {
"queued": 0,
"processed": 0,
"succeeded": 0,
"failed": 0,
"blocked": 0,
"skipped": 0,
}
result = dict(provider.dispatch_due(session, limit=limit))
session.commit()
return result