fix(iace): assign mitigations to ALL hazards per category

hazardIDsByCategory changed from map[string]uuid.UUID to
map[string][]uuid.UUID — measures are now distributed to every
hazard in a category, not just the last one created.

Previously 94/108 hazards had no measures, now all get them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-14 23:34:57 +02:00
parent 4e9043f26d
commit 8069d0ea89
2 changed files with 33 additions and 36 deletions
@@ -139,7 +139,7 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
// ── Step 5: Create hazards from matched patterns (skip if exist) ── // ── Step 5: Create hazards from matched patterns (skip if exist) ──
existingHazards, _ := h.store.ListHazards(ctx, projectID) existingHazards, _ := h.store.ListHazards(ctx, projectID)
hazardStep := InitStep{Name: "Gefaehrdungen erstellt", Status: "skipped"} hazardStep := InitStep{Name: "Gefaehrdungen erstellt", Status: "skipped"}
hazardIDsByCategory := make(map[string]uuid.UUID) hazardIDsByCategory := make(map[string][]uuid.UUID)
if len(existingHazards) == 0 && len(matchOutput.MatchedPatterns) > 0 { if len(existingHazards) == 0 && len(matchOutput.MatchedPatterns) > 0 {
comps, _ := h.store.ListComponents(ctx, projectID) comps, _ := h.store.ListComponents(ctx, projectID)
@@ -225,7 +225,7 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
if cerr == nil { if cerr == nil {
created++ created++
catCount[cat]++ catCount[cat]++
hazardIDsByCategory[cat] = hz.ID hazardIDsByCategory[cat] = append(hazardIDsByCategory[cat], hz.ID)
} }
} }
} }
@@ -234,7 +234,7 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
hazardStep.Details = "Bereits vorhanden" hazardStep.Details = "Bereits vorhanden"
hazardStep.Count = len(existingHazards) hazardStep.Count = len(existingHazards)
for _, eh := range existingHazards { for _, eh := range existingHazards {
hazardIDsByCategory[eh.Category] = eh.ID hazardIDsByCategory[eh.Category] = append(hazardIDsByCategory[eh.Category], eh.ID)
} }
} }
steps = append(steps, hazardStep) steps = append(steps, hazardStep)
@@ -253,51 +253,51 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
} }
created := 0 created := 0
usedMeasureIDs := make(map[string]bool)
// Assign suggested measures to ALL hazards in matching category
for _, sm := range matchOutput.SuggestedMeasures { for _, sm := range matchOutput.SuggestedMeasures {
entry, ok := measureByID[sm.MeasureID] entry, ok := measureByID[sm.MeasureID]
if !ok || usedMeasureIDs[sm.MeasureID] { if !ok {
continue
}
hazardID := findHazardForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
if hazardID == uuid.Nil {
continue continue
} }
hazardIDs := findHazardsForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
rt := iace.ReductionType(entry.ReductionType) rt := iace.ReductionType(entry.ReductionType)
if rt == "" { if rt == "" {
rt = iace.ReductionTypeInformation rt = iace.ReductionTypeInformation
} }
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{ for _, hazID := range hazardIDs {
HazardID: hazardID, ReductionType: rt, _, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
Name: entry.Name, Description: entry.Description, HazardID: hazID, ReductionType: rt,
}) Name: entry.Name, Description: entry.Description,
if cerr == nil { })
created++ if cerr == nil {
usedMeasureIDs[sm.MeasureID] = true created++
}
} }
} }
for hazCat, hazID := range hazardIDsByCategory { // Fallback: assign category-based measures to ALL hazards per category
for hazCat, hazIDs := range hazardIDsByCategory {
measCat := patternCatToMeasureCat(hazCat) measCat := patternCatToMeasureCat(hazCat)
added := 0 added := 0
for _, m := range measuresByCat[measCat] { for _, m := range measuresByCat[measCat] {
if usedMeasureIDs[m.ID] || added >= 8 { if added >= 5 {
break break
} }
rt := iace.ReductionType(m.ReductionType) rt := iace.ReductionType(m.ReductionType)
if rt == "" { if rt == "" {
rt = iace.ReductionTypeInformation rt = iace.ReductionTypeInformation
} }
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{ for _, hazID := range hazIDs {
HazardID: hazID, ReductionType: rt, _, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
Name: m.Name, Description: m.Description, HazardID: hazID, ReductionType: rt,
}) Name: m.Name, Description: m.Description,
if cerr == nil { })
created++ if cerr == nil {
usedMeasureIDs[m.ID] = true created++
added++ }
} }
added++
} }
} }
mitStep = InitStep{Name: "Massnahmen erstellt", Status: "done", Count: created} mitStep = InitStep{Name: "Massnahmen erstellt", Status: "done", Count: created}
@@ -369,18 +369,15 @@ func normalizeZoneKey(zone string) string {
return strings.Join(sig, "_") return strings.Join(sig, "_")
} }
// findHazardForMeasureByCategory finds a matching hazard for a measure. // findHazardsForMeasureByCategory finds all hazards matching a measure's category.
func findHazardForMeasureByCategory(measureCat string, hazardsByCategory map[string]uuid.UUID) uuid.UUID { func findHazardsForMeasureByCategory(measureCat string, hazardsByCategory map[string][]uuid.UUID) []uuid.UUID {
if id, ok := hazardsByCategory[measureCat]; ok { if ids, ok := hazardsByCategory[measureCat]; ok {
return id return ids
} }
for cat, id := range hazardsByCategory { for cat, ids := range hazardsByCategory {
if len(measureCat) > 3 && len(cat) > 3 && cat[:4] == measureCat[:4] { if len(measureCat) > 3 && len(cat) > 3 && cat[:4] == measureCat[:4] {
return id return ids
} }
} }
for _, id := range hazardsByCategory { return nil
return id
}
return uuid.Nil
} }