feat(iace): Sprint 4B — ISO 12100 Hazard/Situation/Harm Trennung
ISO 12100 trennt: Hazard (Quelle) → Hazardous Situation (Person exponiert) → Harm (Verletzung).
Bisher war alles in einem Hazard-Record vermischt.
Implementierung als abgeleitetes Feld (keine DB-Migration noetig):
- HazardType Feld auf Hazard Entity ("hazard"|"hazardous_situation"|"harm")
- DeriveHazardType() berechnet Typ aus Scenario/PossibleHarm/Category
- Explizites Override moeglich (HazardType direkt setzen)
- GeneratedHazardType auf HazardPattern fuer Pattern-gesteuerte Zuweisung
- Store: GetHazard/ListHazards setzen HazardType automatisch
- Init-Handler: Fuellt jetzt TriggerEvent, PossibleHarm, AffectedPerson, HazardousZone
aus Pattern-Match-Daten (vorher leer gelassen)
6 neue Tests: ScenarioAndHarm, HarmOnly, CategoryOnly, ExplicitOverride,
EmptyFallback, PatternMatchField
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -338,6 +338,62 @@ func TestEvidenceTypes_UniqueIDs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════
|
||||
// Sprint 4B: HazardType / ISO 12100 Trennung
|
||||
// ══════════════════════════════════════════════════════════════════
|
||||
|
||||
func TestDeriveHazardType_WithScenarioAndHarm(t *testing.T) {
|
||||
h := &Hazard{Scenario: "Person im Bewegungsraum", PossibleHarm: "Quetschung"}
|
||||
if got := DeriveHazardType(h); got != HazardTypeHazardousSituation {
|
||||
t.Errorf("expected hazardous_situation, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveHazardType_HarmOnly(t *testing.T) {
|
||||
h := &Hazard{PossibleHarm: "Quetschung", Category: "mechanical"}
|
||||
if got := DeriveHazardType(h); got != HazardTypeHarm {
|
||||
t.Errorf("expected harm, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveHazardType_CategoryOnly(t *testing.T) {
|
||||
h := &Hazard{Category: "mechanical_hazard"}
|
||||
if got := DeriveHazardType(h); got != HazardTypeHazard {
|
||||
t.Errorf("expected hazard, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveHazardType_ExplicitOverride(t *testing.T) {
|
||||
h := &Hazard{HazardType: "harm", Scenario: "ignored", PossibleHarm: "ignored"}
|
||||
if got := DeriveHazardType(h); got != "harm" {
|
||||
t.Errorf("expected explicit harm, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveHazardType_EmptyFallback(t *testing.T) {
|
||||
h := &Hazard{}
|
||||
if got := DeriveHazardType(h); got != DefaultHazardType {
|
||||
t.Errorf("expected default %s, got %s", DefaultHazardType, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatternMatch_GeneratedHazardType(t *testing.T) {
|
||||
// Verify PatternMatch carries GeneratedHazardType
|
||||
engine := NewPatternEngine()
|
||||
result := engine.Match(MatchInput{
|
||||
ComponentLibraryIDs: []string{"C001"},
|
||||
EnergySourceIDs: []string{"EN01"},
|
||||
})
|
||||
// Most patterns don't set GeneratedHazardType (empty = default)
|
||||
// Just verify the field exists and doesn't crash
|
||||
for _, p := range result.MatchedPatterns {
|
||||
_ = p.GeneratedHazardType // Should compile and not panic
|
||||
}
|
||||
if len(result.MatchedPatterns) == 0 {
|
||||
t.Fatal("expected matched patterns")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvidenceTypes_SortOrder(t *testing.T) {
|
||||
types := GetEvidenceTypeLibrary()
|
||||
for i := 1; i < len(types); i++ {
|
||||
|
||||
Reference in New Issue
Block a user