using OTSSignsOrchestrator.Server.Clients; using OTSSignsOrchestrator.Server.Data.Entities; namespace OTSSignsOrchestrator.Server.Health.Checks; /// /// Verifies the count of authorised displays does not exceed the customer's licensed /// . Uses /// with authorised=1 filter to get all authorised displays. /// public sealed class DisplayAuthorisedHealthCheck : IHealthCheck { private readonly XiboClientFactory _clientFactory; private readonly IServiceProvider _services; private readonly ILogger _logger; public string CheckName => "DisplayAuthorised"; public bool AutoRemediate => false; public DisplayAuthorisedHealthCheck( XiboClientFactory clientFactory, IServiceProvider services, ILogger logger) { _clientFactory = clientFactory; _services = services; _logger = logger; } public async Task RunAsync(Instance instance, CancellationToken ct) { var (client, _) = await ResolveAsync(instance); if (client is null) return new HealthCheckResult(HealthStatus.Critical, "No OAuth app — cannot check displays"); try { var displays = await client.GetAllPagesAsync( (start, length) => client.GetDisplaysAsync(start, length, authorised: 1)); var authorisedCount = displays.Count; var licensed = instance.Customer.ScreenCount; if (authorisedCount <= licensed) { return new HealthCheckResult(HealthStatus.Healthy, $"Authorised displays: {authorisedCount}/{licensed}"); } return new HealthCheckResult(HealthStatus.Degraded, $"Authorised displays ({authorisedCount}) exceeds license ({licensed})", $"Over-provisioned by {authorisedCount - licensed} display(s)"); } catch (Exception ex) { return new HealthCheckResult(HealthStatus.Critical, $"Failed to check displays: {ex.Message}"); } } private async Task<(IXiboApiClient? Client, string Abbrev)> ResolveAsync(Instance instance) { var abbrev = instance.Customer.Abbreviation; var oauthApp = instance.OauthAppRegistries.FirstOrDefault(); if (oauthApp is null) return (null, abbrev); var settings = _services.GetRequiredService(); var secret = await settings.GetAsync(Core.Services.SettingsService.InstanceOAuthSecretId(abbrev)); if (string.IsNullOrEmpty(secret)) return (null, abbrev); var client = await _clientFactory.CreateAsync(instance.XiboUrl, oauthApp.ClientId, secret); return (client, abbrev); } }