32ba8d16b1
Adds an auditor-facing view of the IACE engine: a clickable 10-stage pipeline flow (Grenzen-Formular → ParseNarrative → Pattern-Gates → Relevanz → Caps → Gefährdungen → Maßnahmen → Risiko → Normen → Matrix), plus live library counts, the data-source/license register (incl. the DIN/Beuth + DGUV exclusions), and the norm-matching logic that reconciles DIN/ISO/OSHA machine-type vocabulary via canonicalMachineType folding. Backend: BuildArchitecture() with LIVE counts so the diagram can never drift; GET /iace/architecture; collectAllNorms() extracted from SuggestNorms as the single source of truth for the norm-library count. Frontend: useArchitecture hook + page + new IACE nav tab. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
69 lines
2.5 KiB
Go
69 lines
2.5 KiB
Go
package handlers
|
||
|
||
import (
|
||
"net/http"
|
||
|
||
"github.com/breakpilot/ai-compliance-sdk/internal/iace"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/google/uuid"
|
||
)
|
||
|
||
// GetRiskSuggestion returns BreakPilot's justified dual-model risk suggestion
|
||
// for a hazard: the EN-62061-style F/W/P/S model and the Fine-Kinney P/E/C
|
||
// model, each with suggested values, justifications and the visible formula.
|
||
// Read-only and computed from public-data anchors — the professional adjusts
|
||
// the values; no norm table is stored or reproduced.
|
||
//
|
||
// GET /projects/:id/hazards/:hid/risk-suggestion
|
||
func (h *IACEHandler) GetRiskSuggestion(c *gin.Context) {
|
||
hid, err := uuid.Parse(c.Param("hid"))
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid hazard ID"})
|
||
return
|
||
}
|
||
hz, err := h.store.GetHazard(c.Request.Context(), hid)
|
||
if err != nil || hz == nil {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "hazard not found"})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, iace.BuildRiskSuggestion(hz))
|
||
}
|
||
|
||
// GetRiskMatrix handles GET /projects/:id/risk-matrix.
|
||
// Project-wide confidence-aware risk view computed on read from each hazard (no
|
||
// persistence): per-hazard risk list + a Severity×Probability aggregation grid.
|
||
// Uses the same model as the GT benchmark, so matrix numbers match the
|
||
// comparison. Lets a customer see risk for EVERY project, not only GT ones.
|
||
func (h *IACEHandler) GetRiskMatrix(c *gin.Context) {
|
||
projectID, err := uuid.Parse(c.Param("id"))
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project ID"})
|
||
return
|
||
}
|
||
hazards, err := h.store.ListHazards(c.Request.Context(), projectID)
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, iace.BuildRiskMatrix(hazards))
|
||
}
|
||
|
||
// GetRiskDataSources handles GET /risk-data-sources.
|
||
// Returns the license-tagged public-statistics evidence register (Eurostat ESAW,
|
||
// CC BY 4.0) that anchors the risk-frequency tiers, plus the overall attribution
|
||
// note — so an auditor can see WHERE the risk numbers come from.
|
||
func (h *IACEHandler) GetRiskDataSources(c *gin.Context) {
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"note": iace.RiskDataSourcesNote,
|
||
"evidence": iace.AllRiskEvidence(),
|
||
})
|
||
}
|
||
|
||
// GetArchitecture handles GET /architecture.
|
||
// Data-driven self-description of the IACE engine (pipeline stages, libraries
|
||
// with LIVE counts, data sources + licenses, norm-matching logic) for the
|
||
// "Architektur & Datenfluss" auditability tab.
|
||
func (h *IACEHandler) GetArchitecture(c *gin.Context) {
|
||
c.JSON(http.StatusOK, iace.BuildArchitecture())
|
||
}
|