From 8f9aec3e053baa99bc63d82c6fe35e262372b7e2 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Tue, 24 Feb 2026 14:17:07 +0100 Subject: [PATCH] fix: make Analyze Now button actually re-run all rules Previously, AnalyzeSessionAsync always loaded existing results and skipped rules already evaluated (deduplication check). The reanalyze flag from the API endpoint was never passed through, so clicking "Analyze Now" only returned cached results. Fix: - Add `reanalyze` parameter to `AnalyzeSessionAsync`; when true, skip deduplication so all active rules evaluate against the full event stream - In GetRuleResultsFunction, pass reanalyze=true and delete stale stored results before writing the fresh evaluation output Co-Authored-By: Claude Sonnet 4.6 --- .../Functions/GetRuleResultsFunction.cs | 12 ++++++------ .../Services/RuleEngine.cs | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs index d6dace29..32bae941 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/GetRuleResultsFunction.cs @@ -49,17 +49,17 @@ namespace AutopilotMonitor.Functions.Functions try { var ruleEngine = new RuleEngine(_analyzeRuleService, _storageService, _logger); - var newResults = await ruleEngine.AnalyzeSessionAsync(tenantId, sessionId); + var freshResults = await ruleEngine.AnalyzeSessionAsync(tenantId, sessionId, reanalyze: true); - foreach (var result in newResults) + // Delete existing results so stale entries don't persist after re-analysis + await _storageService.DeleteSessionRuleResultsAsync(tenantId, sessionId); + + foreach (var result in freshResults) { await _storageService.StoreRuleResultAsync(result); } - if (newResults.Count > 0) - { - _logger.LogInformation($"On-demand analysis for session {sessionId}: {newResults.Count} new issue(s) detected"); - } + _logger.LogInformation($"On-demand re-analysis for session {sessionId}: {freshResults.Count} issue(s) detected"); } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs b/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs index 64259abb..7a46059c 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/RuleEngine.cs @@ -25,8 +25,9 @@ namespace AutopilotMonitor.Functions.Services /// /// Evaluates ALL active analyze rules against the full session event stream. /// Called once at enrollment end or on-demand. Fetches events internally. + /// When reanalyze=true, all rules are re-evaluated regardless of existing results. /// - public async Task> AnalyzeSessionAsync(string tenantId, string sessionId) + public async Task> AnalyzeSessionAsync(string tenantId, string sessionId, bool reanalyze = false) { var results = new List(); @@ -41,9 +42,18 @@ namespace AutopilotMonitor.Functions.Services return results; } - // Get existing rule results to avoid duplicates - var existingResults = await _storageService.GetRuleResultsAsync(tenantId, sessionId); - var existingRuleIds = new HashSet(existingResults.Select(r => r.RuleId)); + // On reanalyze: skip deduplication so all rules are re-evaluated from scratch + // On normal run: skip rules already evaluated to avoid duplicate storage + HashSet existingRuleIds; + if (reanalyze) + { + existingRuleIds = new HashSet(); + } + else + { + var existingResults = await _storageService.GetRuleResultsAsync(tenantId, sessionId); + existingRuleIds = new HashSet(existingResults.Select(r => r.RuleId)); + } _logger.LogInformation($"Analyzing session {sessionId}: {allEvents.Count} events, {activeRules.Count} rules ({existingRuleIds.Count} already evaluated)");