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
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:
@@ -135,39 +135,21 @@ router = APIRouter(prefix="/campaigns", tags=["campaigns"])
|
||||
|
||||
|
||||
def _create_jira_tickets_for_campaign(db: Session, campaign: Campaign, campaign_id: str, user: User) -> None:
|
||||
"""Create Jira tickets for a campaign and its already-linked tests, if missing.
|
||||
"""Create Jira tickets for *campaign* now, if its start_date has arrived.
|
||||
|
||||
Shared by both paths that bring a campaign to ``active``: the admin-only
|
||||
emergency `/activate` override and the normal manager `/approve` flow.
|
||||
Tests may already be linked to the campaign from when it was still a
|
||||
draft, i.e. before any Jira ticket existed for the campaign — so they
|
||||
need their own tickets created here too. Best-effort: failures are
|
||||
logged, not raised, since a Jira outage must not block activation.
|
||||
If ``start_date`` is still in the future, ticket creation is skipped
|
||||
here and left to the periodic ``sync_due_campaign_jira_tickets`` job,
|
||||
which creates them once that date actually arrives — this is what makes
|
||||
the campaign's real scheduled date/time authoritative for when tickets
|
||||
(and their Jira start-date field) appear, instead of always at approval
|
||||
time.
|
||||
"""
|
||||
try:
|
||||
from app.services.jira_service import (
|
||||
auto_create_campaign_issue,
|
||||
auto_create_test_issue,
|
||||
get_campaign_jira_key,
|
||||
get_test_jira_key,
|
||||
)
|
||||
campaign_jira_key = get_campaign_jira_key(db, campaign_id)
|
||||
if not campaign_jira_key:
|
||||
campaign_jira_key = auto_create_campaign_issue(db, campaign, user)
|
||||
if campaign_jira_key:
|
||||
for ct in campaign.campaign_tests:
|
||||
if ct.test and not get_test_jira_key(db, ct.test.id):
|
||||
auto_create_test_issue(
|
||||
db, ct.test, user,
|
||||
parent_ticket_override=campaign_jira_key,
|
||||
campaign_start_date=campaign.start_date,
|
||||
)
|
||||
db.commit()
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Jira ticket creation failed while activating campaign %s",
|
||||
campaign_id,
|
||||
)
|
||||
if campaign.start_date and campaign.start_date > datetime.utcnow():
|
||||
return
|
||||
from app.services.jira_service import ensure_campaign_jira_tickets
|
||||
ensure_campaign_jira_tickets(db, campaign, user)
|
||||
|
||||
|
||||
# ── Pydantic schemas ─────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user