fix(exec-dashboard): replace time-dependent throughput with Pipeline Conversion %
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

'Validation Throughput (tests/week)' was time-dependent — director wanted
an activity-based metric instead.

New metric: Pipeline Conversion Rate
  formula: validated / (validated + rejected + in_review) × 100
  unit: %  (no time reference)
  meaning: 'of all tests that have entered validation, X% succeeded'
  trend: declining if in_review backlog > validated count,
         improving if conversion ≥ 80%, stable otherwise

Backend: calculate_validation_throughput() rewritten — same API key
(tests_per_week) kept for compatibility, new conversion_rate field added.
Frontend: label → 'Pipeline Conversion', unit → '%', tooltip updated.
This commit is contained in:
kitos
2026-06-03 10:06:30 +02:00
parent 9e36b683fa
commit f53500bcb5
2 changed files with 50 additions and 36 deletions

View File

@@ -237,45 +237,59 @@ def calculate_coverage_velocity(db: Session) -> dict:
def calculate_validation_throughput(db: Session) -> dict:
"""Calculate tests validated/rejected per week."""
twelve_weeks_ago = datetime.utcnow() - timedelta(weeks=12)
"""Pipeline Conversion Rate — activity-based, no time dependency.
# Tests validated
validated_weekly = (
db.query(
func.date_trunc("week", Test.red_validated_at).label("week"),
func.count(Test.id).label("count"),
)
.filter(
Test.red_validated_at >= twelve_weeks_ago,
Test.state.in_([TestState.validated, TestState.rejected]),
)
.group_by(func.date_trunc("week", Test.red_validated_at))
.order_by("week")
.all()
Measures what percentage of tests that have entered the validation
phase have been successfully approved (validated).
formula: validated / (validated + rejected + in_review) * 100
100% = every test that reached validation was approved.
0% = nothing has been validated yet.
Lower = backlog or quality issues blocking approvals.
"""
validated_count = (
db.query(func.count(Test.id))
.filter(Test.state == TestState.validated)
.scalar()
) or 0
rejected_count = (
db.query(func.count(Test.id))
.filter(Test.state == TestState.rejected)
.scalar()
) or 0
in_review_count = (
db.query(func.count(Test.id))
.filter(Test.state == TestState.in_review)
.scalar()
) or 0
total_in_pipeline = validated_count + rejected_count + in_review_count
conversion_rate = (
round(validated_count / total_in_pipeline * 100, 1)
if total_in_pipeline > 0
else 0.0
)
if validated_weekly:
counts = [row.count for row in validated_weekly]
avg_per_week = round(sum(counts) / len(counts), 1)
recent = counts[-4:] if len(counts) >= 4 else counts
earlier = counts[-8:-4] if len(counts) >= 8 else counts[:len(counts) // 2] if counts else []
recent_avg = sum(recent) / len(recent) if recent else 0
earlier_avg = sum(earlier) / len(earlier) if earlier else 0
if recent_avg > earlier_avg * 1.1:
trend = "improving"
elif recent_avg < earlier_avg * 0.9:
trend = "declining"
else:
trend = "stable"
# Trend: compare conversion rate when considering pending tests
# High pending backlog relative to validated = declining
if total_in_pipeline == 0:
trend = "stable"
elif in_review_count > validated_count:
trend = "declining" # backlog building up
elif conversion_rate >= 80:
trend = "improving" # most tests making it through
else:
avg_per_week = 0
trend = "stable"
return {
"tests_per_week": avg_per_week,
"tests_per_week": conversion_rate, # reuse key for API compat
"conversion_rate": conversion_rate,
"validated": validated_count,
"rejected": rejected_count,
"in_review": in_review_count,
"trend": trend,
}

View File

@@ -498,11 +498,11 @@ export default function ExecutiveDashboardPage() {
tooltip={{ description: "Percentage of executed attacks that Blue Team successfully detected. 100% means every simulated attack triggered an alert.", context: "Higher is better. Below 60% indicates significant detection gaps." }}
/>
<KPICard
label="Validation Throughput"
value={opMetrics?.validation_throughput?.tests_per_week ?? 0}
unit="/week"
label="Pipeline Conversion"
value={opMetrics?.validation_throughput?.conversion_rate ?? opMetrics?.validation_throughput?.tests_per_week ?? 0}
unit="%"
trend={opMetrics?.validation_throughput?.trend}
tooltip={{ description: "Number of tests fully validated (approved by Red + Blue leads) per week. Shows how productive the security testing programme is.", context: "Increasing trend = programme is accelerating. Decreasing may indicate process bottlenecks." }}
tooltip={{ description: "Percentage of tests that have entered the validation phase and been successfully approved. Formula: Validated ÷ (Validated + Rejected + In Review) × 100.", context: "100% = all reviewed tests approved. < 60% = quality or process issues. High backlog (many In Review) lowers this score." }}
/>
</div>