Files
hms/crates/erp-server/migration/src/m20260512_000142_seed_copilot_rules.rs
iven 95db4fe9ff feat(db): 15 条 Copilot 内置规则种子数据
覆盖 5 大类: 体征异常(4) + 化验异常(4) + 依从性(2) + 透析质量(3) + 综合(2)
系统级规则(tenant_id=nil)适用于所有机构
2026-05-12 12:18:40 +08:00

215 lines
7.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 15 条 Copilot 内置规则种子数据
//!
//! 覆盖 spec §3.1 的 5 大类:体征异常(4)、化验异常(4)、依从性(2)、透析质量(3)、综合(2)
//! 所有规则 tenant_id = nil系统级规则适用于所有机构
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";
// 15 条内置 Copilot 规则 (使用固定 UUID)
// (id_suffix, name, category, condition_expr, score, severity, suggestion, sort_order)
let rules: &[(i32, &str, &str, &str, i16, &str, &str, i32)] = &[
// 体征异常
(
1,
"血压持续偏高",
"vital_signs",
r#"{"and":[{"=": [{"var":"vital_signs.systolic_bp_morning.count_gte_140"}, 3]}]}"#,
2,
"warning",
"建议增加血压监测频率并评估降压方案",
1,
),
(
2,
"舒张压持续偏高",
"vital_signs",
r#"{"and":[{"=": [{"var":"vital_signs.diastolic_bp_morning.count_gte_90"}, 3]}]}"#,
1,
"info",
"持续舒张压偏高,建议关注并记录血压变化",
2,
),
(
3,
"体重周增幅过大",
"vital_signs",
r#"{">": [{"var":"vital_signs.weight.weekly_change_kg"}, 2]}"#,
2,
"warning",
"体重周增幅超过2kg建议评估水钠潴留情况",
3,
),
(
4,
"心动过速",
"vital_signs",
r#"{">": [{"var":"vital_signs.heart_rate.latest"}, 100]}"#,
1,
"info",
"心率超过100次/分,建议进一步评估原因",
4,
),
// 化验异常
(
5,
"eGFR下降",
"lab",
r#"{"<": [{"var":"lab_reports.egfr.latest"}, 60]}"#,
3,
"warning",
"eGFR<60提示肾功能受损建议调整透析方案",
5,
),
(
6,
"高钾血症风险",
"lab",
r#"{">": [{"var":"lab_reports.potassium.latest"}, 5.5]}"#,
4,
"critical",
"立即通知主治医生,评估紧急透析需求",
6,
),
(
7,
"肌酐快速上升",
"lab",
r#"{">": [{"var":"lab_reports.creatinine.change_pct"}, 20]}"#,
3,
"warning",
"肌酐环比增幅超过20%,建议评估急性肾损伤可能",
7,
),
(
8,
"血磷偏高",
"lab",
r#"{">": [{"var":"lab_reports.phosphorus.latest"}, 1.5]}"#,
2,
"warning",
"血磷>1.5mmol/L建议调整磷结合剂用量",
8,
),
// 依从性
(
9,
"随访失约过多",
"compliance",
r#"{">": [{"var":"follow_up.missed_count"}, 2]}"#,
1,
"info",
"近期随访失约超过2次建议主动联系患者",
9,
),
(
10,
"药物依从性不足",
"compliance",
r#"{"<": [{"var":"medication.adherence_rate"}, 80]}"#,
2,
"warning",
"药物依从性低于80%,建议加强用药教育",
10,
),
// 透析质量
(
11,
"Kt/V不达标",
"dialysis",
r#"{"<": [{"var":"dialysis.kt_v.latest"}, 1.2]}"#,
2,
"warning",
"Kt/V<1.2,建议评估透析充分性并调整透析参数",
11,
),
(
12,
"透析间期体重增长过多",
"dialysis",
r#"{">": [{"var":"dialysis.interdialytic_weight_gain_pct"}, 5]}"#,
3,
"warning",
"透析间期体重增长超过5%,建议加强液体管理教育",
12,
),
(
13,
"透析前收缩压过高",
"dialysis",
r#"{">": [{"var":"dialysis.pre_systolic.latest"}, 180]}"#,
3,
"warning",
"透析前收缩压>180mmHg建议评估降压方案",
13,
),
// 综合规则
(
14,
"肾功能恶化伴高钾",
"composite",
r#"{"and":[{"<": [{"var":"lab_reports.egfr.latest"}, 60]},{">": [{"var":"lab_reports.potassium.latest"}, 5.5]}]}"#,
5,
"critical",
"eGFR下降且高钾血症建议紧急评估并考虑紧急透析",
14,
),
(
15,
"血压急剧升高伴肾功能恶化",
"composite",
r#"{"and":[{">": [{"var":"vital_signs.systolic_bp_morning.latest"}, 160]},{">": [{"var":"lab_reports.creatinine.change_pct"}, 20]}]}"#,
4,
"critical",
"血压急剧升高且肌酐快速上升,建议紧急评估并调整治疗方案",
15,
),
];
for &(idx, name, category, cond, score, severity, suggestion, sort) in rules {
// 生成确定性 UUID: copilot-rule-XXXX 前缀
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 tenant_id = '00000000-0000-0000-0000-000000000000'",
[],
))
.await?;
Ok(())
}
}