feature: Explainable Alerts

This commit is contained in:
voltsrage
2026-06-25 00:25:31 +08:00
parent 279add1e45
commit 666d683d67
61 changed files with 9553 additions and 125 deletions
+27 -6
View File
@@ -21,7 +21,7 @@ public class AlertService : IAlertService
_audit = audit;
}
public async Task<PagedResult<ClinicalAlert>> ListByEncounterAsync(
public async Task<PagedResult<AlertResponse>> ListByEncounterAsync(
Guid encounterId, AlertStatus? status, int page, int pageSize)
{
var query = _db.ClinicalAlerts
@@ -38,10 +38,12 @@ public class AlertService : IAlertService
.Take(pageSize)
.ToListAsync();
return new PagedResult<ClinicalAlert>(alerts, page, pageSize, total);
return new PagedResult<AlertResponse>(
alerts.Select(AlertResponseMapper.ToResponse).ToList(),
page, pageSize, total);
}
public async Task<PagedResult<ClinicalAlert>> ListGlobalAsync(
public async Task<PagedResult<AlertResponse>> ListGlobalAsync(
AlertStatus? status, AlertSeverity? severity, Department? department, int page, int pageSize)
{
var query = _db.ClinicalAlerts
@@ -65,10 +67,12 @@ public class AlertService : IAlertService
.Take(pageSize)
.ToListAsync();
return new PagedResult<ClinicalAlert>(alerts, page, pageSize, total);
return new PagedResult<AlertResponse>(
alerts.Select(AlertResponseMapper.ToResponse).ToList(),
page, pageSize, total);
}
public async Task<ClinicalAlert> GetByIdAsync(Guid id)
public async Task<AlertResponse> GetByIdAsync(Guid id)
{
var alert = await _db.ClinicalAlerts
.AsNoTracking()
@@ -78,7 +82,7 @@ public class AlertService : IAlertService
if (alert is null)
throw new NotFoundException("Alert not found.", "ALERT_NOT_FOUND");
return alert;
return AlertResponseMapper.ToResponse(alert);
}
public async Task<ClinicalAlert> AcknowledgeAsync(Guid id, AcknowledgeAlertRequest req)
@@ -304,4 +308,21 @@ public class AlertService : IAlertService
var prefix = $"[{roleLabel}] Acknowledged by {displayName}.";
return string.IsNullOrWhiteSpace(note) ? prefix : $"{prefix} {note.Trim()}";
}
public static class AlertResponseMapper
{
public static AlertResponse ToResponse(ClinicalAlert alert) => new(
alert.Id,
alert.EncounterId,
alert.PatientId,
alert.AlertType,
alert.Severity,
alert.Details,
alert.Status,
alert.TriggeredAt,
alert.AcknowledgedAt,
alert.AcknowledgedBy,
alert.ResolvedAt,
alert.Explanation);
}
}
@@ -1,12 +1,12 @@
public interface IAlertService
{
Task<PagedResult<ClinicalAlert>> ListByEncounterAsync(
Task<PagedResult<AlertResponse>> ListByEncounterAsync(
Guid encounterId, AlertStatus? status, int page, int pageSize);
Task<PagedResult<ClinicalAlert>> ListGlobalAsync(
Task<PagedResult<AlertResponse>> ListGlobalAsync(
AlertStatus? status, AlertSeverity? severity, Department? department, int page, int pageSize);
Task<ClinicalAlert> GetByIdAsync(Guid id);
Task<AlertResponse> GetByIdAsync(Guid id);
Task<ClinicalAlert> AcknowledgeAsync(Guid id, AcknowledgeAlertRequest req);