feat(health): 深度 tracing 补全 — health_data 45 处 + action_inbox 8 处
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

health_data_service: 每个公开函数覆盖 entry/success/error 三层
- 13 个函数全覆盖(vital_signs/lab_report/health_record)
- 16 info + 13 info success + 3 debug + 13 error = 45 处

action_inbox_service: 追加 debug 级别中间结果日志
This commit is contained in:
iven
2026-05-03 19:44:49 +08:00
parent 3ddd04b422
commit 8a53948934
2 changed files with 68 additions and 18 deletions

View File

@@ -886,10 +886,14 @@ pub async fn get_team_overview(
)
.all(db)
.await
.map_err(|e| HealthError::DbError(e.to_string()))?;
.map_err(|e| {
tracing::error!(tenant_id = %tenant_id, error = %e, "查询团队成员统计失败");
HealthError::DbError(e.to_string())
})?;
let total_pending: u64 = members.iter().map(|m| m.pending_count as u64).sum();
let total_completed: u64 = members.iter().map(|m| m.completed_count as u64).sum();
tracing::debug!(tenant_id = %tenant_id, member_count = members.len(), total_pending = total_pending, total_completed = total_completed, "团队概览成员统计");
let team_members: Vec<TeamMemberOverview> = members
.into_iter()
@@ -933,7 +937,10 @@ pub async fn get_team_overview(
)
.all(db)
.await
.map_err(|e| HealthError::DbError(e.to_string()))?;
.map_err(|e| {
tracing::error!(tenant_id = %tenant_id, error = %e, "查询风险分布失败");
HealthError::DbError(e.to_string())
})?;
let mut risk_distribution = RiskDistribution {
high: 0,

View File

@@ -424,6 +424,7 @@ pub async fn create_lab_report(
key_version: Set(Some(1)),
};
let m = active.insert(&state.db).await?;
tracing::info!(id = %m.id, tenant_id = %tenant_id, patient_id = %patient_id, report_type = %m.report_type, "化验报告创建成功");
let event = DomainEvent::new(
crate::event::LAB_REPORT_UPLOADED,
@@ -467,6 +468,7 @@ pub async fn update_lab_report(
req: UpdateLabReportReq,
expected_version: i32,
) -> HealthResult<LabReportResp> {
tracing::info!(tenant_id = %tenant_id, report_id = %report_id, patient_id = %patient_id, expected_version, "更新化验报告");
let model = lab_report::Entity::find()
.filter(lab_report::Column::Id.eq(report_id))
.filter(lab_report::Column::PatientId.eq(patient_id))
@@ -474,9 +476,14 @@ pub async fn update_lab_report(
.filter(lab_report::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::LabReportNotFound)?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
.ok_or_else(|| {
tracing::error!(report_id = %report_id, tenant_id = %tenant_id, "更新化验报告失败:报告不存在");
HealthError::LabReportNotFound
})?;
let next_ver = check_version(expected_version, model.version).map_err(|e| {
tracing::error!(report_id = %report_id, expected_version, db_version = model.version, "更新化验报告失败:版本冲突");
e
})?;
// 记录变更前的关键字段items 为加密值,记录 meta 信息)
let old_values = serde_json::json!({
@@ -511,6 +518,7 @@ pub async fn update_lab_report(
active.key_version = Set(Some(1));
let m = active.update(&state.db).await?;
tracing::info!(id = %m.id, tenant_id = %tenant_id, version = m.version, "化验报告更新成功");
// 变更后快照
let new_values = serde_json::json!({
@@ -557,16 +565,22 @@ pub async fn delete_lab_report(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<()> {
tracing::info!(tenant_id = %tenant_id, report_id = %report_id, expected_version, "删除化验报告");
let model = lab_report::Entity::find()
.filter(lab_report::Column::Id.eq(report_id))
.filter(lab_report::Column::TenantId.eq(tenant_id))
.filter(lab_report::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::LabReportNotFound)?;
.ok_or_else(|| {
tracing::error!(report_id = %report_id, tenant_id = %tenant_id, "删除化验报告失败:报告不存在");
HealthError::LabReportNotFound
})?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
let next_ver = check_version(expected_version, model.version).map_err(|e| {
tracing::error!(report_id = %report_id, expected_version, db_version = model.version, "删除化验报告失败:版本冲突");
e
})?;
let mut active: lab_report::ActiveModel = model.into();
active.deleted_at = Set(Some(Utc::now()));
@@ -574,6 +588,7 @@ pub async fn delete_lab_report(
active.updated_by = Set(operator_id);
active.version = Set(next_ver);
active.update(&state.db).await?;
tracing::info!(report_id = %report_id, tenant_id = %tenant_id, "化验报告删除成功");
audit_service::record(
AuditLog::new(tenant_id, operator_id, "lab_report.deleted", "lab_report")
@@ -593,6 +608,7 @@ pub async fn review_lab_report(
req: crate::dto::health_data_dto::ReviewLabReportReq,
expected_version: i32,
) -> HealthResult<LabReportResp> {
tracing::info!(tenant_id = %tenant_id, report_id = %report_id, reviewer_id = %reviewer_id, "审核化验报告");
let model = lab_report::Entity::find()
.filter(lab_report::Column::Id.eq(report_id))
.filter(lab_report::Column::PatientId.eq(patient_id))
@@ -600,10 +616,15 @@ pub async fn review_lab_report(
.filter(lab_report::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::LabReportNotFound)?;
.ok_or_else(|| {
tracing::error!(report_id = %report_id, tenant_id = %tenant_id, "审核化验报告失败:报告不存在");
HealthError::LabReportNotFound
})?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
let next_ver = check_version(expected_version, model.version).map_err(|e| {
tracing::error!(report_id = %report_id, expected_version, db_version = model.version, "审核化验报告失败:版本冲突");
e
})?;
validate_lab_report_status_transition(&model.status, "reviewed")?;
@@ -630,6 +651,7 @@ pub async fn review_lab_report(
active.key_version = Set(Some(1));
let m = active.update(&state.db).await?;
tracing::info!(id = %m.id, tenant_id = %tenant_id, old_status = %old_status, new_status = %m.status, "化验报告审核成功");
audit_service::record(
AuditLog::new(tenant_id, Some(reviewer_id), "lab_report.reviewed", "lab_report")
@@ -687,6 +709,7 @@ pub async fn list_health_records(
page: u64,
page_size: u64,
) -> HealthResult<PaginatedResponse<HealthRecordResp>> {
tracing::info!(tenant_id = %tenant_id, patient_id = %patient_id, page, page_size, "查询体检记录列表");
let limit = page_size.min(100);
let offset = page.saturating_sub(1) * limit;
@@ -696,6 +719,7 @@ pub async fn list_health_records(
.filter(health_record::Column::DeletedAt.is_null());
let total = query.clone().count(&state.db).await?;
tracing::debug!(total, "体检记录查询结果数量");
let models = query
.order_by_desc(health_record::Column::RecordDate)
.offset(offset)
@@ -721,6 +745,7 @@ pub async fn create_health_record(
operator_id: Option<Uuid>,
req: CreateHealthRecordReq,
) -> HealthResult<HealthRecordResp> {
tracing::info!(tenant_id = %tenant_id, patient_id = %patient_id, "创建体检记录");
// 校验患者存在
patient::Entity::find()
.filter(patient::Column::Id.eq(patient_id))
@@ -728,7 +753,10 @@ pub async fn create_health_record(
.filter(patient::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::PatientNotFound)?;
.ok_or_else(|| {
tracing::error!(patient_id = %patient_id, tenant_id = %tenant_id, "创建体检记录失败:患者不存在");
HealthError::PatientNotFound
})?;
let now = Utc::now();
let record_type = req.record_type.unwrap_or_else(|| "checkup".to_string());
@@ -752,6 +780,7 @@ pub async fn create_health_record(
version: Set(1),
};
let m = active.insert(&state.db).await?;
tracing::info!(id = %m.id, tenant_id = %tenant_id, patient_id = %patient_id, record_type = %m.record_type, "体检记录创建成功");
audit_service::record(
AuditLog::new(tenant_id, operator_id, "health_record.created", "health_record")
@@ -776,6 +805,7 @@ pub async fn update_health_record(
req: UpdateHealthRecordReq,
expected_version: i32,
) -> HealthResult<HealthRecordResp> {
tracing::info!(tenant_id = %tenant_id, record_id = %record_id, patient_id = %patient_id, expected_version, "更新体检记录");
let model = health_record::Entity::find()
.filter(health_record::Column::Id.eq(record_id))
.filter(health_record::Column::PatientId.eq(patient_id))
@@ -783,9 +813,14 @@ pub async fn update_health_record(
.filter(health_record::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::HealthRecordNotFound)?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
.ok_or_else(|| {
tracing::error!(record_id = %record_id, tenant_id = %tenant_id, "更新体检记录失败:记录不存在");
HealthError::HealthRecordNotFound
})?;
let next_ver = check_version(expected_version, model.version).map_err(|e| {
tracing::error!(record_id = %record_id, expected_version, db_version = model.version, "更新体检记录失败:版本冲突");
e
})?;
// 记录变更前的关键字段
let old_values = serde_json::json!({
@@ -807,6 +842,7 @@ pub async fn update_health_record(
active.version = Set(next_ver);
let m = active.update(&state.db).await?;
tracing::info!(id = %m.id, tenant_id = %tenant_id, version = m.version, "体检记录更新成功");
// 变更后快照
let new_values = serde_json::json!({
@@ -838,16 +874,22 @@ pub async fn delete_health_record(
operator_id: Option<Uuid>,
expected_version: i32,
) -> HealthResult<()> {
tracing::info!(tenant_id = %tenant_id, record_id = %record_id, expected_version, "删除体检记录");
let model = health_record::Entity::find()
.filter(health_record::Column::Id.eq(record_id))
.filter(health_record::Column::TenantId.eq(tenant_id))
.filter(health_record::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or(HealthError::HealthRecordNotFound)?;
.ok_or_else(|| {
tracing::error!(record_id = %record_id, tenant_id = %tenant_id, "删除体检记录失败:记录不存在");
HealthError::HealthRecordNotFound
})?;
let next_ver = check_version(expected_version, model.version)
.map_err(|_| HealthError::VersionMismatch)?;
let next_ver = check_version(expected_version, model.version).map_err(|e| {
tracing::error!(record_id = %record_id, expected_version, db_version = model.version, "删除体检记录失败:版本冲突");
e
})?;
let mut active: health_record::ActiveModel = model.into();
active.deleted_at = Set(Some(Utc::now()));
@@ -855,6 +897,7 @@ pub async fn delete_health_record(
active.updated_by = Set(operator_id);
active.version = Set(next_ver);
active.update(&state.db).await?;
tracing::info!(record_id = %record_id, tenant_id = %tenant_id, "体检记录删除成功");
audit_service::record(
AuditLog::new(tenant_id, operator_id, "health_record.deleted", "health_record")