test(health): PII 加密集成测试 + 性能基准 + 编译修复
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

- 10 个集成测试: CRUD 加密流(8) + 多租户隔离(2)
- 3 个性能基准: encrypt avg 17μs, decrypt avg 14μs, 批量50条 877μs
- 8 个 key_manager 单元测试 + 4 个 masking 边界测试
- 迁移: 加宽 emergency_contact_phone/phone/license_number/result 列
- 修复: follow_up_service.create_record 返回密文改为解密返回
- 修复: consultation_service/patient_service HealthError::NotFound 引用
This commit is contained in:
iven
2026-04-26 13:10:53 +08:00
parent 17b423b9b8
commit ebc0f20e33
10 changed files with 1211 additions and 4 deletions

View File

@@ -71,6 +71,7 @@ mod m20260427_000068_add_doctor_profile_pii_fields;
mod m20260427_000069_add_dialysis_record_key_version;
mod m20260427_000070_add_lab_report_key_version;
mod m20260427_000071_add_diagnosis_key_version;
mod m20260427_000072_widen_encrypted_phone_columns;
pub struct Migrator;
@@ -149,6 +150,7 @@ impl MigratorTrait for Migrator {
Box::new(m20260427_000069_add_dialysis_record_key_version::Migration),
Box::new(m20260427_000070_add_lab_report_key_version::Migration),
Box::new(m20260427_000071_add_diagnosis_key_version::Migration),
Box::new(m20260427_000072_widen_encrypted_phone_columns::Migration),
]
}
}

View File

@@ -0,0 +1,68 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20260427_000072_widen_encrypted_phone_columns"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let conn = manager.get_connection();
// patient.emergency_contact_phone: varchar(20) → varchar(255),容纳 AES-256-GCM 密文
conn.execute_unprepared(
"ALTER TABLE patient ALTER COLUMN emergency_contact_phone TYPE varchar(255)",
)
.await?;
// patient_family_member.phone: varchar(20) → varchar(255)
conn.execute_unprepared(
"ALTER TABLE patient_family_member ALTER COLUMN phone TYPE varchar(255)",
)
.await?;
// doctor_profile.license_number: varchar(50) → varchar(255)
conn.execute_unprepared(
"ALTER TABLE doctor_profile ALTER COLUMN license_number TYPE varchar(255)",
)
.await?;
// follow_up_record.result: varchar(20) → varchar(255)
conn.execute_unprepared(
"ALTER TABLE follow_up_record ALTER COLUMN result TYPE varchar(255)",
)
.await?;
Ok(())
}
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
let conn = manager.get_connection();
conn.execute_unprepared(
"ALTER TABLE patient ALTER COLUMN emergency_contact_phone TYPE varchar(20)",
)
.await?;
conn.execute_unprepared(
"ALTER TABLE patient_family_member ALTER COLUMN phone TYPE varchar(20)",
)
.await?;
conn.execute_unprepared(
"ALTER TABLE doctor_profile ALTER COLUMN license_number TYPE varchar(50)",
)
.await?;
conn.execute_unprepared(
"ALTER TABLE follow_up_record ALTER COLUMN result TYPE varchar(20)",
)
.await?;
Ok(())
}
}