fix(iace): max 5 mitigations per hazard — clean per-hazard assignment
Replaced category-broadcast logic with per-hazard loop: each hazard gets up to 5 measures (pattern-suggested first, then category fallback). Expected: 108 × 5 = max 540 total. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -253,67 +253,66 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
created := 0
|
created := 0
|
||||||
|
const maxMitigationsPerHazard = 5
|
||||||
|
|
||||||
// Assign suggested measures to ALL hazards in matching category
|
// Build a flat list of all hazard IDs for iteration
|
||||||
|
var allHazardIDs []uuid.UUID
|
||||||
|
hazardCatByID := make(map[uuid.UUID]string)
|
||||||
|
for cat, ids := range hazardIDsByCategory {
|
||||||
|
for _, id := range ids {
|
||||||
|
allHazardIDs = append(allHazardIDs, id)
|
||||||
|
hazardCatByID[id] = cat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each hazard: assign up to maxMitigationsPerHazard measures
|
||||||
|
// Priority: pattern-suggested first, then category fallback
|
||||||
|
suggestedByMeasCat := make(map[string][]iace.ProtectiveMeasureEntry)
|
||||||
for _, sm := range matchOutput.SuggestedMeasures {
|
for _, sm := range matchOutput.SuggestedMeasures {
|
||||||
entry, ok := measureByID[sm.MeasureID]
|
if entry, ok := measureByID[sm.MeasureID]; ok {
|
||||||
if !ok {
|
suggestedByMeasCat[entry.HazardCategory] = append(suggestedByMeasCat[entry.HazardCategory], entry)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
hazardIDs := findHazardsForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
|
}
|
||||||
rt := iace.ReductionType(entry.ReductionType)
|
|
||||||
if rt == "" {
|
for _, hazID := range allHazardIDs {
|
||||||
rt = iace.ReductionTypeInformation
|
hazCat := hazardCatByID[hazID]
|
||||||
}
|
measCat := patternCatToMeasureCat(hazCat)
|
||||||
for _, hazID := range hazardIDs {
|
added := 0
|
||||||
|
|
||||||
|
// First: pattern-suggested measures for this category
|
||||||
|
for _, entry := range suggestedByMeasCat[measCat] {
|
||||||
|
if added >= maxMitigationsPerHazard {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
rt := iace.ReductionType(entry.ReductionType)
|
||||||
|
if rt == "" {
|
||||||
|
rt = iace.ReductionTypeInformation
|
||||||
|
}
|
||||||
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
|
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
|
||||||
HazardID: hazID, ReductionType: rt,
|
HazardID: hazID, ReductionType: rt,
|
||||||
Name: entry.Name, Description: entry.Description,
|
Name: entry.Name, Description: entry.Description,
|
||||||
})
|
})
|
||||||
if cerr == nil {
|
if cerr == nil {
|
||||||
created++
|
created++
|
||||||
|
added++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback: assign category-based measures only to hazards that
|
// Then: category fallback if still under limit
|
||||||
// didn't get any measures from pattern suggestions (max 3 per hazard)
|
for _, m := range measuresByCat[measCat] {
|
||||||
hazardsWithMeasures := make(map[uuid.UUID]bool)
|
if added >= maxMitigationsPerHazard {
|
||||||
for _, sm := range matchOutput.SuggestedMeasures {
|
break
|
||||||
entry, ok := measureByID[sm.MeasureID]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, ids := range hazardIDsByCategory {
|
|
||||||
for _, id := range ids {
|
|
||||||
_ = entry // suppress unused
|
|
||||||
hazardsWithMeasures[id] = true
|
|
||||||
}
|
}
|
||||||
}
|
rt := iace.ReductionType(m.ReductionType)
|
||||||
}
|
if rt == "" {
|
||||||
for hazCat, hazIDs := range hazardIDsByCategory {
|
rt = iace.ReductionTypeInformation
|
||||||
measCat := patternCatToMeasureCat(hazCat)
|
|
||||||
measures := measuresByCat[measCat]
|
|
||||||
for _, hazID := range hazIDs {
|
|
||||||
if hazardsWithMeasures[hazID] {
|
|
||||||
continue // Already has pattern-suggested measures
|
|
||||||
}
|
}
|
||||||
added := 0
|
_, cerr := h.store.CreateMitigation(ctx, iace.CreateMitigationRequest{
|
||||||
for _, m := range measures {
|
HazardID: hazID, ReductionType: rt,
|
||||||
if added >= 3 {
|
Name: m.Name, Description: m.Description,
|
||||||
break
|
})
|
||||||
}
|
if cerr == nil {
|
||||||
rt := iace.ReductionType(m.ReductionType)
|
created++
|
||||||
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++
|
|
||||||
}
|
|
||||||
added++
|
added++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user