fix(campaigns): defer Jira ticket creation to start_date, gate recurring campaigns behind manager approval
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled

- Approve endpoint now only creates Jira tickets immediately when
  start_date is now/past; a new periodic job (every 15 min) catches
  campaigns whose scheduled start_date has since arrived.
- Recurring campaign clones now go to pending_approval instead of
  active, routing through the same manager-approval gate as any other
  campaign; managers are notified instead of red_tech.
- Fix UTC conversion for the campaign approval start_date input and
  extract shared isoToDatetimeLocal/datetimeLocalToIso helpers.
This commit is contained in:
kitos
2026-07-16 11:09:10 +02:00
parent 0b60531677
commit cf4a6c3cde
9 changed files with 291 additions and 101 deletions
+26 -2
View File
@@ -27,7 +27,10 @@ from app.jobs.jira_sync_job import sync_all_jira_links
from app.jobs.retention_job import run_retention_job
# Import check_and_run_recurring_campaigns from app.services.campaign_scheduler_service
from app.services.campaign_scheduler_service import check_and_run_recurring_campaigns
from app.services.campaign_scheduler_service import (
check_and_run_recurring_campaigns,
sync_due_campaign_jira_tickets,
)
# Import scan_intel from app.services.intel_service
from app.services.intel_service import scan_intel
@@ -164,6 +167,19 @@ def _run_recurring_campaigns() -> None:
db.close()
def _run_due_campaign_jira_sync() -> None:
"""Create Jira tickets for campaigns whose scheduled start_date has arrived."""
logger.info("Scheduled due-campaign Jira sync starting...")
db = SessionLocal()
try:
processed = sync_due_campaign_jira_tickets(db)
logger.info("Due-campaign Jira sync finished — processed %d campaigns", processed)
except Exception:
logger.exception("Due-campaign Jira sync failed")
finally:
db.close()
def _run_intel_scan() -> None:
"""Execute an intel scan inside its own DB session."""
# Log info: "Scheduled intel scan job starting..."
@@ -497,6 +513,14 @@ def start_scheduler() -> None:
# Keyword argument: replace_existing
replace_existing=True,
)
scheduler.add_job(
_run_due_campaign_jira_sync,
trigger="interval",
minutes=15,
id="due_campaign_jira_sync",
name="Due campaign Jira ticket sync (every 15 min)",
replace_existing=True,
)
# Call scheduler.add_job()
scheduler.add_job(
sync_all_jira_links,
@@ -605,7 +629,7 @@ def start_scheduler() -> None:
# Literal argument value
"notification_cleanup (24h), weekly_snapshot (Sundays 00:00), "
# Literal argument value
"recurring_campaigns (daily), jira_sync (1h), "
"recurring_campaigns (daily), due_campaign_jira_sync (15m), jira_sync (1h), "
# Literal argument value
"osint_enrichment (weekly), stale_detection (daily), "
"retention_policies (daily), data_sources_sync (6h), "