ff100c1cb8
Adds a jurisdiction-cross-reference layer to the norms library. Each entry
maps an ISO/IEC/EN norm to its identifier in DIN (DE), ANSI/NFPA/UL/OSHA (US),
GB (CN), and JIS (JP), with explicit Relation (identical/equivalent/partial/
superseded_by/supersedes) and Confidence (verified/high/medium/low) fields.
Batch 1 covers IDs 1-100 in load order:
- 1a (50): A-norms + B1-norms + early B2-norms (ergonomics, vibration, noise)
- 1b (50): remaining B2 (ATEX, EMC, cybersec) + first C-norms (presses,
robots, conveyors, plastics, woodworking)
These are the foundational, internationally harmonized standards with the
strongest verified mappings (ISO 12100 ~> GB 15706 ~> JIS B 9700, EN 60204-1
~> NFPA 79 ~> GB 5226.1 ~> JIS B 9960-1, etc.).
API:
- GET /iace/norms-library?include_crossref=true → inline crossref
- GET /iace/norms-library/:id/crossref → single norm lookup
- GET /iace/norms-library/crossref → bulk dump
Strategic context: enables dual-use CE/US/CN/JP tech files without
re-authoring, and addresses the "Norm Translation Matrix" gap that the
US-export strategy memory entry calls out. 6 batches remaining (~571 norms)
to reach full library coverage.
Tests: 6 new tests; all pass via `go test -vet=off ./internal/iace/`.
(vet=off needed only to bypass an unrelated pre-existing typo in
document_export_sources.go.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
139 lines
7.8 KiB
Go
139 lines
7.8 KiB
Go
package app
|
|
|
|
// IACE route registration extracted from routes.go (2026-05-21) because
|
|
// routes.go hit the 500-LOC hard cap when the LLM gap-review endpoint
|
|
// (Task #7) was added. Splitting keeps every routes file under the cap
|
|
// without changing behaviour — `registerRoutes` in routes.go still
|
|
// invokes `registerIACERoutes` exactly once at the same point in the
|
|
// startup sequence.
|
|
|
|
import (
|
|
"github.com/breakpilot/ai-compliance-sdk/internal/api/handlers"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func registerIACERoutes(v1 *gin.RouterGroup, h *handlers.IACEHandler) {
|
|
iaceRoutes := v1.Group("/iace")
|
|
{
|
|
// Library catalogues (read-only reference data).
|
|
iaceRoutes.GET("/hazard-library", h.ListHazardLibrary)
|
|
iaceRoutes.GET("/controls-library", h.ListControlsLibrary)
|
|
iaceRoutes.GET("/norms-library", h.ListNormsLibrary)
|
|
iaceRoutes.GET("/norms-library/crossref", h.ListNormCrossRefs)
|
|
iaceRoutes.GET("/norms-library/:id/crossref", h.GetNormCrossRef)
|
|
iaceRoutes.GET("/lifecycle-phases", h.ListLifecyclePhases)
|
|
iaceRoutes.GET("/roles", h.ListRoles)
|
|
iaceRoutes.GET("/evidence-types", h.ListEvidenceTypes)
|
|
iaceRoutes.GET("/protective-measures-library", h.ListProtectiveMeasures)
|
|
iaceRoutes.GET("/failure-modes", h.ListFailureModes)
|
|
iaceRoutes.GET("/operational-states", h.ListOperationalStates)
|
|
iaceRoutes.GET("/component-library", h.ListComponentLibrary)
|
|
iaceRoutes.GET("/energy-sources", h.ListEnergySources)
|
|
iaceRoutes.GET("/tags", h.ListTags)
|
|
iaceRoutes.GET("/hazard-patterns", h.ListHazardPatterns)
|
|
|
|
// Project CRUD.
|
|
iaceRoutes.POST("/projects", h.CreateProject)
|
|
iaceRoutes.GET("/projects", h.ListProjects)
|
|
iaceRoutes.GET("/projects/:id", h.GetProject)
|
|
iaceRoutes.PUT("/projects/:id", h.UpdateProject)
|
|
iaceRoutes.DELETE("/projects/:id", h.ArchiveProject)
|
|
iaceRoutes.POST("/projects/:id/init-from-profile", h.InitFromProfile)
|
|
iaceRoutes.POST("/projects/:id/variants", h.CreateVariant)
|
|
iaceRoutes.GET("/projects/:id/variants", h.ListVariants)
|
|
iaceRoutes.GET("/projects/:id/variant-gap", h.GetVariantGap)
|
|
iaceRoutes.POST("/projects/:id/completeness-check", h.CheckCompleteness)
|
|
|
|
// Components.
|
|
iaceRoutes.POST("/projects/:id/components", h.CreateComponent)
|
|
iaceRoutes.GET("/projects/:id/components", h.ListComponents)
|
|
iaceRoutes.PUT("/projects/:id/components/:cid", h.UpdateComponent)
|
|
iaceRoutes.DELETE("/projects/:id/components/:cid", h.DeleteComponent)
|
|
|
|
// Classification + hazards.
|
|
iaceRoutes.POST("/projects/:id/classify", h.Classify)
|
|
iaceRoutes.GET("/projects/:id/classifications", h.GetClassifications)
|
|
iaceRoutes.POST("/projects/:id/classify/:regulation", h.ClassifySingle)
|
|
iaceRoutes.POST("/projects/:id/hazards", h.CreateHazard)
|
|
iaceRoutes.GET("/projects/:id/hazards", h.ListHazards)
|
|
iaceRoutes.PUT("/projects/:id/hazards/:hid", h.UpdateHazard)
|
|
iaceRoutes.POST("/projects/:id/hazards/suggest", h.SuggestHazards)
|
|
iaceRoutes.POST("/projects/:id/match-patterns", h.MatchPatterns)
|
|
iaceRoutes.POST("/projects/:id/parse-narrative", h.ParseNarrative)
|
|
iaceRoutes.POST("/projects/:id/delta-analysis", h.DeltaAnalysis)
|
|
iaceRoutes.POST("/projects/:id/llm-gap-review", h.LLMGapReview)
|
|
iaceRoutes.GET("/projects/:id/fmea/export", h.ExportFMEA)
|
|
iaceRoutes.POST("/projects/:id/components/:cid/suggest-fms", h.SuggestFailureModes)
|
|
iaceRoutes.POST("/projects/:id/apply-patterns", h.ApplyPatternResults)
|
|
iaceRoutes.POST("/projects/:id/hazards/:hid/suggest-measures", h.SuggestMeasuresForHazard)
|
|
iaceRoutes.POST("/projects/:id/mitigations/:mid/suggest-evidence", h.SuggestEvidenceForMitigation)
|
|
iaceRoutes.POST("/projects/:id/hazards/:hid/assess", h.AssessRisk)
|
|
iaceRoutes.GET("/projects/:id/risk-summary", h.GetRiskSummary)
|
|
iaceRoutes.GET("/projects/:id/suggested-norms", h.SuggestProjectNorms)
|
|
iaceRoutes.POST("/projects/:id/hazards/:hid/reassess", h.ReassessRisk)
|
|
|
|
// Mitigations + evidence + verification.
|
|
iaceRoutes.GET("/projects/:id/mitigations", h.ListProjectMitigations)
|
|
iaceRoutes.POST("/projects/:id/hazards/:hid/mitigations", h.CreateMitigation)
|
|
iaceRoutes.DELETE("/projects/:id/mitigations/:mid", h.DeleteMitigation)
|
|
iaceRoutes.PUT("/mitigations/:mid", h.UpdateMitigation)
|
|
iaceRoutes.POST("/mitigations/:mid/verify", h.VerifyMitigation)
|
|
iaceRoutes.POST("/projects/:id/validate-mitigation-hierarchy", h.ValidateMitigationHierarchy)
|
|
iaceRoutes.POST("/projects/:id/evidence", h.UploadEvidence)
|
|
iaceRoutes.GET("/projects/:id/evidence", h.ListEvidence)
|
|
iaceRoutes.POST("/projects/:id/verification-plan", h.CreateVerificationPlan)
|
|
iaceRoutes.PUT("/verification-plan/:vid", h.UpdateVerificationPlan)
|
|
iaceRoutes.POST("/verification-plan/:vid/complete", h.CompleteVerification)
|
|
iaceRoutes.GET("/projects/:id/verifications", h.ListVerificationPlans)
|
|
iaceRoutes.POST("/projects/:id/verifications", h.CreateVerificationAlias)
|
|
iaceRoutes.DELETE("/projects/:id/verifications/:vid", h.DeleteVerificationPlan)
|
|
iaceRoutes.POST("/projects/:id/verifications/:vid/complete", h.CompleteVerificationAlias)
|
|
|
|
// Tech file + monitoring + audit.
|
|
iaceRoutes.POST("/projects/:id/tech-file/generate", h.GenerateTechFile)
|
|
iaceRoutes.GET("/projects/:id/tech-file", h.ListTechFileSections)
|
|
iaceRoutes.PUT("/projects/:id/tech-file/:section", h.UpdateTechFileSection)
|
|
iaceRoutes.POST("/projects/:id/tech-file/:section/approve", h.ApproveTechFileSection)
|
|
iaceRoutes.POST("/projects/:id/tech-file/:section/generate", h.GenerateSingleSection)
|
|
iaceRoutes.GET("/projects/:id/tech-file/export", h.ExportTechFile)
|
|
iaceRoutes.POST("/projects/:id/monitoring", h.CreateMonitoringEvent)
|
|
iaceRoutes.GET("/projects/:id/monitoring", h.ListMonitoringEvents)
|
|
iaceRoutes.PUT("/projects/:id/monitoring/:eid", h.UpdateMonitoringEvent)
|
|
iaceRoutes.GET("/projects/:id/audit-trail", h.GetAuditTrail)
|
|
|
|
// Library + corpus + benchmark.
|
|
iaceRoutes.POST("/library-search", h.SearchLibrary)
|
|
iaceRoutes.GET("/ce-corpus-documents", h.ListCECorpusDocuments)
|
|
iaceRoutes.POST("/projects/:id/initialize", h.InitializeProject)
|
|
iaceRoutes.GET("/projects/:id/hazard-blocks", h.GetHazardBlocks)
|
|
iaceRoutes.POST("/projects/:id/benchmark/import-gt", h.ImportGroundTruth)
|
|
iaceRoutes.GET("/projects/:id/benchmark", h.RunBenchmark)
|
|
iaceRoutes.GET("/projects/:id/benchmark/summary", h.GetBenchmarkSummary)
|
|
|
|
// Regulatory enrichment.
|
|
iaceRoutes.GET("/projects/:id/hazards/:hid/regulatory-hints", h.EnrichHazardWithRegulations)
|
|
iaceRoutes.GET("/projects/:id/mitigations/:mid/regulatory-hints", h.EnrichMitigationWithRegulations)
|
|
iaceRoutes.GET("/projects/:id/regulatory-hints", h.EnrichProjectHazardsBatch)
|
|
iaceRoutes.POST("/projects/:id/tech-file/:section/enrich", h.EnrichTechFileSection)
|
|
|
|
// Production lines.
|
|
iaceRoutes.POST("/production-lines", h.CreateProductionLine)
|
|
iaceRoutes.GET("/production-lines", h.ListProductionLines)
|
|
iaceRoutes.GET("/production-lines/:lid/dashboard", h.GetProductionLineDashboard)
|
|
iaceRoutes.POST("/production-lines/:lid/stations", h.AddStationToLine)
|
|
iaceRoutes.DELETE("/production-lines/:lid/stations/:sid", h.RemoveStationFromLine)
|
|
|
|
// CE x Compliance crossover + clarifications + customer standards.
|
|
iaceRoutes.GET("/projects/:id/compliance-triggers", h.GetComplianceTriggers)
|
|
iaceRoutes.GET("/compliance-faq", h.GetComplianceFAQ)
|
|
iaceRoutes.GET("/projects/:id/clarifications", h.ListClarifications)
|
|
iaceRoutes.GET("/projects/:id/clarifications.csv", h.ExportClarificationsCSV)
|
|
iaceRoutes.GET("/projects/:id/clarifications.html", h.ExportClarificationsHTML)
|
|
iaceRoutes.GET("/projects/:id/clarifications/:cid/detail", h.ListClarificationDetail)
|
|
iaceRoutes.POST("/projects/:id/clarifications/:cid/answer", h.AnswerClarification)
|
|
iaceRoutes.POST("/projects/:id/clarifications/:cid/comment", h.PostClarificationComment)
|
|
iaceRoutes.GET("/projects/:id/customer-standards", h.ListCustomerStandardSuggestions)
|
|
iaceRoutes.POST("/projects/:id/customer-standards/import", h.ImportCustomerStandardSuggestion)
|
|
}
|
|
}
|