fix(coverage): partial coverage when mix of detected+not_detected; add bulk recalculate endpoint
Aegis CI / lint-and-test (push) Waiting to run
Snyk Security Scan / Python vulnerabilities (backend) (push) Waiting to run
Snyk Security Scan / npm vulnerabilities (frontend) (push) Waiting to run
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Waiting to run
Aegis CI / lint-and-test (push) Waiting to run
Snyk Security Scan / Python vulnerabilities (backend) (push) Waiting to run
Snyk Security Scan / npm vulnerabilities (frontend) (push) Waiting to run
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Waiting to run
This commit is contained in:
@@ -271,13 +271,13 @@ class TechniqueEntity:
|
||||
else:
|
||||
self.status_global = TechniqueStatus.partial
|
||||
elif any(
|
||||
# Keyword argument: r
|
||||
r == TestResult.partially_detected or r == "partially_detected"
|
||||
r in (TestResult.detected, "detected",
|
||||
TestResult.partially_detected, "partially_detected")
|
||||
for r in results
|
||||
):
|
||||
# Assign self.status_global = TechniqueStatus.partial
|
||||
# Mix of detected + not_detected, or any partially_detected → partial
|
||||
self.status_global = TechniqueStatus.partial
|
||||
# Fallback: handle remaining cases
|
||||
# Fallback: handle remaining cases (all not_detected)
|
||||
else:
|
||||
# Assign self.status_global = TechniqueStatus.not_covered
|
||||
self.status_global = TechniqueStatus.not_covered
|
||||
|
||||
@@ -824,6 +824,38 @@ def re_enrich_evaluation_round(
|
||||
return summary
|
||||
|
||||
|
||||
@router.post("/recalculate-coverage")
|
||||
def recalculate_all_coverage(
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(require_role("admin")),
|
||||
):
|
||||
"""Recompute status_global for every technique based on its current tests.
|
||||
|
||||
**Requires** the ``admin`` role.
|
||||
Run this after logic changes to the coverage scoring rules.
|
||||
"""
|
||||
from app.models.technique import Technique
|
||||
from app.services.status_service import recalculate_technique_status
|
||||
|
||||
techniques = db.query(Technique).all()
|
||||
updated = 0
|
||||
for tech in techniques:
|
||||
old_status = tech.status_global
|
||||
recalculate_technique_status(db, tech)
|
||||
if tech.status_global != old_status:
|
||||
updated += 1
|
||||
db.commit()
|
||||
logger.info(
|
||||
"Bulk coverage recalculation: %d/%d techniques updated (by %s)",
|
||||
updated, len(techniques), current_user.email,
|
||||
)
|
||||
return {
|
||||
"total": len(techniques),
|
||||
"updated": updated,
|
||||
"message": f"Coverage recalculated for {len(techniques)} techniques. {updated} statuses changed.",
|
||||
}
|
||||
|
||||
|
||||
@router.post("/email-test")
|
||||
def send_test_email(
|
||||
payload: EmailTestRequest,
|
||||
|
||||
Reference in New Issue
Block a user