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 SirsCodes = new HashSet { "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(); }