diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt index cc5027ee..3091e8ee 100644 --- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt +++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt @@ -1 +1 @@ -502 +504 diff --git a/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs b/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs index a56080f6..98db1f89 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/MaintenanceService.cs @@ -86,16 +86,11 @@ namespace AutopilotMonitor.Functions.Services await CleanupOldDataAsync(); await RecomputePlatformStatsAsync(); - // Safety net: backfill any sessions missing from SessionsIndex - await _storageService.BackfillSessionIndexAsync(); - - // One-time cleanup: remove ghost SessionsIndex entries caused by the - // StoreSessionAsync Replace-mode IndexRowKey bug (now fixed). - // TODO: Remove after 2026-06-01 - await _storageService.CleanupGhostSessionIndexEntriesAsync(); - - // Backfill OnboardedAt for tenants that don't have it yet - await BackfillTenantOnboardedAtAsync(); + // Backfill and one-time repair tasks run only via manual trigger (RunManualAsync) + // to keep the timer-triggered path lightweight. See RunManualAsync for: + // - BackfillSessionIndexAsync (safety net for missing index entries) + // - CleanupGhostSessionIndexEntriesAsync (one-time ghost cleanup) + // - BackfillTenantOnboardedAtAsync (backfill missing OnboardedAt) maintenanceStart.Stop(); _logger.LogInformation($"Daily maintenance completed in {maintenanceStart.ElapsedMilliseconds}ms"); @@ -132,6 +127,20 @@ namespace AutopilotMonitor.Functions.Services { await CleanupOldDataAsync(); result.DataCleanupExecuted = true; + + // --- Backfill & repair tasks (manual-only, not in timer path) --- + + // Safety net: backfill any sessions missing from SessionsIndex + await _storageService.BackfillSessionIndexAsync(); + + // One-time cleanup: remove ghost SessionsIndex entries caused by the + // StoreSessionAsync Replace-mode IndexRowKey bug (now fixed). + // TODO: Remove after 2026-06-01 + await _storageService.CleanupGhostSessionIndexEntriesAsync(); + + // Backfill OnboardedAt for tenants that don't have it yet + // TODO: Remove once all tenants have been backfilled + await BackfillTenantOnboardedAtAsync(); } await RecomputePlatformStatsAsync(); diff --git a/src/Web/autopilot-monitor-web/app/admin-configuration/components/MaintenanceSection.tsx b/src/Web/autopilot-monitor-web/app/admin-configuration/components/MaintenanceSection.tsx index c9c3e74d..3975f48b 100644 --- a/src/Web/autopilot-monitor-web/app/admin-configuration/components/MaintenanceSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin-configuration/components/MaintenanceSection.tsx @@ -195,22 +195,48 @@ export function MaintenanceSection({

- Manually trigger the daily maintenance job which includes: + Runs all timer-triggered tasks plus additional backfill & repair operations that only run on manual trigger.

- +
+
+

Standard tasks (also run by 2h timer)

+
    +
  • + • + Mark stalled sessions as timed out +
  • +
  • + • + Aggregate metrics into historical snapshots +
  • +
  • + • + Clean up old data based on retention policies +
  • +
  • + • + Recompute platform-wide statistics +
  • +
+
+
+

Manual-only tasks (backfill & repair)

+
    +
  • + • + Backfill sessions missing from SessionsIndex +
  • +
  • + • + Clean up ghost SessionsIndex entries (remove after 2026-06) +
  • +
  • + • + Backfill tenant OnboardedAt dates (remove when complete) +
  • +
+
+