feat(health): patient_service 集成 PiiCrypto — 电话/过敏史/病史加密
- HealthState.crypto: HealthCrypto → PiiCrypto (erp-core) - create_patient: 加密 phone/allergy/medical_history + HMAC 索引 - update_patient: 同上,同步加密 - model_to_resp_decrypted: 解密所有 Tier 1 字段 - model_to_resp (列表): Tier 1 字段返回 None - list_patients 搜索: 新增 phone hash 精确搜索 - article handler: 适配新 list_articles 签名 - article 迁移: 添加 category_id 列 - error.rs: From<String> for HealthError - 集成测试: HealthCrypto → PiiCrypto::dev_default()
This commit is contained in:
@@ -212,14 +212,10 @@ async fn main() -> anyhow::Result<()> {
|
||||
std::process::exit(1);
|
||||
}
|
||||
if config.health.aes_key == "__MUST_SET_VIA_ENV__" || config.health.hmac_key == "__MUST_SET_VIA_ENV__" {
|
||||
tracing::error!(
|
||||
"健康数据加密密钥为默认占位值,拒绝启动。请设置环境变量 ERP__HEALTH__AES_KEY 和 ERP__HEALTH__HMAC_KEY(64 字符 hex 编码)"
|
||||
// 注: health 密钥已被统一 KEK (ERP__CRYPTO__KEK) 替代,此处仅保留兼容性检查
|
||||
tracing::warn!(
|
||||
"ERP__HEALTH__AES_KEY/HMAC_KEY 未设置(已迁移到 ERP__CRYPTO__KEK 统一密钥体系)"
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
if let Err(e) = erp_health::HealthCrypto::from_keys(&config.health.aes_key, &config.health.hmac_key) {
|
||||
tracing::error!("健康数据加密密钥无效: {}。密钥必须为 64 字符 hex 编码(32 字节)", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// Initialize tracing
|
||||
@@ -449,6 +445,21 @@ async fn main() -> anyhow::Result<()> {
|
||||
};
|
||||
|
||||
// Build shared state
|
||||
let pii_crypto = if config.crypto.kek == "__MUST_SET_VIA_ENV__" {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
tracing::warn!("⚠️ PII KEK 使用开发默认值,仅用于本地开发");
|
||||
erp_core::crypto::PiiCrypto::dev_default()
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
panic!("ERP__CRYPTO__KEK must be set in production. Use a 64-char hex string (32 bytes).");
|
||||
}
|
||||
} else {
|
||||
erp_core::crypto::PiiCrypto::from_kek_hex(&config.crypto.kek)
|
||||
.expect("PII KEK must be valid 64-char hex (32 bytes). Set ERP__CRYPTO__KEK")
|
||||
};
|
||||
|
||||
let state = AppState {
|
||||
db,
|
||||
config,
|
||||
@@ -462,6 +473,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
.time_to_idle(std::time::Duration::from_secs(300))
|
||||
.build(),
|
||||
ai_state,
|
||||
pii_crypto,
|
||||
};
|
||||
|
||||
// --- Build the router ---
|
||||
|
||||
Reference in New Issue
Block a user