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,54 +253,54 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
|
||||
}
|
||||
|
||||
created := 0
|
||||
const maxMitigationsPerHazard = 5
|
||||
|
||||
// Assign suggested measures to ALL hazards in matching category
|
||||
for _, sm := range matchOutput.SuggestedMeasures {
|
||||
entry, ok := measureByID[sm.MeasureID]
|
||||
if !ok {
|
||||
continue
|
||||
// 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 {
|
||||
if entry, ok := measureByID[sm.MeasureID]; ok {
|
||||
suggestedByMeasCat[entry.HazardCategory] = append(suggestedByMeasCat[entry.HazardCategory], entry)
|
||||
}
|
||||
}
|
||||
|
||||
for _, hazID := range allHazardIDs {
|
||||
hazCat := hazardCatByID[hazID]
|
||||
measCat := patternCatToMeasureCat(hazCat)
|
||||
added := 0
|
||||
|
||||
// First: pattern-suggested measures for this category
|
||||
for _, entry := range suggestedByMeasCat[measCat] {
|
||||
if added >= maxMitigationsPerHazard {
|
||||
break
|
||||
}
|
||||
hazardIDs := findHazardsForMeasureByCategory(entry.HazardCategory, hazardIDsByCategory)
|
||||
rt := iace.ReductionType(entry.ReductionType)
|
||||
if rt == "" {
|
||||
rt = iace.ReductionTypeInformation
|
||||
}
|
||||
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++
|
||||
}
|
||||
added++
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: assign category-based measures only to hazards that
|
||||
// didn't get any measures from pattern suggestions (max 3 per hazard)
|
||||
hazardsWithMeasures := make(map[uuid.UUID]bool)
|
||||
for _, sm := range matchOutput.SuggestedMeasures {
|
||||
entry, ok := measureByID[sm.MeasureID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, ids := range hazardIDsByCategory {
|
||||
for _, id := range ids {
|
||||
_ = entry // suppress unused
|
||||
hazardsWithMeasures[id] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
for hazCat, hazIDs := range hazardIDsByCategory {
|
||||
measCat := patternCatToMeasureCat(hazCat)
|
||||
measures := measuresByCat[measCat]
|
||||
for _, hazID := range hazIDs {
|
||||
if hazardsWithMeasures[hazID] {
|
||||
continue // Already has pattern-suggested measures
|
||||
}
|
||||
added := 0
|
||||
for _, m := range measures {
|
||||
if added >= 3 {
|
||||
// Then: category fallback if still under limit
|
||||
for _, m := range measuresByCat[measCat] {
|
||||
if added >= maxMitigationsPerHazard {
|
||||
break
|
||||
}
|
||||
rt := iace.ReductionType(m.ReductionType)
|
||||
@@ -313,7 +313,6 @@ func (h *IACEHandler) InitializeProject(c *gin.Context) {
|
||||
})
|
||||
if cerr == nil {
|
||||
created++
|
||||
}
|
||||
added++
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user