feat(db): 8 条 Copilot 趋势/复合类告警规则种子数据
趋势类(4): 收缩压快速上升、肌酐连续上升、体重连续上升、血压趋势上升 复合类(4): eGFR+血钾双重危急、透析间期+血压、失约+依从性、Kt/V+血压
This commit is contained in:
@@ -144,6 +144,7 @@ mod m20260512_000139_create_copilot_insights;
|
||||
mod m20260512_000140_create_copilot_risk_snapshots;
|
||||
mod m20260512_000141_create_copilot_chat_logs;
|
||||
mod m20260512_000142_seed_copilot_rules;
|
||||
mod m20260512_000143_seed_copilot_alert_rules;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -295,6 +296,7 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260512_000140_create_copilot_risk_snapshots::Migration),
|
||||
Box::new(m20260512_000141_create_copilot_chat_logs::Migration),
|
||||
Box::new(m20260512_000142_seed_copilot_rules::Migration),
|
||||
Box::new(m20260512_000143_seed_copilot_alert_rules::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
//! 8 条 Copilot 趋势/复合类告警规则种子数据
|
||||
//!
|
||||
//! 覆盖 spec §3.2 告警分级场景:
|
||||
//! - 趋势类(4): 收缩压快速上升、肌酐连续上升、体重连续上升、血压趋势上升
|
||||
//! - 复合类(4): eGFR+血钾双重危急、透析间期+血压、失约+依从性、Kt/V+血压
|
||||
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let db = manager.get_connection();
|
||||
let nil_tenant = "00000000-0000-0000-0000-000000000000";
|
||||
|
||||
// 8 条趋势/复合类告警规则
|
||||
// (idx, name, category, condition_expr, score, severity, suggestion, sort_order)
|
||||
let rules: &[(i32, &str, &str, &str, i16, &str, &str, i32)] = &[
|
||||
// 趋势类规则
|
||||
(
|
||||
20,
|
||||
"收缩压快速上升",
|
||||
"vital_signs",
|
||||
r#"{"and":[{"=": [{"var":"vital_signs.systolic.trend_rising"}, true]},{">": [{"var":"vital_signs.systolic.change_pct"}, 15]}]}"#,
|
||||
3,
|
||||
"warning",
|
||||
"血压短时间内快速上升,需排除急性因素,建议加测并通知主治医生",
|
||||
20,
|
||||
),
|
||||
(
|
||||
21,
|
||||
"肌酐连续上升",
|
||||
"lab",
|
||||
r#"{"and":[{"=": [{"var":"lab_reports.creatinine.trend_rising"}, true]},{">": [{"var":"lab_reports.creatinine.change_pct"}, 10]}]}"#,
|
||||
3,
|
||||
"warning",
|
||||
"肌酐连续上升且环比增幅>10%,需排除急性肾损伤可能",
|
||||
21,
|
||||
),
|
||||
(
|
||||
22,
|
||||
"体重连续上升",
|
||||
"vital_signs",
|
||||
r#"{"=": [{"var":"vital_signs.weight.trend_rising"}, true]}"#,
|
||||
2,
|
||||
"info",
|
||||
"体重连续上升,需评估水钠潴留情况",
|
||||
22,
|
||||
),
|
||||
(
|
||||
23,
|
||||
"血压趋势整体上升",
|
||||
"vital_signs",
|
||||
r#"{"=": [{"var":"vital_signs.systolic.trend_rising"}, true]}"#,
|
||||
2,
|
||||
"info",
|
||||
"血压呈持续上升趋势,建议关注并调整降压方案",
|
||||
23,
|
||||
),
|
||||
// 复合类规则
|
||||
(
|
||||
24,
|
||||
"eGFR<45且血钾>5.0",
|
||||
"composite",
|
||||
r#"{"and":[{"<": [{"var":"lab_reports.egfr.latest"}, 45]},{">": [{"var":"lab_reports.potassium.latest"}, 5.0]}]}"#,
|
||||
5,
|
||||
"critical",
|
||||
"eGFR严重下降且血钾升高,需紧急评估并考虑紧急透析",
|
||||
24,
|
||||
),
|
||||
(
|
||||
25,
|
||||
"透析间期体重增长+血压极高",
|
||||
"composite",
|
||||
r#"{"and":[{">": [{"var":"dialysis.interdialytic_weight_gain_pct"}, 5]},{">": [{"var":"vital_signs.systolic_bp_morning.latest"}, 160]}]}"#,
|
||||
4,
|
||||
"critical",
|
||||
"透析间期体重增长过多且血压极高,需紧急评估液体管理和降压方案",
|
||||
25,
|
||||
),
|
||||
(
|
||||
26,
|
||||
"失约+药物依从性不足",
|
||||
"composite",
|
||||
r#"{"and":[{">": [{"var":"follow_up.missed_count"}, 2]},{"<": [{"var":"medication.adherence_rate"}, 70]}]}"#,
|
||||
3,
|
||||
"warning",
|
||||
"随访失约且药物依从性不足,建议加强患者教育和主动联系",
|
||||
26,
|
||||
),
|
||||
(
|
||||
27,
|
||||
"透析质量危急",
|
||||
"composite",
|
||||
r#"{"and":[{"<": [{"var":"dialysis.kt_v.latest"}, 1.0]},{">": [{"var":"vital_signs.systolic_bp_morning.latest"}, 180]}]}"#,
|
||||
5,
|
||||
"critical",
|
||||
"透析充分性严重不足且血压极高,需紧急评估透析方案",
|
||||
27,
|
||||
),
|
||||
];
|
||||
|
||||
for &(idx, name, category, cond, score, severity, suggestion, sort) in rules {
|
||||
let id = format!("c0000000-0000-0000-0000-{:012}", idx);
|
||||
let sql = format!(
|
||||
r#"INSERT INTO copilot_rules (id, tenant_id, name, category, condition_expr, score, severity, suggestion, enabled, sort_order, created_at, updated_at, version_lock)
|
||||
VALUES ('{}', '{}', $1, $2, $3::jsonb, $4, $5, $6, true, $7, NOW(), NOW(), 1)"#,
|
||||
id, nil_tenant
|
||||
);
|
||||
db.execute(sea_orm::Statement::from_sql_and_values(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
sql,
|
||||
[
|
||||
name.into(),
|
||||
category.into(),
|
||||
cond.into(),
|
||||
score.into(),
|
||||
severity.into(),
|
||||
suggestion.into(),
|
||||
sort.into(),
|
||||
],
|
||||
))
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let db = manager.get_connection();
|
||||
db.execute(sea_orm::Statement::from_sql_and_values(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
"DELETE FROM copilot_rules WHERE id LIKE 'c0000000-0000-0000-0000-0000000000%' AND sort_order >= 20",
|
||||
[],
|
||||
))
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user