feat: Compliance Maximizer — Regulatory Optimization Engine
Some checks failed
Build + Deploy / build-admin-compliance (push) Successful in 1m45s
Build + Deploy / build-backend-compliance (push) Successful in 4m42s
Build + Deploy / build-ai-sdk (push) Successful in 46s
Build + Deploy / build-developer-portal (push) Successful in 1m6s
Build + Deploy / build-tts (push) Successful in 1m14s
Build + Deploy / build-document-crawler (push) Successful in 31s
Build + Deploy / build-dsms-gateway (push) Successful in 24s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 15s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m27s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Failing after 37s
CI / test-python-backend (push) Successful in 42s
CI / test-python-document-crawler (push) Successful in 25s
CI / test-python-dsms-gateway (push) Successful in 23s
CI / validate-canonical-controls (push) Successful in 18s
Build + Deploy / trigger-orca (push) Successful in 4m35s
Some checks failed
Build + Deploy / build-admin-compliance (push) Successful in 1m45s
Build + Deploy / build-backend-compliance (push) Successful in 4m42s
Build + Deploy / build-ai-sdk (push) Successful in 46s
Build + Deploy / build-developer-portal (push) Successful in 1m6s
Build + Deploy / build-tts (push) Successful in 1m14s
Build + Deploy / build-document-crawler (push) Successful in 31s
Build + Deploy / build-dsms-gateway (push) Successful in 24s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / loc-budget (push) Failing after 15s
CI / secret-scan (push) Has been skipped
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / nodejs-build (push) Successful in 2m27s
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / test-go (push) Failing after 37s
CI / test-python-backend (push) Successful in 42s
CI / test-python-document-crawler (push) Successful in 25s
CI / test-python-dsms-gateway (push) Successful in 23s
CI / validate-canonical-controls (push) Successful in 18s
Build + Deploy / trigger-orca (push) Successful in 4m35s
Neues Modul das den regulatorischen Spielraum fuer KI-Use-Cases deterministisch berechnet und optimale Konfigurationen vorschlaegt. Kernfeatures: - 13-Dimensionen Constraint-Space (DSGVO + AI Act) - 3-Zonen-Analyse: Verboten / Eingeschraenkt / Erlaubt - Deterministische Optimizer-Engine (kein LLM im Kern) - 28 Constraint-Regeln aus DSGVO, AI Act, EDPB Guidelines - 28 Tests (Golden Suite + Meta-Tests) - REST API: /sdk/v1/maximizer/* (9 Endpoints) - Frontend: 3-Zonen-Visualisierung, Dimension-Form, Score-Gauges [migration-approved] Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
155
ai-compliance-sdk/internal/api/handlers/maximizer_handlers.go
Normal file
155
ai-compliance-sdk/internal/api/handlers/maximizer_handlers.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/breakpilot/ai-compliance-sdk/internal/maximizer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// MaximizerHandlers exposes the Compliance Maximizer API.
|
||||
type MaximizerHandlers struct {
|
||||
svc *maximizer.Service
|
||||
}
|
||||
|
||||
// NewMaximizerHandlers creates handlers backed by a maximizer service.
|
||||
func NewMaximizerHandlers(svc *maximizer.Service) *MaximizerHandlers {
|
||||
return &MaximizerHandlers{svc: svc}
|
||||
}
|
||||
|
||||
// Optimize evaluates a DimensionConfig and returns optimized variants.
|
||||
func (h *MaximizerHandlers) Optimize(c *gin.Context) {
|
||||
var req maximizer.OptimizeInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
req.TenantID, _ = getTenantID(c)
|
||||
req.UserID = maximizerGetUserID(c)
|
||||
result, err := h.svc.Optimize(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// OptimizeFromIntake maps a UseCaseIntake to dimensions and optimizes.
|
||||
func (h *MaximizerHandlers) OptimizeFromIntake(c *gin.Context) {
|
||||
var req maximizer.OptimizeFromIntakeInput
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
req.TenantID, _ = getTenantID(c)
|
||||
req.UserID = maximizerGetUserID(c)
|
||||
result, err := h.svc.OptimizeFromIntake(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// OptimizeFromAssessment optimizes an existing UCCA assessment.
|
||||
func (h *MaximizerHandlers) OptimizeFromAssessment(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid assessment id"})
|
||||
return
|
||||
}
|
||||
tid, _ := getTenantID(c)
|
||||
uid := maximizerGetUserID(c)
|
||||
result, err := h.svc.OptimizeFromAssessment(c.Request.Context(), id, tid, uid)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// Evaluate performs a 3-zone evaluation without persisting.
|
||||
func (h *MaximizerHandlers) Evaluate(c *gin.Context) {
|
||||
var config maximizer.DimensionConfig
|
||||
if err := c.ShouldBindJSON(&config); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
result := h.svc.Evaluate(&config)
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// ListOptimizations returns stored optimizations for the tenant.
|
||||
func (h *MaximizerHandlers) ListOptimizations(c *gin.Context) {
|
||||
f := &maximizer.OptimizationFilters{
|
||||
Search: c.Query("search"),
|
||||
Limit: maximizerParseInt(c.Query("limit"), 20),
|
||||
Offset: maximizerParseInt(c.Query("offset"), 0),
|
||||
}
|
||||
tid, _ := getTenantID(c)
|
||||
results, total, err := h.svc.ListOptimizations(c.Request.Context(), tid, f)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"optimizations": results, "total": total})
|
||||
}
|
||||
|
||||
// GetOptimization returns a single optimization.
|
||||
func (h *MaximizerHandlers) GetOptimization(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
||||
return
|
||||
}
|
||||
result, err := h.svc.GetOptimization(c.Request.Context(), id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, result)
|
||||
}
|
||||
|
||||
// DeleteOptimization removes an optimization.
|
||||
func (h *MaximizerHandlers) DeleteOptimization(c *gin.Context) {
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
|
||||
return
|
||||
}
|
||||
if err := h.svc.DeleteOptimization(c.Request.Context(), id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
// GetDimensionSchema returns the dimension enum values for the frontend.
|
||||
func (h *MaximizerHandlers) GetDimensionSchema(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, h.svc.GetDimensionSchema())
|
||||
}
|
||||
|
||||
func maximizerGetUserID(c *gin.Context) uuid.UUID {
|
||||
if id, exists := c.Get("user_id"); exists {
|
||||
if uid, ok := id.(uuid.UUID); ok {
|
||||
return uid
|
||||
}
|
||||
}
|
||||
return uuid.Nil
|
||||
}
|
||||
|
||||
// maximizerParseInt is a local helper for query param parsing.
|
||||
func maximizerParseInt(s string, def int) int {
|
||||
if s == "" {
|
||||
return def
|
||||
}
|
||||
n := 0
|
||||
for _, c := range s {
|
||||
if c < '0' || c > '9' {
|
||||
return def
|
||||
}
|
||||
n = n*10 + int(c-'0')
|
||||
}
|
||||
return n
|
||||
}
|
||||
Reference in New Issue
Block a user