Files

76 lines
2.6 KiB
C#

using Microsoft.EntityFrameworkCore;
public class SepsisBundleMonitorService : BackgroundService
{
private static readonly TimeSpan ScanInterval = TimeSpan.FromMinutes(5);
private readonly IServiceProvider _services;
private readonly ClinicalMetrics _metrics;
private readonly ILogger<SepsisBundleMonitorService> _logger;
public SepsisBundleMonitorService(
IServiceProvider services,
ClinicalMetrics metrics,
ILogger<SepsisBundleMonitorService> logger)
{
_services = services;
_metrics = metrics;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Sepsis bundle monitor started. ScanInterval={Interval}", ScanInterval);
while (!stoppingToken.IsCancellationRequested)
{
try
{
await ScanOverdueBundlesAsync(stoppingToken);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
_logger.LogError(ex, "Sepsis bundle monitor error — will retry on next scan cycle");
}
await Task.Delay(ScanInterval, stoppingToken);
}
}
internal async Task ScanOverdueBundlesAsync(CancellationToken ct)
{
using var scope = _services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
var overdue = await db.SepsisBundles
.Where(b => b.ComplianceStatus == SepsisBundleComplianceStatus.InProgress
&& b.DeadlineAt < DateTimeOffset.UtcNow)
.ToListAsync(ct);
if (overdue.Count == 0)
return;
foreach (var bundle in overdue)
{
bundle.ComplianceStatus = SepsisBundleComplianceStatus.NonCompliant;
_metrics.SepsisBundleComplianceTotal
.WithLabels("NON_COMPLIANT").Inc();
var incompleteCount = await db.SepsisBundleElements
.CountAsync(e => e.BundleId == bundle.Id
&& e.Status != SepsisBundleElementStatus.Completed, ct);
_logger.LogWarning(
"Sepsis bundle {BundleId} for encounter {EncounterId} marked NON_COMPLIANT — " +
"deadline {Deadline} passed with {Incomplete} incomplete elements",
bundle.Id, bundle.EncounterId, bundle.DeadlineAt, incompleteCount);
}
await db.SaveChangesAsync(ct);
_logger.LogInformation(
"Sepsis bundle monitor marked {Count} overdue bundles as NON_COMPLIANT", overdue.Count);
}
}