56892cf7dc
Automatische Erkennung von DSGVO/AI Act/CRA/NIS2/Data Act Implikationen bei CE-Gefaehrdungen. 50 Trigger-Mappings auf Hazard-Patterns → Compliance-Module mit Modul-Links. - compliance_triggers.go: 50 Pattern→Regulation Mappings - compliance_crossover.go: Engine die Projekt-Hazards gegen Trigger prueft - iace_handler_compliance.go: GET /compliance-triggers API - ComplianceAlerts.tsx: Frontend Alert-Panel auf Projekt-Uebersicht Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
2.9 KiB
Go
87 lines
2.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// ============================================================================
|
|
// CE x Compliance Crossover Engine
|
|
// ============================================================================
|
|
|
|
// GetComplianceTriggers handles GET /projects/:id/compliance-triggers.
|
|
// It analyses the project's hazards and component patterns to determine
|
|
// which DSGVO, AI Act, CRA, NIS2, and EU Data Act obligations are triggered.
|
|
// The response includes deduplicated triggers sorted by severity, plus boolean
|
|
// summary flags (dsfa_required, ai_act_relevant, cra_relevant, etc.).
|
|
func (h *IACEHandler) GetComplianceTriggers(c *gin.Context) {
|
|
projectID, err := uuid.Parse(c.Param("id"))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
|
return
|
|
}
|
|
|
|
// Verify project exists
|
|
project, err := h.store.GetProject(c.Request.Context(), projectID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if project == nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
|
|
return
|
|
}
|
|
|
|
// Fetch all hazards for this project
|
|
hazards, err := h.store.ListHazards(c.Request.Context(), projectID)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to load hazards: " + err.Error()})
|
|
return
|
|
}
|
|
|
|
// Also run pattern matching with component tags to catch tag-based triggers.
|
|
// Collect tags from the project's components (reuse the norms handler logic).
|
|
componentTags := collectComponentTags(h, c, projectID)
|
|
|
|
// Get all patterns from the pattern library
|
|
allPatterns := iace.AllPatterns()
|
|
|
|
// Additionally derive extra fired patterns by re-matching component tags
|
|
// against the pattern engine. This ensures patterns that are not yet
|
|
// applied as hazards still contribute their compliance triggers.
|
|
engine := iace.NewPatternEngine()
|
|
matchInput := iace.MatchInput{
|
|
CustomTags: componentTags,
|
|
}
|
|
matchResult := engine.Match(matchInput)
|
|
|
|
// Merge matched pattern IDs into a pseudo-hazard list so the crossover
|
|
// engine picks them up. We create lightweight Hazard structs with the
|
|
// pattern ID embedded in the Description field.
|
|
mergedHazards := make([]iace.Hazard, len(hazards))
|
|
copy(mergedHazards, hazards)
|
|
for _, pm := range matchResult.MatchedPatterns {
|
|
mergedHazards = append(mergedHazards, iace.Hazard{
|
|
Name: pm.PatternName,
|
|
Description: "Pattern " + pm.PatternID,
|
|
Category: firstOrEmpty(pm.HazardCats),
|
|
})
|
|
}
|
|
|
|
// Run the crossover engine
|
|
summary := iace.GetProjectComplianceTriggers(mergedHazards, allPatterns)
|
|
|
|
c.JSON(http.StatusOK, summary)
|
|
}
|
|
|
|
// firstOrEmpty returns the first element of a string slice or "".
|
|
func firstOrEmpty(ss []string) string {
|
|
if len(ss) > 0 {
|
|
return ss[0]
|
|
}
|
|
return ""
|
|
}
|