using Data.SeaHavenIndustries; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using SeaHaven.Services.DTOs; using SeaHaven.Services.Interfaces; namespace SeaHaven.Services.Implementation { public class WorkOrderOpsHealthService : IWorkOrderOpsHealthService { private readonly ApplicationDbContext _db; private readonly WorkOrderJobRunStateAccessor _runState; private readonly bool _syncEnabled; private readonly bool _ingestEnabled; private readonly bool _legacyDeprecationEnabled; private readonly string? _legacySunsetDate; public WorkOrderOpsHealthService( ApplicationDbContext db, WorkOrderJobRunStateAccessor runState, IOptions options) { _db = db; _runState = runState; _syncEnabled = options.Value.SyncEnabled; _ingestEnabled = options.Value.IngestEnabled; _legacyDeprecationEnabled = options.Value.LegacyDeprecationEnabled; _legacySunsetDate = options.Value.LegacySunsetDate; } public async Task GetHealthAsync(CancellationToken cancellationToken = default) { var since = DateTime.UtcNow.AddHours(-24); var syncRejected = await _db.WorkOrderAuditLogs .CountAsync(l => l.Action == "SyncRejected" && l.CreatedAt >= since, cancellationToken); var fieldLocks = await _db.WorkOrderFieldLocks.CountAsync(cancellationToken); var state = _runState.State; var ledgerWeekRolled = await _db.WorkOrderWeekRolledLedgers .MaxAsync(l => (DateTime?)l.ProcessedAt, cancellationToken); return new WorkOrderOpsHealthDto { LastWeekRolledRunUtc = state.LastWeekRolledRunUtc ?? ledgerWeekRolled, LastPastDueCacheRunUtc = state.LastPastDueCacheRunUtc, LastWeekRolledError = state.LastWeekRolledError, LastPastDueCacheError = state.LastPastDueCacheError, SyncRejectedLast24h = syncRejected, FieldLockCount = fieldLocks, SyncEnabled = _syncEnabled, IngestEnabled = _ingestEnabled, LegacyDeprecationEnabled = _legacyDeprecationEnabled, LegacySunsetDate = _legacySunsetDate, CheckedAtUtc = DateTime.UtcNow }; } } /// Options bridged from API configuration for health snapshots. public class WorkOrderOpsHealthOptions { public bool SyncEnabled { get; set; } = true; public bool IngestEnabled { get; set; } = true; public bool LegacyDeprecationEnabled { get; set; } public string? LegacySunsetDate { get; set; } } public class WorkOrderJobRunStateAccessor { public WorkOrderJobRunState State { get; } = new(); } public class WorkOrderJobRunState { public DateTime? LastWeekRolledRunUtc { get; set; } public DateTime? LastPastDueCacheRunUtc { get; set; } public string? LastWeekRolledError { get; set; } public string? LastPastDueCacheError { get; set; } } }