fix(health): DTO 输入校验补全 + handler .validate() 调用
- daily_monitoring_dto: Create/Update 添加 Validate derive + 血压/体重/血糖/入液量范围校验 - health_data_dto: LabReport/HealthRecord Create/Update/Review 添加 Validate derive - consultation_dto: CreateSessionReq/CreateMessageReq 添加 Validate + content length - article_dto: title max=500→200 匹配 DB VARCHAR(200) - health_data_handler: 7 个 create/update handler 添加 .validate() 调用 - consultation_handler: create_session/create_message 添加 .validate() 调用 - daily_monitoring_handler: create/update 添加 .validate() 调用
This commit is contained in:
@@ -75,7 +75,7 @@ pub struct ArticleListParams {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateArticleReq {
|
||||
#[validate(length(min = 1, max = 500, message = "文章标题长度须在1-500之间"))]
|
||||
#[validate(length(min = 1, max = 200, message = "文章标题长度须在1-200之间"))]
|
||||
pub title: String,
|
||||
#[validate(length(max = 2000, message = "摘要最多2000字"))]
|
||||
pub summary: Option<String>,
|
||||
@@ -113,7 +113,7 @@ impl CreateArticleReq {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UpdateArticleReq {
|
||||
#[validate(length(min = 1, max = 500, message = "文章标题长度须在1-500之间"))]
|
||||
#[validate(length(min = 1, max = 200, message = "文章标题长度须在1-200之间"))]
|
||||
pub title: Option<String>,
|
||||
#[validate(length(max = 2000, message = "摘要最多2000字"))]
|
||||
pub summary: Option<String>,
|
||||
|
||||
@@ -37,10 +37,12 @@ pub struct MessageResp {
|
||||
}
|
||||
|
||||
/// 发送消息请求体 — 不含 sender_id/sender_role,由服务端从 JWT 注入。
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateMessageReq {
|
||||
pub session_id: Uuid,
|
||||
#[validate(length(max = 50, message = "内容类型最多 50 字"))]
|
||||
pub content_type: Option<String>,
|
||||
#[validate(length(min = 1, max = 5000, message = "消息内容长度须在 1-5000 之间"))]
|
||||
pub content: String,
|
||||
/// 关联的媒体文件 ID(当 content_type 为 image/file/voice 时必填)
|
||||
pub media_id: Option<Uuid>,
|
||||
@@ -52,10 +54,11 @@ impl CreateMessageReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateSessionReq {
|
||||
pub patient_id: Uuid,
|
||||
pub doctor_id: Option<Uuid>,
|
||||
#[validate(length(max = 50, message = "咨询类型最多 50 字"))]
|
||||
pub consultation_type: Option<String>,
|
||||
}
|
||||
|
||||
@@ -70,11 +73,13 @@ pub struct SessionQuery {
|
||||
|
||||
/// 从咨询会话创建随访任务请求体 — 仅需填写随访类型和计划日期,
|
||||
/// patient_id / source_type / source_id 由服务端自动填充。
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateFollowUpFromConsultationReq {
|
||||
#[validate(length(min = 1, max = 50, message = "随访类型长度须在 1-50 之间"))]
|
||||
pub follow_up_type: String,
|
||||
pub planned_date: chrono::NaiveDate,
|
||||
pub assigned_to: Option<Uuid>,
|
||||
#[validate(length(max = 2000, message = "内容模板最多 2000 字"))]
|
||||
pub content_template: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use erp_core::sanitize::sanitize_option;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
type Decimal = f64;
|
||||
|
||||
@@ -10,18 +11,27 @@ type Decimal = f64;
|
||||
// 日常监测
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateDailyMonitoringReq {
|
||||
pub patient_id: Uuid,
|
||||
pub record_date: NaiveDate,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub morning_bp_systolic: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub morning_bp_diastolic: Option<i32>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub evening_bp_systolic: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub evening_bp_diastolic: Option<i32>,
|
||||
#[validate(range(min = 0.5, max = 500.0, message = "体重范围 0.5-500 kg"))]
|
||||
pub weight: Option<Decimal>,
|
||||
#[validate(range(min = 0.5, max = 33.3, message = "血糖范围 0.5-33.3 mmol/L"))]
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
#[validate(range(min = 0, max = 10000, message = "入液量范围 0-10000 ml"))]
|
||||
pub fluid_intake: Option<i32>,
|
||||
#[validate(range(min = 0, max = 10000, message = "尿量范围 0-10000 ml"))]
|
||||
pub urine_output: Option<i32>,
|
||||
#[validate(length(max = 2000, message = "备注最多 2000 字"))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
@@ -32,17 +42,26 @@ impl CreateDailyMonitoringReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UpdateDailyMonitoringReq {
|
||||
pub record_date: Option<NaiveDate>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub morning_bp_systolic: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub morning_bp_diastolic: Option<i32>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub evening_bp_systolic: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub evening_bp_diastolic: Option<i32>,
|
||||
#[validate(range(min = 0.5, max = 500.0, message = "体重范围 0.5-500 kg"))]
|
||||
pub weight: Option<Decimal>,
|
||||
#[validate(range(min = 0.5, max = 33.3, message = "血糖范围 0.5-33.3 mmol/L"))]
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
#[validate(range(min = 0, max = 10000, message = "入液量范围 0-10000 ml"))]
|
||||
pub fluid_intake: Option<i32>,
|
||||
#[validate(range(min = 0, max = 10000, message = "尿量范围 0-10000 ml"))]
|
||||
pub urine_output: Option<i32>,
|
||||
#[validate(length(max = 2000, message = "备注最多 2000 字"))]
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ use erp_core::sanitize::sanitize_option;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
/// 用 f64 表示 Decimal 值以满足 utoipa ToSchema 要求。
|
||||
/// 对于健康数值(血压 60-200mmHg、血糖 3.9-11.1mmol/L、体重 30-300kg),
|
||||
@@ -10,23 +11,37 @@ use uuid::Uuid;
|
||||
/// 数据库层仍使用 SeaORM Decimal 类型,转换仅在 DTO 边界进行。
|
||||
type Decimal = f64;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateVitalSignsReq {
|
||||
pub record_date: NaiveDate,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub systolic_bp_morning: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub diastolic_bp_morning: Option<i32>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub systolic_bp_evening: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub diastolic_bp_evening: Option<i32>,
|
||||
#[validate(range(min = 20, max = 250, message = "心率范围 20-250 bpm"))]
|
||||
pub heart_rate: Option<i32>,
|
||||
#[validate(range(min = 0.5, max = 500.0, message = "体重范围 0.5-500 kg"))]
|
||||
pub weight: Option<Decimal>,
|
||||
#[validate(range(min = 0.5, max = 33.3, message = "血糖范围 0.5-33.3 mmol/L"))]
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
#[validate(range(min = 30.0, max = 45.0, message = "体温范围 30-45 °C"))]
|
||||
pub body_temperature: Option<Decimal>,
|
||||
#[validate(range(min = 50, max = 100, message = "血氧范围 50-100%"))]
|
||||
pub spo2: Option<i32>,
|
||||
/// fasting / postprandial / random / ogtt
|
||||
#[validate(length(max = 50, message = "血糖类型最多 50 字"))]
|
||||
pub blood_sugar_type: Option<String>,
|
||||
#[validate(range(min = 0, max = 10000, message = "入液量范围 0-10000 ml"))]
|
||||
pub water_intake_ml: Option<i32>,
|
||||
#[validate(range(min = 0, max = 10000, message = "尿量范围 0-10000 ml"))]
|
||||
pub urine_output_ml: Option<i32>,
|
||||
#[validate(length(max = 2000, message = "备注最多 2000 字"))]
|
||||
pub notes: Option<String>,
|
||||
#[validate(length(max = 50, message = "来源最多 50 字"))]
|
||||
pub source: Option<String>,
|
||||
}
|
||||
|
||||
@@ -36,21 +51,34 @@ impl CreateVitalSignsReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UpdateVitalSignsReq {
|
||||
pub record_date: Option<NaiveDate>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub systolic_bp_morning: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub diastolic_bp_morning: Option<i32>,
|
||||
#[validate(range(min = 40, max = 300, message = "收缩压范围 40-300 mmHg"))]
|
||||
pub systolic_bp_evening: Option<i32>,
|
||||
#[validate(range(min = 20, max = 200, message = "舒张压范围 20-200 mmHg"))]
|
||||
pub diastolic_bp_evening: Option<i32>,
|
||||
#[validate(range(min = 20, max = 250, message = "心率范围 20-250 bpm"))]
|
||||
pub heart_rate: Option<i32>,
|
||||
#[validate(range(min = 0.5, max = 500.0, message = "体重范围 0.5-500 kg"))]
|
||||
pub weight: Option<Decimal>,
|
||||
#[validate(range(min = 0.5, max = 33.3, message = "血糖范围 0.5-33.3 mmol/L"))]
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
#[validate(range(min = 30.0, max = 45.0, message = "体温范围 30-45 °C"))]
|
||||
pub body_temperature: Option<Decimal>,
|
||||
#[validate(range(min = 50, max = 100, message = "血氧范围 50-100%"))]
|
||||
pub spo2: Option<i32>,
|
||||
#[validate(length(max = 50, message = "血糖类型最多 50 字"))]
|
||||
pub blood_sugar_type: Option<String>,
|
||||
#[validate(range(min = 0, max = 10000, message = "入液量范围 0-10000 ml"))]
|
||||
pub water_intake_ml: Option<i32>,
|
||||
#[validate(range(min = 0, max = 10000, message = "尿量范围 0-10000 ml"))]
|
||||
pub urine_output_ml: Option<i32>,
|
||||
#[validate(length(max = 2000, message = "备注最多 2000 字"))]
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
@@ -84,7 +112,7 @@ pub struct VitalSignsResp {
|
||||
pub version: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateLabReportReq {
|
||||
pub report_date: NaiveDate,
|
||||
pub report_type: String,
|
||||
@@ -102,7 +130,7 @@ impl CreateLabReportReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UpdateLabReportReq {
|
||||
pub report_date: Option<NaiveDate>,
|
||||
pub report_type: Option<String>,
|
||||
@@ -136,7 +164,7 @@ pub struct LabReportResp {
|
||||
pub version: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct CreateHealthRecordReq {
|
||||
pub record_type: Option<String>,
|
||||
pub record_date: NaiveDate,
|
||||
@@ -154,7 +182,7 @@ impl CreateHealthRecordReq {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, Validate)]
|
||||
pub struct UpdateHealthRecordReq {
|
||||
pub record_type: Option<String>,
|
||||
pub record_date: Option<NaiveDate>,
|
||||
@@ -264,7 +292,7 @@ pub struct MiniTodayResp {
|
||||
pub weight: Option<IndicatorSummary>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, ToSchema)]
|
||||
#[derive(Debug, Clone, serde::Deserialize, ToSchema, Validate)]
|
||||
pub struct ReviewLabReportReq {
|
||||
pub doctor_notes: Option<String>,
|
||||
pub items: Option<serde_json::Value>,
|
||||
|
||||
@@ -25,7 +25,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.articles.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
// 非管理权限用户只能查看已发布文章,防止草稿泄露
|
||||
let status =
|
||||
if require_any_permission(&ctx, &["health.articles.manage", "health.articles.review"])
|
||||
@@ -58,7 +58,7 @@ pub async fn list_public_articles(
|
||||
.tenant_id
|
||||
.ok_or_else(|| AppError::Validation("tenant_id is required".into()))?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result = article_service::list_articles(
|
||||
&state,
|
||||
tenant_id,
|
||||
@@ -307,7 +307,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.articles.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result =
|
||||
article_service::list_revisions(&state, ctx.tenant_id, id, page, page_size).await?;
|
||||
Ok(Json(ApiResponse::ok(result)))
|
||||
|
||||
@@ -68,6 +68,8 @@ where
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
require_permission(&ctx, "health.consultation.manage")?;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
let result =
|
||||
consultation_service::create_session(&state, ctx.tenant_id, Some(ctx.user_id), req).await?;
|
||||
Ok(Json(ApiResponse::ok(result)))
|
||||
@@ -84,7 +86,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.consultation.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result = consultation_service::list_sessions(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -124,7 +126,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.consultation.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result = consultation_service::list_messages(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -209,6 +211,9 @@ where
|
||||
content: req.content,
|
||||
media_id: None,
|
||||
};
|
||||
msg_req
|
||||
.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
msg_req.sanitize();
|
||||
let result = consultation_service::create_message(
|
||||
&state,
|
||||
|
||||
@@ -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;
|
||||
@@ -38,7 +39,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.daily-monitoring.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result = daily_monitoring_service::list_daily_monitoring(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -76,6 +77,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.daily-monitoring.manage")?;
|
||||
let mut req = req;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
req.sanitize();
|
||||
let result = daily_monitoring_service::create_daily_monitoring(
|
||||
&state,
|
||||
@@ -99,6 +102,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.daily-monitoring.manage")?;
|
||||
let mut data = req.data;
|
||||
data.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
data.sanitize();
|
||||
let result = daily_monitoring_service::update_daily_monitoring(
|
||||
&state,
|
||||
|
||||
@@ -8,6 +8,8 @@ use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
use erp_core::types::{ApiResponse, PaginatedResponse, TenantContext};
|
||||
|
||||
use validator::Validate;
|
||||
|
||||
use crate::dto::DeleteWithVersion;
|
||||
use crate::dto::health_data_dto::*;
|
||||
use crate::service::health_data_service;
|
||||
@@ -58,7 +60,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result =
|
||||
health_data_service::list_vital_signs(&state, ctx.tenant_id, patient_id, page, page_size)
|
||||
.await?;
|
||||
@@ -77,6 +79,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut req = req;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
req.sanitize();
|
||||
let result = health_data_service::create_vital_signs(
|
||||
&state,
|
||||
@@ -101,6 +105,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut data = req.data;
|
||||
data.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
data.sanitize();
|
||||
let result = health_data_service::update_vital_signs(
|
||||
&state,
|
||||
@@ -153,7 +159,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result =
|
||||
health_data_service::list_lab_reports(&state, ctx.tenant_id, patient_id, page, page_size)
|
||||
.await?;
|
||||
@@ -172,6 +178,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut req = req;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
req.sanitize();
|
||||
let result = health_data_service::create_lab_report(
|
||||
&state,
|
||||
@@ -196,6 +204,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut data = req.data;
|
||||
data.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
data.sanitize();
|
||||
let result = health_data_service::update_lab_report(
|
||||
&state,
|
||||
@@ -244,6 +254,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut data = req.data;
|
||||
data.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
data.sanitize();
|
||||
let result = health_data_service::review_lab_report(
|
||||
&state,
|
||||
@@ -274,7 +286,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result = health_data_service::list_health_records(
|
||||
&state,
|
||||
ctx.tenant_id,
|
||||
@@ -298,6 +310,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut req = req;
|
||||
req.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
req.sanitize();
|
||||
let result = health_data_service::create_health_record(
|
||||
&state,
|
||||
@@ -322,6 +336,8 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.manage")?;
|
||||
let mut data = req.data;
|
||||
data.validate()
|
||||
.map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
data.sanitize();
|
||||
let result = health_data_service::update_health_record(
|
||||
&state,
|
||||
@@ -374,7 +390,7 @@ where
|
||||
{
|
||||
require_permission(&ctx, "health.health-data.list")?;
|
||||
let page = params.page.unwrap_or(1);
|
||||
let page_size = params.page_size.unwrap_or(20);
|
||||
let page_size = params.page_size.unwrap_or(20).min(100);
|
||||
let result =
|
||||
trend_service::list_trends(&state, ctx.tenant_id, patient_id, page, page_size).await?;
|
||||
Ok(Json(ApiResponse::ok(result)))
|
||||
|
||||
Reference in New Issue
Block a user