Files

77 lines
2.9 KiB
C#

using Microsoft.EntityFrameworkCore;
public class LocalAlertService : ILocalAlertService
{
private readonly GatewayDbContext _db;
public LocalAlertService(GatewayDbContext db) => _db = db;
public async Task<LocalClinicalAlert> AcknowledgeAsync(
Guid id, AcknowledgeAlertRequest req, string clinicianId)
{
var alert = await _db.ClinicalAlerts.FindAsync(id)
?? throw new NotFoundException("Alert not found.", "ALERT_NOT_FOUND");
if (alert.Status is not (AlertStatus.Open or AlertStatus.Escalated))
throw new ConflictException("Alert cannot be acknowledged.", "ALERT_NOT_ACKNOWLEDGEABLE");
alert.Status = AlertStatus.Acknowledged;
alert.AcknowledgedAt = DateTimeOffset.UtcNow;
alert.AcknowledgedBy = clinicianId;
BufferedSyncWriter.Enqueue(_db, BufferedSyncItemType.Ack, new
{
clientRef = Guid.NewGuid(),
alert.ClientAlertId,
clinicianId,
acknowledgedAt = alert.AcknowledgedAt,
req.Note
}, $"ack:{alert.ClientAlertId}:{alert.AcknowledgedAt:o}", alert.EncounterId, alert.AcknowledgedAt!.Value);
await _db.SaveChangesAsync();
return alert;
}
public async Task<LocalClinicalAlert> ResolveAsync(Guid id)
{
var alert = await _db.ClinicalAlerts.FindAsync(id)
?? throw new NotFoundException("Alert not found.", "ALERT_NOT_FOUND");
if (alert.Status != AlertStatus.Acknowledged)
throw new ConflictException("Alert must be acknowledged first.", "ALERT_NOT_ACKNOWLEDGED");
alert.Status = AlertStatus.Resolved;
alert.ResolvedAt = DateTimeOffset.UtcNow;
BufferedSyncWriter.Enqueue(_db, BufferedSyncItemType.Resolve, new
{
clientRef = Guid.NewGuid(),
alert.ClientAlertId,
clinicianId = alert.AcknowledgedBy,
resolvedAt = alert.ResolvedAt,
note = (string?)null
}, $"resolve:{alert.ClientAlertId}", alert.EncounterId, alert.ResolvedAt!.Value);
await _db.SaveChangesAsync();
return alert;
}
public async Task<PagedResult<LocalClinicalAlert>> ListAsync(
Guid? encounterId, string? status, int page, int pageSize)
{
page = Math.Max(1, page);
pageSize = Math.Clamp(pageSize, 1, 100);
var q = _db.ClinicalAlerts.AsNoTracking().AsQueryable();
if (encounterId.HasValue) q = q.Where(a => a.EncounterId == encounterId);
if (!string.IsNullOrEmpty(status))
{
var parsedStatus = AlertStatusExtensions.FromDbString(status);
q = q.Where(a => a.Status == parsedStatus);
}
var total = await q.CountAsync();
var items = await q.OrderByDescending(a => a.TriggeredAt)
.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedResult<LocalClinicalAlert>(items, page, pageSize, total);
}
}