feat(ai): Copilot 评分引擎 + Handler + 路由 + 权限码

- scoring.rs: 混合评分 (calculate_risk) + RiskScore/MatchedRule 结构
- engine.rs: CopilotEngine 协调规则评估和评分
- risk_service.rs: 风险计算 + UPSERT 快照 + 规则加载
- insight_service.rs: 洞察 CRUD + 过期清理
- 3 个 Handler: insight/risk/rule,7 个 API 端点
- 5 个权限码: copilot.insights.list/manage, copilot.risk.view, copilot.rules.list/manage
- AiState 扩展 risk_service + insight_service
This commit is contained in:
iven
2026-05-12 12:14:16 +08:00
parent fe983ba4ae
commit 57f33dd726
15 changed files with 698 additions and 0 deletions

View File

@@ -69,6 +69,37 @@ impl ErpModule for AiModule {
description: "批准或拒绝 AI 建议".into(),
module: "ai".into(),
},
// Copilot 权限
PermissionDescriptor {
code: "copilot.insights.list".into(),
name: "查看 Copilot 洞察".into(),
description: "查看 Copilot 生成的患者洞察列表".into(),
module: "ai".into(),
},
PermissionDescriptor {
code: "copilot.insights.manage".into(),
name: "管理 Copilot 洞察".into(),
description: "处理/忽略 Copilot 洞察".into(),
module: "ai".into(),
},
PermissionDescriptor {
code: "copilot.risk.view".into(),
name: "查看风险评分".into(),
description: "查看 Copilot 计算的患者风险评分".into(),
module: "ai".into(),
},
PermissionDescriptor {
code: "copilot.rules.list".into(),
name: "查看 Copilot 规则".into(),
description: "查看 Copilot 规则引擎配置".into(),
module: "ai".into(),
},
PermissionDescriptor {
code: "copilot.rules.manage".into(),
name: "管理 Copilot 规则".into(),
description: "创建/编辑/删除 Copilot 规则".into(),
module: "ai".into(),
},
]
}
@@ -385,5 +416,34 @@ impl AiModule {
"/ai/cost/estimate",
axum::routing::get(crate::handler::cost_estimate),
)
// Copilot 路由
.route(
"/copilot/insights",
axum::routing::get(crate::handler::insight_handler::list_insights),
)
.route(
"/copilot/insights/{id}",
axum::routing::get(crate::handler::insight_handler::get_insight),
)
.route(
"/copilot/insights/{id}/dismiss",
axum::routing::post(crate::handler::insight_handler::dismiss_insight),
)
.route(
"/copilot/patients/{id}/risk",
axum::routing::get(crate::handler::risk_handler::get_patient_risk),
)
.route(
"/copilot/rules",
axum::routing::get(crate::handler::rule_handler::list_rules),
)
.route(
"/copilot/rules",
axum::routing::post(crate::handler::rule_handler::create_rule),
)
.route(
"/copilot/rules/{id}",
axum::routing::put(crate::handler::rule_handler::update_rule),
)
}
}