From 499210eff226bf40d23f40825a22767cdea28816 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Fri, 8 May 2026 07:03:44 +0200 Subject: [PATCH] =?UTF-8?q?perf:=20Fix=20N+1=20query=20in=20production=20l?= =?UTF-8?q?ine=20dashboard=20(27s=20=E2=86=92=20<1s)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GetLineDashboard called GetLatestAssessment per hazard (N+1 queries). Replaced with GetLatestAssessmentsByProject — one batch query per station instead of one per hazard. With 50+ hazards across multiple stations, this reduces hundreds of DB queries to ~5. Co-Authored-By: Claude Opus 4.6 (1M context) --- ai-compliance-sdk/internal/iace/store_production_lines.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ai-compliance-sdk/internal/iace/store_production_lines.go b/ai-compliance-sdk/internal/iace/store_production_lines.go index 32bc107..9f8afdf 100644 --- a/ai-compliance-sdk/internal/iace/store_production_lines.go +++ b/ai-compliance-sdk/internal/iace/store_production_lines.go @@ -256,10 +256,12 @@ func (s *Store) buildStationDashboard(ctx context.Context, st ProductionLineStat mitigations, _ := s.ListMitigationsByProject(ctx, st.ProjectID) sd.MitigationCount = len(mitigations) - // Compute risk summary and max SIL/PL from latest assessments + // Batch-load all latest assessments in ONE query (not N+1) + latestByHazard, _ := s.GetLatestAssessmentsByProject(ctx, st.ProjectID) + for _, h := range hazards { - latest, _ := s.GetLatestAssessment(ctx, h.ID) - if latest == nil { + latest, ok := latestByHazard[h.ID] + if !ok { continue }