Files
hms/crates/erp-ai/src/config.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

96 lines
2.6 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProviderType {
Claude,
Openai,
Ollama,
Rules,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ProviderConfig {
pub provider_type: ProviderType,
pub api_key_env: Option<String>,
pub base_url: Option<String>,
pub default_model: String,
pub max_tokens: u32,
pub temperature: f32,
#[serde(default = "default_true")]
pub is_enabled: bool,
}
fn default_true() -> bool {
true
}
#[derive(Debug, Clone, Deserialize)]
pub struct AiModuleConfig {
pub default_provider: String,
pub cache_ttl_seconds: u64,
pub quota_check_enabled: bool,
pub rate_limit_patient_daily: u32,
pub providers: std::collections::HashMap<String, ProviderConfig>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn provider_type_serde_roundtrip() {
let pt = ProviderType::Claude;
let json = serde_json::to_string(&pt).unwrap();
assert_eq!(json, "\"claude\"");
let back: ProviderType = serde_json::from_str(&json).unwrap();
assert_eq!(back, pt);
}
#[test]
fn provider_type_all_variants() {
for pt in [
ProviderType::Claude,
ProviderType::Openai,
ProviderType::Ollama,
ProviderType::Rules,
] {
let json = serde_json::to_string(&pt).unwrap();
let back: ProviderType = serde_json::from_str(&json).unwrap();
assert_eq!(back, pt);
}
}
#[test]
fn parse_provider_config() {
let json = r#"{
"provider_type": "openai",
"api_key_env": "OPENAI_API_KEY",
"base_url": "https://api.openai.com",
"default_model": "gpt-4o",
"max_tokens": 2048,
"temperature": 0.3,
"is_enabled": true
}"#;
let config: ProviderConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.provider_type, ProviderType::Openai);
assert_eq!(config.default_model, "gpt-4o");
assert!(config.is_enabled);
}
#[test]
fn parse_ollama_config_no_api_key() {
let json = r#"{
"provider_type": "ollama",
"base_url": "http://localhost:11434",
"default_model": "qwen2.5:7b",
"max_tokens": 2048,
"temperature": 0.3
}"#;
let config: ProviderConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.provider_type, ProviderType::Ollama);
assert!(config.api_key_env.is_none());
assert!(config.is_enabled); // default
}
}