Files
hms/crates/erp-server/migration/src/m20260427_000082_seed_ai_prompts.rs
iven 6d5a711d2c
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
fix: 修复测试发现的 7 个问题 + 全 workspace clippy 清零
功能修复:
1. 患者创建空名称验证:后端添加 name.trim().is_empty() 检查
2. 仪表盘统计容错:单个查询失败返回零值而非 500
3. FHIR 路由修复:从 /fhir 移到 /api/v1/fhir 保持一致
4. 冻结模块后端中间件:新增 frozen_module_middleware 拦截冻结路径
5. 积分端点权限码:health.health-data.list → health.points.list
6. 角色权限迁移:护士补充 devices.list,运营补充 points.list/manage
7. 测试结果文档:R01-R05 角色测试 + T00/T10 结果归档

Clippy 全 workspace 清零(14→0 errors):
- erp-core: 修复 empty doc line、collapsible if、redundant closure 等 9 处
- erp-health: 修复 too_many_arguments、unused var、unnecessary parens 等 58 处
- erp-ai: 修复 dead_code、unused import 等 11 处
- erp-plugin: 修复 too_many_arguments、wildcard pattern 等 11 处
- erp-server-migration: 修复 enum_variant_names 5 处
- erp-auth/config/workflow/message: 各 1-3 处

工程改进:
- lint-staged 配置迁移到 .lintstagedrc.js(函数式避免文件列表传给 clippy)
- cargo fmt 统一格式化
2026-05-07 23:43:14 +08:00

86 lines
5.5 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.
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 result = db
.query_one(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
"SELECT id::text FROM tenant LIMIT 1".to_string(),
))
.await?;
let tid = match result {
Some(row) => row.try_get_by_index::<String>(0).unwrap_or_default(),
None => return Ok(()),
};
let sys = "00000000-0000-0000-0000-000000000000";
let mc = r#"{"model":"claude-sonnet-4-6","temperature":0.3,"max_tokens":2048}"#;
insert_prompt(db, &tid, sys, "lab_report_interpretation", "化验单解读", "analysis", mc,
"你是一名专业的医学检验解读助手。请根据提供的化验指标数据,为患者提供清晰、准确的解读。\n\n要求:\n1. 逐项分析每个指标的含义和是否在正常范围\n2. 对异常指标提供可能的原因说明(不作为诊断)\n3. 给出建议的后续行动\n4. 使用通俗易懂的语言\n5. 最后给出总体健康提示",
"以下是患者的化验报告数据:\n\n报告日期:{{report_date}}\n科室:{{department}}\n患者年龄段:{{age_group}},性别:{{sex}}\n\n检查项目:\n{{#each items}}\n- {{name}}{{value}} {{unit}}(参考范围:{{reference_range}}{{#if is_abnormal}}异常{{else}}正常{{/if}}\n{{/each}}\n\n请对以上化验结果进行详细解读。",
).await?;
insert_prompt(db, &tid, sys, "health_trend_analysis", "健康趋势分析", "analysis", mc,
"你是一名健康数据分析专家。请根据提供的生命体征趋势数据,分析患者的健康变化趋势。\n\n要求:\n1. 识别数据中的关键趋势\n2. 对异常趋势提出预警\n3. 结合各指标间的关联性进行综合分析\n4. 给出健康管理建议",
"以下是患者的生命体征趋势数据:\n\n患者年龄段:{{age_group}},性别:{{sex}}\n\n监测指标:\n{{#each metrics}}\n### {{name}}{{unit}}\n数据点:{{#each values}}{{this.[0]}}: {{this.[1]}}{{#unless @last}}, {{/unless}}{{/each}}\n{{/each}}\n\n请分析以上健康趋势数据。",
).await?;
insert_prompt(db, &tid, sys, "personalized_checkup_plan", "个性化体检方案", "planning", mc,
"你是一名健康管理顾问。请根据患者的健康状况信息,为其制定个性化的体检方案。\n\n要求:\n1. 基于患者年龄、性别、既往病史推荐检查项目\n2. 按优先级排序\n3. 给出建议的检查频率\n4. 说明每项检查的目的和意义",
"请为以下患者制定个性化体检方案:\n\n年龄段:{{age_group}}\n性别:{{sex}}\n慢性疾病:{{#each chronic_conditions}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n当前用药:{{#each medications}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n家族病史:{{#each family_history}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n\n请给出详细的体检方案推荐。",
).await?;
insert_prompt(db, &tid, sys, "report_summary_generation", "报告摘要生成", "summary", mc,
"你是一名医疗报告摘要撰写专家。请根据提供的健康报告内容,生成结构清晰的摘要。\n\n要求:\n1. 提取报告中的关键发现\n2. 标注异常项目及其严重程度\n3. 给出简明的结论\n4. 提供行动建议\n5. 控制在 500 字以内",
"请为以下健康报告生成摘要:\n\n报告日期:{{report_date}}\n科室:{{department}}\n患者年龄段:{{age_group}},性别:{{sex}}\n\n报告内容:\n{{#each sections}}\n## {{title}}\n发现:{{#each findings}}{{this}}{{#unless @last}}{{/unless}}{{/each}}\n{{#if abnormal_items.length}}\n异常项:{{#each abnormal_items}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n{{/if}}\n{{/each}}\n\n请生成结构化的报告摘要。",
).await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let db = manager.get_connection();
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
"DELETE FROM ai_prompt WHERE name IN ('lab_report_interpretation','health_trend_analysis','personalized_checkup_plan','report_summary_generation')".to_string(),
))
.await?;
Ok(())
}
}
fn esc(s: &str) -> String {
s.replace('\'', "''")
}
async fn insert_prompt(
db: &sea_orm_migration::SchemaManagerConnection<'_>,
tenant_id: &str,
sys: &str,
name: &str,
description: &str,
category: &str,
model_config: &str,
system_prompt: &str,
user_template: &str,
) -> Result<(), DbErr> {
db.execute(sea_orm::Statement::from_string(
sea_orm::DatabaseBackend::Postgres,
format!(
"INSERT INTO ai_prompt (id, tenant_id, name, description, system_prompt, user_prompt_template, model_config, version, is_active, category, tags, created_at, updated_at, created_by, updated_by, version_lock) \
VALUES (gen_random_uuid(), '{}', '{}', '{}', '{}', '{}', '{}', 1, true, '{}', NULL, NOW(), NOW(), '{}', '{}', 1) ON CONFLICT DO NOTHING",
tenant_id, esc(name), esc(description), esc(system_prompt), esc(user_template), esc(model_config), category, sys, sys
),
))
.await?;
Ok(())
}