feat(iace): Betriebszustand-Traceability auf Hazards + Mitigations

Hazards zeigen jetzt farbige Badges mit den Betriebszustaenden die sie
ausgeloest haben (z.B. "Wartung", "Not-Halt"). Mitigations erben die
States ihrer verknuepften Hazards.

Backend: OperationalStates im Function-Feld encodiert (kein DB-Schema),
beim Lesen als operational_states[] JSON-Feld zurueckgegeben.
Frontend: Indigo-Badges in HazardTable + MitigationCard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-11 09:04:20 +02:00
parent af5ab9127a
commit cb8fb65d3e
9 changed files with 72 additions and 5 deletions
@@ -23,7 +23,7 @@ export function useMitigations(projectId: string) {
let hazardList: Hazard[] = []
if (hazRes.ok) {
const json = await hazRes.json()
hazardList = (json.hazards || json || []).map((h: Hazard) => ({ id: h.id, name: h.name, risk_level: h.risk_level, category: h.category }))
hazardList = (json.hazards || json || []).map((h: Record<string, unknown>) => ({ id: h.id as string, name: h.name as string, risk_level: h.risk_level as string, category: h.category as string, operational_states: (h.operational_states || []) as string[] }))
setHazards(hazardList)
}
if (mitRes.ok) {
@@ -31,6 +31,7 @@ export function useMitigations(projectId: string) {
const raw = json.mitigations || json || []
// Map API fields (name, hazard_id) to frontend fields (title, linked_hazard_ids/names)
const hazardMap = Object.fromEntries(hazardList.map((h) => [h.id, h.name]))
const hazardStatesMap = Object.fromEntries(hazardList.map((h) => [h.id, (h as Record<string, unknown>).operational_states || []]))
const mits: Mitigation[] = raw.map((m: Record<string, unknown>) => ({
id: m.id as string,
title: (m.title || m.name || '') as string,
@@ -44,6 +45,12 @@ export function useMitigations(projectId: string) {
created_at: (m.created_at || '') as string,
verified_at: (m.verified_at || null) as string | null,
verified_by: (m.verified_by || null) as string | null,
operational_states: (() => {
const ids = m.linked_hazard_ids ? (m.linked_hazard_ids as string[]) : m.hazard_id ? [m.hazard_id as string] : []
const states = new Set<string>()
ids.forEach((id) => { ((hazardStatesMap[id] || []) as string[]).forEach((s) => states.add(s)) })
return [...states]
})(),
}))
setMitigations(mits)
validateHierarchy(mits)
@@ -146,7 +153,7 @@ export function useMitigations(projectId: string) {
const byType = {
design: mitigations.filter((m) => m.reduction_type === 'design'),
protection: mitigations.filter((m) => m.reduction_type === 'protection' || m.reduction_type === 'protective'),
protection: mitigations.filter((m) => m.reduction_type === 'protection'),
information: mitigations.filter((m) => m.reduction_type === 'information'),
}