feat(iace): Klaerungen MVP — Phase 1

New page "Klaerungen" between Massnahmen and Verifikation.

Backend:
- internal/iace/clarifications.go: Clarification struct + ClarificationAnswer +
  BuildProjectClarifications() — aggregates pattern-level + manufacturer-
  level questions from collectAllPatterns + GetManufacturerSafetyFeatures.
  Deterministic IDs ("pattern:HP1640:0", "manuf:fanuc:dual-check-safety-dcs:1")
  so persisted answers survive every re-init.
- internal/api/handlers/iace_handler_clarifications.go:
  - GET /projects/:id/clarifications returns aggregated list with affected
    hazard names + persisted answer state, sorted (open first).
  - POST /projects/:id/clarifications/:cid/answer writes status/answer/
    reasoning/answered_by/answered_at to project.metadata.clarification_-
    answers — no DB schema change.

Frontend:
- admin-compliance/app/sdk/iace/layout.tsx: new "Klaerungen" nav item.
- app/sdk/iace/[projectId]/clarifications/page.tsx: table grouped by
  source (FANUC / Pattern HP1640 / …), Filter Offen/Beantwortet/Alle,
  search field, Antwort-Modal with status/answer/Begruendung/Bearbeiter.

A clarification answered once applies to ALL referenced hazards — the
operator no longer has to answer the same FANUC DCS question on 48
mechanical hazards individually.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-17 01:05:53 +02:00
parent bc21480a2a
commit 79efa54898
5 changed files with 779 additions and 0 deletions
+4
View File
@@ -451,6 +451,10 @@ func registerIACERoutes(v1 *gin.RouterGroup, h *handlers.IACEHandler) {
// CE x Compliance Crossover
iaceRoutes.GET("/projects/:id/compliance-triggers", h.GetComplianceTriggers)
iaceRoutes.GET("/compliance-faq", h.GetComplianceFAQ)
// Clarifications — aggregated open questions per project
iaceRoutes.GET("/projects/:id/clarifications", h.ListClarifications)
iaceRoutes.POST("/projects/:id/clarifications/:cid/answer", h.AnswerClarification)
}
}