fix: Trend alert matching uses fragile LIKE pattern

This commit is contained in:
voltsrage
2026-06-21 16:45:09 +08:00
parent 076e8364b2
commit 3eb937ef98
6 changed files with 1339 additions and 6 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace VigilCareClinicalAPI.Migrations
{
/// <inheritdoc />
public partial class AddAlertObservationCode : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "observation_code",
table: "clinical_alerts",
type: "character varying(50)",
maxLength: 50,
nullable: true);
migrationBuilder.Sql(@"
UPDATE clinical_alerts
SET observation_code = CASE
WHEN details LIKE '%HEART_RATE%' THEN 'HEART_RATE'
WHEN details LIKE '%RESP_RATE%' THEN 'RESP_RATE'
WHEN details LIKE '%SYSTOLIC_BP%' THEN 'SYSTOLIC_BP'
WHEN details LIKE '%TEMP_C%' THEN 'TEMP_C'
WHEN details LIKE '%SPO2%' THEN 'SPO2'
END
WHERE alert_type = 'RAPID_DETERIORATION'
AND observation_code IS NULL;
");
migrationBuilder.CreateIndex(
name: "IX_clinical_alerts_encounter_id_alert_type_observation_code",
table: "clinical_alerts",
columns: new[] { "encounter_id", "alert_type", "observation_code" },
filter: "status IN ('OPEN', 'ESCALATED')");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_clinical_alerts_encounter_id_alert_type_observation_code",
table: "clinical_alerts");
migrationBuilder.DropColumn(
name: "observation_code",
table: "clinical_alerts");
}
}
}
@@ -113,6 +113,11 @@ namespace VigilCareClinicalAPI.Migrations
.HasColumnType("uuid")
.HasColumnName("encounter_id");
b.Property<string>("ObservationCode")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("observation_code");
b.Property<Guid?>("ObservationId")
.HasColumnType("uuid")
.HasColumnName("observation_id");
@@ -154,6 +159,9 @@ namespace VigilCareClinicalAPI.Migrations
b.HasIndex("Severity", "TriggeredAt")
.HasFilter("status = 'OPEN'");
b.HasIndex("EncounterId", "AlertType", "ObservationCode")
.HasFilter("status IN ('OPEN', 'ESCALATED')");
b.ToTable("clinical_alerts", null, t =>
{
t.HasCheckConstraint("chk_clinical_alerts_alert_type", "alert_type IN ('SEPSIS_WARNING', 'CRITICAL_HEART_RATE', 'CRITICAL_TEMP_C', 'CRITICAL_POTASSIUM_MEQ_L', 'CRITICAL_SPO2', 'CRITICAL_RESP_RATE', 'CRITICAL_WBC_K_UL', 'CRITICAL_SYSTOLIC_BP', 'CRITICAL_DIASTOLIC_BP', 'CRITICAL_LACTATE_MMOL_L', 'CRITICAL_AVPU', 'CRITICAL_GLUCOSE_MG_DL', 'CRITICAL_PAO2_MMHG', 'CRITICAL_PLATELET_K_UL', 'CRITICAL_BILIRUBIN_MG_DL', 'CRITICAL_CREATININE_MG_DL', 'WARNING_HEART_RATE', 'WARNING_TEMP_C', 'WARNING_POTASSIUM_MEQ_L', 'WARNING_SPO2', 'WARNING_RESP_RATE', 'WARNING_WBC_K_UL', 'WARNING_SYSTOLIC_BP', 'WARNING_DIASTOLIC_BP', 'WARNING_LACTATE_MMOL_L', 'WARNING_GLUCOSE_MG_DL', 'WARNING_PAO2_MMHG', 'WARNING_PLATELET_K_UL', 'WARNING_BILIRUBIN_MG_DL', 'WARNING_CREATININE_MG_DL', 'NEWS2_WARNING', 'NEWS2_EMERGENCY', 'RAPID_DETERIORATION', 'QSOFA_WARNING', 'QSOFA_SCREEN', 'GCS_CRITICAL', 'GCS_WARNING', 'SOFA_SEPSIS', 'SOFA_WARNING')");