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) ──
existingHazards, _ := h.store.ListHazards(ctx, projectID)
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 {
comps, _ := h.store.ListComponents(ctx, projectID)
@@ -225,7 +225,7 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
if cerr == nil {
created++
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.Count = len(existingHazards)
for _, eh := range existingHazards {
hazardIDsByCategory[eh.Category] = eh.ID
hazardIDsByCategory[eh.Category] = append(hazardIDsByCategory[eh.Category], eh.ID)
}
}
steps = append(steps, hazardStep)
@@ -253,51 +253,51 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
}
created := 0
usedMeasureIDs := make(map[string]bool)
// Assign suggested measures to ALL hazards in matching category
for _, sm := range matchOutput.SuggestedMeasures {
entry, ok := measureByID[sm.MeasureID]
if !ok || usedMeasureIDs[sm.MeasureID] {
continue
}
hazardID := findHazardForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
if hazardID == uuid.Nil {
if !ok {
continue
}
hazardIDs := findHazardsForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
rt := iace.ReductionType(entry.ReductionType)
if rt == "" {
rt = iace.ReductionTypeInformation
}
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
HazardID: hazardID, ReductionType: rt,
Name: entry.Name, Description: entry.Description,
})
if cerr == nil {
created++
usedMeasureIDs[sm.MeasureID] = true
for _, hazID := range hazardIDs {
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
HazardID: hazID, ReductionType: rt,
Name: entry.Name, Description: entry.Description,
})
if cerr == nil {
created++
}
}
}
for hazCat, hazID := range hazardIDsByCategory {
// Fallback: assign category-based measures to ALL hazards per category
for hazCat, hazIDs := range hazardIDsByCategory {
measCat := patternCatToMeasureCat(hazCat)
added := 0
for _, m := range measuresByCat[measCat] {
if usedMeasureIDs[m.ID] || added >= 8 {
if added >= 5 {
break
}
rt := iace.ReductionType(m.ReductionType)
if rt == "" {
rt = iace.ReductionTypeInformation
}
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
HazardID: hazID, ReductionType: rt,
Name: m.Name, Description: m.Description,
})
if cerr == nil {
created++
usedMeasureIDs[m.ID] = true
added++
for _, hazID := range hazIDs {
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
HazardID: hazID, ReductionType: rt,
Name: m.Name, Description: m.Description,
})
if cerr == nil {
created++
}
}
added++
}
}
mitStep = InitStep{Name: "Massnahmen erstellt", Status: "done", Count: created}
@@ -369,18 +369,15 @@ func normalizeZoneKey(zone string) string {
return strings.Join(sig, "_")
}
// findHazardForMeasureByCategory finds a matching hazard for a measure.
func findHazardForMeasureByCategory(measureCat string, hazardsByCategory map[string]uuid.UUID) uuid.UUID {
if id, ok := hazardsByCategory[measureCat]; ok {
return id
// findHazardsForMeasureByCategory finds all hazards matching a measure's category.
func findHazardsForMeasureByCategory(measureCat string, hazardsByCategory map[string][]uuid.UUID) []uuid.UUID {
if ids, ok := hazardsByCategory[measureCat]; ok {
return ids
}
for cat, id := range hazardsByCategory {
for cat, ids := range hazardsByCategory {
if len(measureCat) > 3 && len(cat) > 3 && cat[:4] == measureCat[:4] {
return id
return ids
}
}
for _, id := range hazardsByCategory {
return id
}
return uuid.Nil
return nil
}