fix(campaigns): filter existing-test picker to draft + not in any campaign
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

Backend: add not_in_any_campaign filter to list_tests (subquery on
CampaignTest) and expose it as a query param on GET /tests.
Frontend: the 'Existing Test' tab now requests only
  state=draft & not_in_any_campaign=true
so tests already linked to any campaign or not in draft state
are never shown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-05-29 09:55:02 +02:00
parent b19ecc0d5f
commit c467459b51
4 changed files with 13 additions and 2 deletions

View File

@@ -19,6 +19,7 @@ from app.models.enums import TestState
from app.models.technique import Technique
from app.models.test import Test
from app.models.test_template import TestTemplate
from app.models.campaign import CampaignTest
from app.models.audit import AuditLog
from app.utils import escape_like
@@ -31,6 +32,7 @@ def list_tests(
platform: str | None = None,
created_by: uuid.UUID | None = None,
pending_validation_side: str | None = None,
not_in_any_campaign: bool = False,
offset: int = 0,
limit: int = 50,
) -> list[Test]:
@@ -55,6 +57,9 @@ def list_tests(
Test.state == TestState.in_review,
Test.blue_validation_status.in_(["pending", None]),
)
if not_in_any_campaign:
linked = db.query(CampaignTest.test_id).distinct().subquery()
query = query.filter(~Test.id.in_(linked))
return query.order_by(Test.created_at.desc()).offset(offset).limit(limit).all()