feat(campaign): bound synchronous delivery
This commit is contained in:
@@ -44,6 +44,7 @@ from govoplan_campaign.backend.schemas import (
|
||||
CampaignSendJobRequest,
|
||||
CampaignSendUnattemptedRequest,
|
||||
CampaignResolveOutcomeRequest,
|
||||
CampaignDeliveryOptionsResponse,
|
||||
CampaignListResponse,
|
||||
CampaignResponse,
|
||||
CampaignVersionDetailResponse,
|
||||
@@ -65,7 +66,7 @@ from govoplan_campaign.backend.schemas import (
|
||||
SendCampaignNowRequest,
|
||||
SendCampaignNowResponse,
|
||||
)
|
||||
from govoplan_core.auth import ApiPrincipal, has_scope, require_scope
|
||||
from govoplan_core.auth import ApiPrincipal, has_scope, require_any_scope, require_scope
|
||||
from govoplan_core.audit.logging import audit_from_principal
|
||||
from govoplan_core.core.access import CAPABILITY_ACCESS_DIRECTORY, AccessDirectory
|
||||
from govoplan_core.core.change_sequence import (
|
||||
@@ -148,6 +149,7 @@ from govoplan_campaign.backend.dev.mock_campaign import MockCampaignSendError, r
|
||||
from govoplan_campaign.backend.sending.execution import ExecutionSnapshotError, clear_execution_snapshot
|
||||
from govoplan_campaign.backend.sending.jobs import (
|
||||
QueueingError,
|
||||
SynchronousSendRejected,
|
||||
cancel_campaign_jobs,
|
||||
enqueue_pending_imap_appends,
|
||||
pause_campaign_jobs,
|
||||
@@ -158,6 +160,7 @@ from govoplan_campaign.backend.sending.jobs import (
|
||||
resume_campaign_jobs,
|
||||
send_campaign_now,
|
||||
send_single_campaign_job,
|
||||
synchronous_send_options,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/campaigns", tags=["campaigns"])
|
||||
@@ -3019,6 +3022,30 @@ def revoke_campaign_share(
|
||||
# Queue / delivery control -------------------------------------------------
|
||||
|
||||
|
||||
@router.get("/{campaign_id}/delivery-options", response_model=CampaignDeliveryOptionsResponse)
|
||||
def campaign_delivery_options(
|
||||
campaign_id: str,
|
||||
version_id: str | None = None,
|
||||
session: Session = Depends(get_session),
|
||||
principal: ApiPrincipal = Depends(
|
||||
require_any_scope("campaigns:campaign:send", "campaigns:campaign:queue")
|
||||
),
|
||||
):
|
||||
_get_campaign_for_principal(session, campaign_id, principal, write=True)
|
||||
_require_permission(principal, "campaigns:recipient:read")
|
||||
try:
|
||||
return CampaignDeliveryOptionsResponse(
|
||||
**synchronous_send_options(
|
||||
session,
|
||||
tenant_id=principal.tenant_id,
|
||||
campaign_id=campaign_id,
|
||||
version_id=version_id,
|
||||
)
|
||||
)
|
||||
except QueueingError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.post("/{campaign_id}/queue", response_model=QueueCampaignResponse)
|
||||
def queue_campaign(
|
||||
campaign_id: str,
|
||||
@@ -3264,12 +3291,7 @@ def send_campaign_now_endpoint(
|
||||
):
|
||||
_get_campaign_for_principal(session, campaign_id, principal, write=True)
|
||||
_require_permission(principal, "campaigns:recipient:read")
|
||||
"""Validate/build/queue and synchronously send every eligible job.
|
||||
|
||||
No server-side job-count bound is currently enforced. Ordinary batches
|
||||
must use the queue/Celery flow; this endpoint is for deliberately small
|
||||
interactive runs.
|
||||
"""
|
||||
"""Preflight and synchronously send a policy-bounded built execution."""
|
||||
|
||||
payload = payload or SendCampaignNowRequest()
|
||||
try:
|
||||
@@ -3320,6 +3342,20 @@ def send_campaign_now_endpoint(
|
||||
commit=True,
|
||||
)
|
||||
return SendCampaignNowResponse(result=result)
|
||||
except SynchronousSendRejected as exc:
|
||||
audit_from_principal(
|
||||
session,
|
||||
principal,
|
||||
action="campaign.send_now_rejected",
|
||||
object_type="campaign",
|
||||
object_id=campaign_id,
|
||||
details={
|
||||
**exc.audit_details(),
|
||||
"version_id": payload.version_id,
|
||||
},
|
||||
commit=True,
|
||||
)
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail=str(exc)) from exc
|
||||
except HTTPException:
|
||||
raise
|
||||
except (CampaignPersistenceError, QueueingError) as exc:
|
||||
|
||||
Reference in New Issue
Block a user