feature: Ward Gateway Service (Local-First Clinical Path)
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class EncounterReadService : IEncounterReadService
|
||||
{
|
||||
private readonly GatewayDbContext _db;
|
||||
|
||||
public EncounterReadService(GatewayDbContext db) => _db = db;
|
||||
|
||||
public async Task<List<WardEncounterSummary>> ListActiveAsync(string? department)
|
||||
{
|
||||
var q = _db.Encounters
|
||||
.Include(e => e.Patient)
|
||||
.Where(e => e.Status == EncounterStatus.Active);
|
||||
|
||||
if (!string.IsNullOrEmpty(department))
|
||||
{
|
||||
var dept = DepartmentExtensions.FromDbString(department);
|
||||
q = q.Where(e => e.Department == dept);
|
||||
}
|
||||
|
||||
var encounters = await q
|
||||
.OrderByDescending(e => e.AdmittedAt)
|
||||
.ToListAsync();
|
||||
|
||||
if (encounters.Count == 0)
|
||||
return [];
|
||||
|
||||
var encounterIds = encounters.Select(e => e.Id).ToList();
|
||||
var openAlertCounts = await _db.ClinicalAlerts
|
||||
.AsNoTracking()
|
||||
.Where(a => encounterIds.Contains(a.EncounterId) && a.Status == AlertStatus.Open)
|
||||
.GroupBy(a => a.EncounterId)
|
||||
.Select(g => new { EncounterId = g.Key, Count = g.Count() })
|
||||
.ToDictionaryAsync(x => x.EncounterId, x => x.Count);
|
||||
|
||||
return encounters.Select(e => new WardEncounterSummary(
|
||||
e.Id,
|
||||
e.Patient.Mrn,
|
||||
e.Patient.FirstName,
|
||||
e.Patient.LastName,
|
||||
e.Department,
|
||||
e.RoomBed,
|
||||
e.AttendingPhysician,
|
||||
e.AdmittedAt,
|
||||
openAlertCounts.GetValueOrDefault(e.Id),
|
||||
News2Score: null,
|
||||
QsofaScore: null,
|
||||
SepsisBundleStatus: null)).ToList();
|
||||
}
|
||||
|
||||
public async Task<EncounterDetail?> GetByIdAsync(Guid id)
|
||||
{
|
||||
var enc = await _db.Encounters
|
||||
.Include(e => e.Patient)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(e => e.Id == id);
|
||||
|
||||
if (enc is null) return null;
|
||||
|
||||
var observations = await _db.Observations
|
||||
.AsNoTracking()
|
||||
.Where(o => o.EncounterId == id)
|
||||
.OrderByDescending(o => o.RecordedAt)
|
||||
.Take(10)
|
||||
.ToListAsync();
|
||||
|
||||
var alerts = await _db.ClinicalAlerts
|
||||
.AsNoTracking()
|
||||
.Where(a => a.EncounterId == id && a.Status == AlertStatus.Open)
|
||||
.OrderByDescending(a => a.TriggeredAt)
|
||||
.ToListAsync();
|
||||
|
||||
return new EncounterDetail(
|
||||
enc.Id,
|
||||
enc.PatientId,
|
||||
enc.Patient.Mrn,
|
||||
enc.Patient.FirstName,
|
||||
enc.Patient.LastName,
|
||||
enc.Department,
|
||||
enc.Status,
|
||||
enc.RoomBed,
|
||||
enc.AttendingPhysician,
|
||||
enc.AdmittedAt,
|
||||
observations,
|
||||
alerts);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user