fix(health+plugin): 空标签名校验 + 出生日期校验 + metrics 错误映射 + 测试报告修正
- C1 已修复: CreateTagReq 添加 validate(length(min=1)) + handler 调 .validate() - C2 非BUG: 媒体库实际路径 /health/media-folders(非 /health/media/folders) - H6 已修复: create/update patient 添加 birth_date <= today 校验 - H7 已修复: 插件 metrics 移除手动 map_err,用 From trait 自动映射 - H1-H5 非BUG: 测试使用了错误的 API 路径(积分/随访/告警/设备) - M1-M2 非BUG: Pagination 已有 .min(100) 上限 + u64 不接受负数 - 测试报告更新: Go/No-Go 从 CONDITIONAL GO 升级为 GO Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ use axum::extract::{FromRef, Json, Path, Query, State};
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -73,6 +74,11 @@ where
|
||||
if req.name.len() > 255 {
|
||||
return Err(AppError::Validation("患者姓名长度不能超过255个字符".into()));
|
||||
}
|
||||
if let Some(ref bd) = req.birth_date
|
||||
&& *bd > chrono::Utc::now().date_naive()
|
||||
{
|
||||
return Err(AppError::Validation("出生日期不能是未来日期".into()));
|
||||
}
|
||||
let result =
|
||||
patient_service::create_patient(&state, ctx.tenant_id, Some(ctx.user_id), req).await?;
|
||||
Ok(Json(ApiResponse::ok(result)))
|
||||
@@ -120,6 +126,11 @@ where
|
||||
verification_status: req.verification_status,
|
||||
};
|
||||
update.sanitize();
|
||||
if let Some(ref bd) = update.birth_date
|
||||
&& *bd > chrono::Utc::now().date_naive()
|
||||
{
|
||||
return Err(AppError::Validation("出生日期不能是未来日期".into()));
|
||||
}
|
||||
let result = patient_service::update_patient(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -353,8 +364,9 @@ where
|
||||
Ok(Json(ApiResponse::ok(tags)))
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema, validator::Validate)]
|
||||
pub struct CreateTagReq {
|
||||
#[validate(length(min = 1, max = 255, message = "标签名称不能为空且不超过255个字符"))]
|
||||
pub name: String,
|
||||
pub color: Option<String>,
|
||||
pub description: Option<String>,
|
||||
@@ -370,6 +382,8 @@ where
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
require_permission(&ctx, "health.patient.manage")?;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
let result = patient_service::create_tag(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -384,8 +398,9 @@ where
|
||||
Ok(Json(ApiResponse::ok(result)))
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema)]
|
||||
#[derive(Debug, serde::Deserialize, utoipa::ToSchema, validator::Validate)]
|
||||
pub struct UpdateTagWithVersion {
|
||||
#[validate(length(min = 1, max = 255, message = "标签名称不能为空且不超过255个字符"))]
|
||||
pub name: Option<String>,
|
||||
pub color: Option<String>,
|
||||
pub description: Option<String>,
|
||||
|
||||
@@ -348,11 +348,7 @@ where
|
||||
// 通过 plugin_id 找到 manifest_id,再查询 metrics
|
||||
let manifest_id =
|
||||
crate::data_service::resolve_manifest_id(id, ctx.tenant_id, &state.db).await?;
|
||||
let metrics = state
|
||||
.engine
|
||||
.get_metrics(&manifest_id)
|
||||
.await
|
||||
.map_err(|e| AppError::Internal(e.to_string()))?;
|
||||
let metrics = state.engine.get_metrics(&manifest_id).await?;
|
||||
|
||||
let avg_ms = if metrics.total_invocations > 0 {
|
||||
metrics.total_response_ms / metrics.total_invocations as f64
|
||||
|
||||
Reference in New Issue
Block a user