feature: Trend Detection & Alert Suppression Windows

This commit is contained in:
voltsrage
2026-06-18 21:18:13 +08:00
parent e6f7989298
commit 3c54feb38a
31 changed files with 2751 additions and 18 deletions
@@ -8,5 +8,6 @@ public class AlertThreshold
public decimal? WarningLow { get; set; }
public decimal? WarningHigh { get; set; }
public decimal? CriticalHigh { get; set; }
public int? SuppressionWindowMinutes { get; set; }
public DateTimeOffset CreatedAt { get; set; }
}
@@ -26,7 +26,9 @@ public enum AlertType
WarningGlucoseMgDl,
News2Warning,
News2Emergency
News2Emergency,
RapidDeterioration,
}
public static class AlertTypeExtensions
@@ -57,6 +59,7 @@ public static class AlertTypeExtensions
AlertType.WarningGlucoseMgDl => "WARNING_GLUCOSE_MG_DL",
AlertType.News2Warning => "NEWS2_WARNING",
AlertType.News2Emergency => "NEWS2_EMERGENCY",
AlertType.RapidDeterioration => "RAPID_DETERIORATION",
_ => throw new ArgumentOutOfRangeException(nameof(t))
};
@@ -86,6 +89,7 @@ public static class AlertTypeExtensions
"WARNING_GLUCOSE_MG_DL" => AlertType.WarningGlucoseMgDl,
"NEWS2_WARNING" => AlertType.News2Warning,
"NEWS2_EMERGENCY" => AlertType.News2Emergency,
"RAPID_DETERIORATION" => AlertType.RapidDeterioration,
_ => throw new ArgumentOutOfRangeException(nameof(v), $"Unknown alert type: '{v}'")
};
@@ -122,4 +126,31 @@ public static class AlertTypeExtensions
_ => throw new ArgumentOutOfRangeException(
nameof(observationCode), $"No warning alert type for observation code '{observationCode}'")
};
public static bool IsSuppressible(this AlertType t) => t switch
{
AlertType.SepsisWarning or AlertType.News2Emergency => false,
AlertType.CriticalHeartRate or AlertType.CriticalTempC or AlertType.CriticalPotassiumMeqL
or AlertType.CriticalSpo2 or AlertType.CriticalRespRate or AlertType.CriticalWbcKUl
or AlertType.CriticalSystolicBp or AlertType.CriticalDiastolicBp
or AlertType.CriticalLactateMmolL or AlertType.CriticalAvpu
or AlertType.CriticalGlucoseMgDl => false,
AlertType.RapidDeterioration => false, // trajectory alerts are never suppressed
_ => true // all Warning* types and News2Warning
};
public static string? ObservationCodeForWarning(this AlertType t) => t switch
{
AlertType.WarningHeartRate => "HEART_RATE",
AlertType.WarningTempC => "TEMP_C",
AlertType.WarningPotassiumMeqL => "POTASSIUM_MEQ_L",
AlertType.WarningSpo2 => "SPO2",
AlertType.WarningRespRate => "RESP_RATE",
AlertType.WarningWbcKUl => "WBC_K_UL",
AlertType.WarningSystolicBp => "SYSTOLIC_BP",
AlertType.WarningDiastolicBp => "DIASTOLIC_BP",
AlertType.WarningLactateMmolL => "LACTATE_MMOL_L",
AlertType.WarningGlucoseMgDl => "GLUCOSE_MG_DL",
_ => null
};
}
@@ -0,0 +1,8 @@
public enum TrendOutcome
{
NotTrendCode,
InsufficientHistory,
Stable,
RapidDeterioration,
AlertAlreadyOpen
}