fix:
No SOFA trend chart or organ-system timeline No GCS trend chart or component history No qSOFA history view
This commit is contained in:
@@ -34,4 +34,16 @@ public static class QsofaCalculator
|
||||
|
||||
public static int CountActiveCriteria(RedisValue[] values) =>
|
||||
values.Count(v => v.HasValue);
|
||||
|
||||
public static QsofaCriteriaState ParseCriteriaState(RedisValue[] values) =>
|
||||
new(
|
||||
ParseOptionalDecimal(values.ElementAtOrDefault(0)),
|
||||
ParseOptionalDecimal(values.ElementAtOrDefault(1)),
|
||||
ParseOptionalDecimal(values.ElementAtOrDefault(2)));
|
||||
|
||||
public static QsofaCriteriaState ParseCriteriaState(QsofaEvaluation evaluation) =>
|
||||
new(evaluation.RespRate, evaluation.SystolicBp, evaluation.Avpu);
|
||||
|
||||
private static decimal? ParseOptionalDecimal(RedisValue value) =>
|
||||
value.HasValue ? decimal.Parse(value.ToString()!) : null;
|
||||
}
|
||||
@@ -83,13 +83,64 @@ public class QsofaDetector
|
||||
var values = await cache.StringGetAsync(allKeys);
|
||||
var activeCount = QsofaCalculator.CountActiveCriteria(values);
|
||||
|
||||
var created = activeCount >= 2
|
||||
&& await TryCreateScreenAlertAsync(encounterId, patientId, activeCount, values, ct);
|
||||
|
||||
await PersistEvaluationIfChangedAsync(
|
||||
encounterId, patientId, activeCount, values, created, ct);
|
||||
|
||||
if (activeCount < 2)
|
||||
return QsofaResult.InsufficientCriteria(activeCount);
|
||||
|
||||
var created = await TryCreateScreenAlertAsync(encounterId, patientId, activeCount, values, ct);
|
||||
return created ? QsofaResult.AlertCreated : QsofaResult.AlertAlreadyOpen;
|
||||
}
|
||||
|
||||
private async Task PersistEvaluationIfChangedAsync(
|
||||
Guid encounterId,
|
||||
Guid patientId,
|
||||
int activeCount,
|
||||
RedisValue[] values,
|
||||
bool screenAlertFired,
|
||||
CancellationToken ct)
|
||||
{
|
||||
using var scope = _services.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
|
||||
var last = await db.QsofaEvaluations
|
||||
.AsNoTracking()
|
||||
.Where(e => e.EncounterId == encounterId)
|
||||
.OrderByDescending(e => e.EvaluatedAt)
|
||||
.ThenByDescending(e => e.Id)
|
||||
.Select(e => new { e.ActiveCriteria, e.ScreenAlertFired })
|
||||
.FirstOrDefaultAsync(ct);
|
||||
|
||||
if (last is not null
|
||||
&& last.ActiveCriteria == activeCount
|
||||
&& !screenAlertFired)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var criteria = QsofaCalculator.ParseCriteriaState(values);
|
||||
var evaluatedAt = DateTimeOffset.UtcNow;
|
||||
|
||||
db.QsofaEvaluations.Add(new QsofaEvaluation
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
EncounterId = encounterId,
|
||||
PatientId = patientId,
|
||||
ActiveCriteria = activeCount,
|
||||
RespRate = criteria.RespRate,
|
||||
SystolicBp = criteria.SystolicBp,
|
||||
Avpu = criteria.Avpu,
|
||||
ScreenAlertFired = screenAlertFired,
|
||||
EvaluatedAt = evaluatedAt,
|
||||
CreatedAt = evaluatedAt,
|
||||
});
|
||||
|
||||
await db.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
private async Task<bool> TryCreateScreenAlertAsync(
|
||||
Guid encounterId,
|
||||
Guid patientId,
|
||||
|
||||
Reference in New Issue
Block a user