From bf974c4a572e6312359b5fe4cef3c04d4e9a6380 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Mon, 11 May 2026 14:22:37 +0200 Subject: [PATCH] fix(dashboard/stats): Active = InProgress only, drop Pending + Stalled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live data showed cross-tenant 7d breakdown of non-terminal sessions: InProgress 11, Pending 43, Stalled 6 = 60 total. The Pending bucket dominates for any tenant with regular WhiteGlove provisioning — those sessions have completed pre-prov and are waiting for the end user to power on the device, which can take days or weeks. Counting them under "Currently enrolling" implies live activity that isn't happening. Active now matches the literal in-flight status. Pending and Stalled remain visible via the sessions list filters; if we want a richer breakdown on the card row later, it can be split into separate cards without further changing the Active semantics. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../SessionStatsAggregationTests.cs | 24 ++++++++++--------- .../Services/TableStorageService.Sessions.cs | 7 ++++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Backend/AutopilotMonitor.Functions.Tests/SessionStatsAggregationTests.cs b/src/Backend/AutopilotMonitor.Functions.Tests/SessionStatsAggregationTests.cs index bc6c95ac..dbc6ea60 100644 --- a/src/Backend/AutopilotMonitor.Functions.Tests/SessionStatsAggregationTests.cs +++ b/src/Backend/AutopilotMonitor.Functions.Tests/SessionStatsAggregationTests.cs @@ -41,26 +41,28 @@ public class SessionStatsAggregationTests } [Fact] - public void Active_count_includes_InProgress_Pending_Stalled_but_not_terminal() + public void Active_count_is_InProgress_only() { - // "Currently enrolling" covers everything still in flight: InProgress - // (mid-enrollment), Pending (WhiteGlove waiting for user), Stalled - // (>60min stale — non-terminal, can heal back to InProgress). Terminal - // states (Succeeded / Failed) and Unknown are NOT in flight. + // "Currently enrolling" must match LIVE activity. Pending (WhiteGlove + // pre-prov complete, awaiting user power-on) and Stalled (>60min no + // progress) are non-terminal but NOT actively enrolling — Pending in + // particular can sit for days/weeks and would dominate the count for + // any tenant with regular WhiteGlove provisioning. var now = DateTime.UtcNow; var sessions = new[] { MakeSession(SessionStatus.InProgress, now.AddHours(-1)), - MakeSession(SessionStatus.Pending, now.AddHours(-2)), - MakeSession(SessionStatus.Stalled, now.AddHours(-3)), - MakeSession(SessionStatus.Succeeded, now.AddHours(-4), 600), - MakeSession(SessionStatus.Failed, now.AddHours(-5)), - MakeSession(SessionStatus.Unknown, now.AddHours(-6)), + MakeSession(SessionStatus.InProgress, now.AddHours(-2)), + MakeSession(SessionStatus.Pending, now.AddHours(-3)), + MakeSession(SessionStatus.Stalled, now.AddHours(-4)), + MakeSession(SessionStatus.Succeeded, now.AddHours(-5), 600), + MakeSession(SessionStatus.Failed, now.AddHours(-6)), + MakeSession(SessionStatus.Unknown, now.AddHours(-7)), }; var stats = TableStorageService.AggregateSessionStats(sessions, days: 7); - Assert.Equal(3, stats.ActiveCount); + Assert.Equal(2, stats.ActiveCount); } [Fact] diff --git a/src/Backend/AutopilotMonitor.Functions/Services/TableStorageService.Sessions.cs b/src/Backend/AutopilotMonitor.Functions/Services/TableStorageService.Sessions.cs index 3869a5ac..8330c3e8 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/TableStorageService.Sessions.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/TableStorageService.Sessions.cs @@ -841,8 +841,11 @@ namespace AutopilotMonitor.Functions.Services switch (s.Status) { case SessionStatus.InProgress: - case SessionStatus.Pending: // WhiteGlove pre-prov complete, waiting for user — still in flight - case SessionStatus.Stalled: // >60min no progress, non-terminal — can heal back to InProgress + // Card label "Currently enrolling" — literal match to the agent's + // in-flight status. Pending (WhiteGlove pre-prov complete, awaiting + // user) often lingers for days/weeks and isn't actively enrolling; + // Stalled (>60min stale) isn't either. Both belong on dedicated + // breakdowns/filters, not on a card that implies live activity. active++; break; case SessionStatus.Succeeded: