2026-07-13 13:22:12 -03:00
|
|
|
using Microsoft.Extensions.Options;
|
2026-07-24 17:35:34 -03:00
|
|
|
using SeaHaven.DataServices.Interfaces;
|
2026-07-13 13:22:12 -03:00
|
|
|
using SeaHaven.Services.DTOs;
|
|
|
|
|
using SeaHaven.Services.Interfaces;
|
|
|
|
|
|
|
|
|
|
namespace SeaHaven.Services.Implementation
|
|
|
|
|
{
|
|
|
|
|
public class WorkOrderOpsHealthService : IWorkOrderOpsHealthService
|
|
|
|
|
{
|
2026-07-24 17:35:34 -03:00
|
|
|
private readonly IWorkOrderOpsHealthDataService _healthData;
|
|
|
|
|
private readonly IWorkOrderJobRunStateAccessor _runState;
|
2026-07-13 13:22:12 -03:00
|
|
|
private readonly WorkOrderOpsHealthOptions _options;
|
|
|
|
|
|
|
|
|
|
public WorkOrderOpsHealthService(
|
2026-07-24 17:35:34 -03:00
|
|
|
IWorkOrderOpsHealthDataService healthData,
|
|
|
|
|
IWorkOrderJobRunStateAccessor runState,
|
2026-07-13 13:22:12 -03:00
|
|
|
IOptions<WorkOrderOpsHealthOptions> options)
|
|
|
|
|
{
|
2026-07-24 17:35:34 -03:00
|
|
|
_healthData = healthData;
|
2026-07-13 13:22:12 -03:00
|
|
|
_runState = runState;
|
|
|
|
|
_options = options.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<WorkOrderOpsHealthDto> GetHealthAsync(CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var since = DateTime.UtcNow.AddHours(-24);
|
|
|
|
|
|
2026-07-24 17:35:34 -03:00
|
|
|
var syncRejected = await _healthData.CountSyncRejectedSinceAsync(since, cancellationToken);
|
|
|
|
|
var fieldLocks = await _healthData.CountFieldLocksAsync(cancellationToken);
|
2026-07-13 13:22:12 -03:00
|
|
|
|
|
|
|
|
var state = _runState.State;
|
2026-07-24 17:35:34 -03:00
|
|
|
var ledgerWeekRolled = await _healthData.GetLastWeekRolledProcessedAtAsync(cancellationToken);
|
2026-07-13 13:22:12 -03:00
|
|
|
|
|
|
|
|
return new WorkOrderOpsHealthDto
|
|
|
|
|
{
|
|
|
|
|
LastWeekRolledRunUtc = state.LastWeekRolledRunUtc ?? ledgerWeekRolled,
|
|
|
|
|
LastPastDueCacheRunUtc = state.LastPastDueCacheRunUtc,
|
|
|
|
|
LastWeekRolledError = state.LastWeekRolledError,
|
|
|
|
|
LastPastDueCacheError = state.LastPastDueCacheError,
|
|
|
|
|
SyncRejectedLast24h = syncRejected,
|
|
|
|
|
FieldLockCount = fieldLocks,
|
|
|
|
|
SyncEnabled = _options.SyncEnabled,
|
|
|
|
|
IngestEnabled = _options.IngestEnabled,
|
|
|
|
|
LegacyDeprecationEnabled = _options.LegacyDeprecationEnabled,
|
|
|
|
|
LegacySunsetDate = _options.LegacySunsetDate,
|
|
|
|
|
CheckedAtUtc = DateTime.UtcNow
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Options bridged from API configuration for health snapshots.</summary>
|
|
|
|
|
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; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Shared in-memory job run timestamps (API hosted services + ops health).</summary>
|
2026-07-24 17:35:34 -03:00
|
|
|
public class WorkOrderJobRunStateAccessor : IWorkOrderJobRunStateAccessor
|
2026-07-13 13:22:12 -03:00
|
|
|
{
|
|
|
|
|
public WorkOrderJobRunState State { get; } = new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|