feature: Sepsis Early Warning Engine

This commit is contained in:
voltsrage
2026-06-17 01:05:15 +08:00
parent fde3d56484
commit ec780144c6
12 changed files with 1194 additions and 8 deletions
@@ -0,0 +1,38 @@
using StackExchange.Redis;
public static class SirsEvaluator
{
// The four SIRS codes defined by this project's simplified SIRS criteria.
// Observations for any other code are ignored by the sepsis engine entirely —
// they pass through to the outbox and Elasticsearch but do not affect SIRS state.
public static readonly IReadOnlySet<string> SirsCodes =
new HashSet<string> { "TEMP_C", "HEART_RATE", "RESP_RATE", "WBC_K_UL" };
// Returns true if the observation value meets the SIRS criterion for its code.
// These thresholds are clinical parameters, not configuration — changing them
// requires clinical review, not a config file edit. They live here as named constants.
public static bool MeetsCriterion(string observationCode, decimal value) =>
observationCode switch
{
// Fever (> 38.3 °C) or hypothermia (< 36.0 °C)
"TEMP_C" => value > 38.3m || value < 36.0m,
// Tachycardia
"HEART_RATE" => value > 90m,
// Tachypnea
"RESP_RATE" => value > 20m,
// Leukocytosis or leukopenia
"WBC_K_UL" => value > 12.0m || value < 4.0m,
_ => false
};
// Redis key for one SIRS criterion for one encounter.
public static string CriterionKey(Guid encounterId, string code) =>
$"sirs:{encounterId}:{code}";
// All four Redis keys for one encounter — used in MGET to count active criteria.
// The order is stable so the MGET result array always maps to the same codes.
public static RedisKey[] AllCriterionKeys(Guid encounterId) =>
SirsCodes
.Select(code => (RedisKey)CriterionKey(encounterId, code))
.ToArray();
}