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
@@ -3,12 +3,32 @@ package iace
import (
"context"
"fmt"
"strings"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
const opStatesPrefix = "op_states:"
// EncodeOpStates encodes operational states into the Function field.
func EncodeOpStates(states []string) string {
if len(states) == 0 {
return ""
}
return opStatesPrefix + strings.Join(states, ",")
}
// decodeOpStates parses operational states from the Function field
// and clears the encoded value so it's not exposed as "function" text.
func decodeOpStates(h *Hazard) {
if strings.HasPrefix(h.Function, opStatesPrefix) {
h.OperationalStates = strings.Split(h.Function[len(opStatesPrefix):], ",")
h.Function = ""
}
}
// ============================================================================
// Hazard CRUD Operations
// ============================================================================
@@ -96,6 +116,7 @@ func (s *Store) GetHazard(ctx context.Context, id uuid.UUID) (*Hazard, error) {
h.Status = HazardStatus(status)
h.ReviewStatus = ReviewStatus(reviewStatus)
h.HazardType = DeriveHazardType(&h)
decodeOpStates(&h)
return &h, nil
}
@@ -135,6 +156,7 @@ func (s *Store) ListHazards(ctx context.Context, projectID uuid.UUID) ([]Hazard,
h.Status = HazardStatus(status)
h.ReviewStatus = ReviewStatus(reviewStatus)
h.HazardType = DeriveHazardType(&h)
decodeOpStates(&h)
hazards = append(hazards, h)
}