using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; using QuantEngine.Core.Interfaces; using QuantEngine.Application.Interfaces; using QuantEngine.Web.Services; namespace QuantEngine.Web.Pages.Admin.Monitoring; [Authorize(AuthenticationSchemes = AdminAuthDefaults.Scheme)] public class IndexModel : PageModel { private readonly ICollectionReadRepository _collectionRepository; private readonly ILogger _logger; public List? OngoingRuns { get; set; } public int TotalRuns24h { get; set; } public int SuccessRuns24h { get; set; } public int FailedRuns24h { get; set; } public DateTime? LastRefreshTime { get; set; } public List? RecentErrors { get; set; } public bool IsDatabaseConnected { get; set; } public IndexModel(ICollectionReadRepository collectionRepository, ILogger logger) { _collectionRepository = collectionRepository; _logger = logger; } public async Task OnGetAsync() { try { LastRefreshTime = DateTime.UtcNow; var runs = await _collectionRepository.GetRecentRunsAsync(limit: 100); OngoingRuns = runs.Where(r => r.Status == "running").ToList(); var last24h = DateTime.UtcNow.AddHours(-24); var runs24h = runs.Where(r => { if (DateTime.TryParse(r.StartedAt?.ToString(), out var startedAt)) return startedAt >= last24h; return false; }).ToList(); TotalRuns24h = runs24h.Count; SuccessRuns24h = runs24h.Count(r => r.Status == "completed" && r.TotalSnapshots > 0); FailedRuns24h = runs24h.Count(r => r.Status == "failed" || r.TotalSnapshots == 0); var allErrors = new List(); foreach (var run in runs.Take(20)) { try { var errors = await _collectionRepository.GetRunErrorsAsync(run.RunId, limit: 5); allErrors.AddRange(errors); } catch (Exception ex) { _logger.LogWarning(ex, "Failed to load errors for run {RunId}", run.RunId); } } RecentErrors = allErrors.OrderByDescending(e => e.CreatedAt).Take(10).ToList(); IsDatabaseConnected = true; } catch (Exception ex) { _logger.LogError(ex, "Failed to load monitoring data"); OngoingRuns = []; RecentErrors = []; IsDatabaseConnected = false; } } }