Files
breakpilot-compliance/ai-compliance-sdk/internal/ucca/policy_engine_gen.go
Sharang Parnerkar c293d76e6b refactor(go/ucca): split policy_engine, legal_rag, ai_act, nis2, financial_policy, dsgvo_module
Split 6 oversized files (719–882 LOC each) into focused files under 500 LOC:
- policy_engine.go → types, loader, eval, gen (4 files)
- legal_rag.go     → types, client, http, context, scroll (5 files)
- ai_act_module.go → module, yaml, obligations (3 files)
- nis2_module.go   → module, yaml, obligations + shared obligation_yaml_types.go (3+1 files)
- financial_policy.go → types, engine (2 files)
- dsgvo_module.go  → module, yaml, obligations (3 files)

All in package ucca, zero exported symbol renames, go test ./internal/ucca/... passes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 09:48:41 +02:00

131 lines
4.0 KiB
Go

package ucca
import (
"fmt"
"strings"
)
// generateSummary creates a human-readable summary
func (e *PolicyEngine) generateSummary(result *AssessmentResult, intake *UseCaseIntake) string {
var parts []string
switch result.Feasibility {
case FeasibilityYES:
parts = append(parts, "Der Use Case ist aus DSGVO-Sicht grundsätzlich umsetzbar.")
case FeasibilityCONDITIONAL:
parts = append(parts, "Der Use Case ist unter Auflagen umsetzbar.")
case FeasibilityNO:
parts = append(parts, "Der Use Case ist in der aktuellen Form nicht DSGVO-konform umsetzbar.")
}
blockCount := 0
warnCount := 0
for _, r := range result.TriggeredRules {
if r.Severity == SeverityBLOCK {
blockCount++
} else if r.Severity == SeverityWARN {
warnCount++
}
}
if blockCount > 0 {
parts = append(parts, fmt.Sprintf("%d kritische Regelverletzung(en) identifiziert.", blockCount))
}
if warnCount > 0 {
parts = append(parts, fmt.Sprintf("%d Warnungen erfordern Aufmerksamkeit.", warnCount))
}
if result.DSFARecommended {
parts = append(parts, "Eine Datenschutz-Folgenabschätzung (DSFA) wird empfohlen.")
}
return strings.Join(parts, " ")
}
// generateRecommendation creates actionable recommendations
func (e *PolicyEngine) generateRecommendation(result *AssessmentResult, intake *UseCaseIntake) string {
if result.Feasibility == FeasibilityYES {
return "Fahren Sie mit der Implementierung fort. Beachten Sie die empfohlenen Architektur-Patterns für optimale DSGVO-Konformität."
}
if result.Feasibility == FeasibilityCONDITIONAL {
if len(result.RequiredControls) > 0 {
return fmt.Sprintf("Implementieren Sie die %d erforderlichen Kontrollen vor dem Go-Live. Dokumentieren Sie alle Maßnahmen für den Nachweis der Rechenschaftspflicht (Art. 5 DSGVO).", len(result.RequiredControls))
}
return "Prüfen Sie die ausgelösten Warnungen und implementieren Sie entsprechende Schutzmaßnahmen."
}
return "Der Use Case erfordert grundlegende Änderungen. Prüfen Sie die Lösungsvorschläge."
}
// generateAlternative creates alternative approach suggestions
func (e *PolicyEngine) generateAlternative(result *AssessmentResult, intake *UseCaseIntake, triggeredRules map[string]bool) string {
var suggestions []string
for _, ps := range e.config.ProblemSolutions {
for _, trigger := range ps.Triggers {
if triggeredRules[trigger.Rule] {
if trigger.WithoutControl != "" {
hasControl := false
for _, ctrl := range result.RequiredControls {
if ctrl.ID == trigger.WithoutControl {
hasControl = true
break
}
}
if hasControl {
continue
}
}
if len(ps.Solutions) > 0 {
sol := ps.Solutions[0]
suggestions = append(suggestions, fmt.Sprintf("%s: %s", sol.Title, sol.TeamQuestion))
}
}
}
}
if len(suggestions) == 0 {
if intake.ModelUsage.Training && intake.DataTypes.PersonalData {
suggestions = append(suggestions, "Nutzen Sie nur RAG statt Training mit personenbezogenen Daten")
}
if intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects {
suggestions = append(suggestions, "Implementieren Sie Human-in-the-Loop für Entscheidungen mit rechtlichen Auswirkungen")
}
if intake.DataTypes.MinorData && intake.Purpose.EvaluationScoring {
suggestions = append(suggestions, "Verzichten Sie auf automatisches Scoring von Minderjährigen")
}
}
if len(suggestions) == 0 {
return "Überarbeiten Sie den Use Case unter Berücksichtigung der ausgelösten Regeln."
}
return strings.Join(suggestions, " | ")
}
// ============================================================================
// Helper Functions
// ============================================================================
func parseSeverity(s string) Severity {
switch strings.ToUpper(s) {
case "BLOCK":
return SeverityBLOCK
case "WARN":
return SeverityWARN
default:
return SeverityINFO
}
}
func categorizeControl(id string) string {
technical := map[string]bool{
"C_ENCRYPTION": true, "C_ACCESS_LOGGING": true,
}
if technical[id] {
return "technical"
}
return "organizational"
}