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.
- Add bulk_technique_scores() that pre-fetches all scoring data in 5 aggregated GROUP BY queries instead of N*5 per-technique queries
- Rewrite calculate_organization_score to use bulk data (N*5+5 queries -> 10 fixed queries)
- Rewrite calculate_tactic_score and calculate_actor_coverage_score to use bulk data
- Preserve calculate_technique_score single-technique API for router-level calls