Test Catalog's pagination showed only 'Page N' with no way to know
how many pages existed, and the campaign 'Add Test' modal's template
picker had no pagination at all — with 2800+ templates in the
catalog, its flat 100-row fetch made most templates unreachable
unless a search happened to match. Adds GET /test-templates/count
(open to any authenticated user, mirrors the list endpoint's filters)
and wires real 'Page N of M' + total-available counts into both.
- start_execution now blocks a test from starting before its campaign's
start_date, closing a gap where the field was persisted but never
enforced
- GET /tests gains a reviewer_id "my reviews" filter for the red_review/
blue_review lead-gate stage, distinct from pending_validation_side
(which only ever covered the later in_review stage and ignored
assignment entirely)
- get_coverage_by_tactic now returns all 14 MITRE tactics in canonical
kill-chain order instead of an alphabetical, partial list — the
regular Dashboard and Executive Dashboard both consume this endpoint
and previously disagreed on order/completeness
- test-template listing now includes existing_test_count per technique
so the catalog can warn before creating a likely-duplicate test
Task D — Google-style docstrings (Args/Returns) on every public function,
method, and class across all 158 Python files in the backend. Zero ruff D
violations (pydocstyle Google convention).
Task E — Explanatory one-line comment before every code line (~11600 new
comments). ruff check passes clean after isort re-sort.