Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 44s
CI/CD / test-python-backend-compliance (push) Successful in 48s
CI/CD / test-python-document-crawler (push) Successful in 32s
CI/CD / test-python-dsms-gateway (push) Successful in 27s
CI/CD / deploy-hetzner (push) Failing after 9s
- Create reporting_handlers.go with ReportingHandlers struct and 4 endpoint methods (GetExecutiveReport, GetComplianceScore, GetUpcomingDeadlines, GetRiskOverview) to fix build failure - Fix gap_analysis/analyzer.py: use Optional[list[str]] instead of list[str] | None for Python 3.9 compatibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
"""Gap detection logic — compares found documents against compliance matrix."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from typing import Optional
|
|
|
|
from .compliance_matrix import COMPLIANCE_MATRIX, RequiredDocument
|
|
|
|
|
|
def generate_gap_analysis(
|
|
classification_counts: dict[str, int],
|
|
company_profiles: Optional[list[str]] = None,
|
|
) -> dict:
|
|
"""Analyze gaps between found documents and required compliance matrix.
|
|
|
|
Args:
|
|
classification_counts: e.g. {"VVT": 2, "TOM": 1, "DSE": 0}
|
|
company_profiles: list of applicable profiles.
|
|
Default: ["universal", "data_processor", "ai_user"]
|
|
|
|
Returns dict with compliance_score, gaps list, classification_breakdown.
|
|
"""
|
|
if company_profiles is None:
|
|
company_profiles = ["universal", "data_processor", "ai_user"]
|
|
|
|
applicable = [
|
|
req for req in COMPLIANCE_MATRIX
|
|
if req.applies_to in company_profiles
|
|
]
|
|
|
|
gaps = []
|
|
covered = 0
|
|
|
|
for req in applicable:
|
|
count = classification_counts.get(req.category, 0)
|
|
if count == 0:
|
|
gaps.append({
|
|
"id": str(uuid.uuid4()),
|
|
"category": req.category,
|
|
"description": req.description,
|
|
"severity": req.severity,
|
|
"regulation": req.regulation,
|
|
"requiredAction": f"{req.category} erstellen und dokumentieren",
|
|
"relatedStepId": None,
|
|
})
|
|
else:
|
|
covered += 1
|
|
|
|
total_required = len(applicable)
|
|
compliance_score = (covered / total_required * 100) if total_required > 0 else 0
|
|
|
|
return {
|
|
"compliance_score": round(compliance_score, 1),
|
|
"total_required": total_required,
|
|
"covered": covered,
|
|
"gaps": gaps,
|
|
"gap_summary": {
|
|
"critical": sum(1 for g in gaps if g["severity"] == "CRITICAL"),
|
|
"high": sum(1 for g in gaps if g["severity"] == "HIGH"),
|
|
"medium": sum(1 for g in gaps if g["severity"] == "MEDIUM"),
|
|
},
|
|
}
|