fix: 修复测试发现的 7 个问题 + 全 workspace clippy 清零
功能修复: 1. 患者创建空名称验证:后端添加 name.trim().is_empty() 检查 2. 仪表盘统计容错:单个查询失败返回零值而非 500 3. FHIR 路由修复:从 /fhir 移到 /api/v1/fhir 保持一致 4. 冻结模块后端中间件:新增 frozen_module_middleware 拦截冻结路径 5. 积分端点权限码:health.health-data.list → health.points.list 6. 角色权限迁移:护士补充 devices.list,运营补充 points.list/manage 7. 测试结果文档:R01-R05 角色测试 + T00/T10 结果归档 Clippy 全 workspace 清零(14→0 errors): - erp-core: 修复 empty doc line、collapsible if、redundant closure 等 9 处 - erp-health: 修复 too_many_arguments、unused var、unnecessary parens 等 58 处 - erp-ai: 修复 dead_code、unused import 等 11 处 - erp-plugin: 修复 too_many_arguments、wildcard pattern 等 11 处 - erp-server-migration: 修复 enum_variant_names 5 处 - erp-auth/config/workflow/message: 各 1-3 处 工程改进: - lint-staged 配置迁移到 .lintstagedrc.js(函数式避免文件列表传给 clippy) - cargo fmt 统一格式化
This commit is contained in:
@@ -20,9 +20,7 @@ pub struct BatchRequest {
|
||||
|
||||
/// 接收小程序批量埋点事件。
|
||||
/// 当前为日志记录模式 — 后续可接入 ClickHouse/PostgreSQL 分析表。
|
||||
pub async fn batch(
|
||||
Json(req): Json<BatchRequest>,
|
||||
) -> Json<ApiResponse<()>> {
|
||||
pub async fn batch(Json(req): Json<BatchRequest>) -> Json<ApiResponse<()>> {
|
||||
for evt in &req.events {
|
||||
tracing::info!(
|
||||
event = %evt.event,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use axum::extract::{FromRef, Path, State};
|
||||
use axum::Extension;
|
||||
use axum::Json;
|
||||
use sea_orm::{ConnectionTrait, Statement, DatabaseBackend};
|
||||
use serde_json::{json, Value};
|
||||
use axum::extract::{FromRef, Path, State};
|
||||
use sea_orm::{ConnectionTrait, DatabaseBackend, Statement};
|
||||
use serde_json::{Value, json};
|
||||
use uuid::Uuid;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
|
||||
@@ -56,10 +56,8 @@ pub async fn readiness_check(State(state): State<AppState>) -> Json<ReadyRespons
|
||||
.map(|m| m.name().to_string())
|
||||
.collect();
|
||||
|
||||
let (db_status, redis_status) = tokio::join!(
|
||||
check_database(&state.db),
|
||||
check_redis(&state.redis),
|
||||
);
|
||||
let (db_status, redis_status) =
|
||||
tokio::join!(check_database(&state.db), check_redis(&state.redis),);
|
||||
|
||||
let overall = if db_status.status == "ok" && redis_status.status == "ok" {
|
||||
"ok"
|
||||
@@ -81,10 +79,8 @@ pub async fn readiness_check(State(state): State<AppState>) -> Json<ReadyRespons
|
||||
async fn check_database(db: &sea_orm::DatabaseConnection) -> ComponentStatus {
|
||||
use sea_orm::ConnectionTrait;
|
||||
let start = std::time::Instant::now();
|
||||
let stmt = sea_orm::Statement::from_string(
|
||||
sea_orm::DatabaseBackend::Postgres,
|
||||
"SELECT 1".to_string(),
|
||||
);
|
||||
let stmt =
|
||||
sea_orm::Statement::from_string(sea_orm::DatabaseBackend::Postgres, "SELECT 1".to_string());
|
||||
match db.query_one(stmt).await {
|
||||
Ok(_) => ComponentStatus {
|
||||
status: "ok".to_string(),
|
||||
@@ -105,26 +101,21 @@ async fn check_database(db: &sea_orm::DatabaseConnection) -> ComponentStatus {
|
||||
async fn check_redis(client: &redis::Client) -> ComponentStatus {
|
||||
let start = std::time::Instant::now();
|
||||
match client.get_multiplexed_async_connection().await {
|
||||
Ok(mut conn) => {
|
||||
match redis::cmd("PING")
|
||||
.query_async::<String>(&mut conn)
|
||||
.await
|
||||
{
|
||||
Ok(_) => ComponentStatus {
|
||||
status: "ok".to_string(),
|
||||
Ok(mut conn) => match redis::cmd("PING").query_async::<String>(&mut conn).await {
|
||||
Ok(_) => ComponentStatus {
|
||||
status: "ok".to_string(),
|
||||
latency_ms: Some(start.elapsed().as_millis() as u64),
|
||||
error: None,
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!(error = %e, "Redis PING failed");
|
||||
ComponentStatus {
|
||||
status: "error".to_string(),
|
||||
latency_ms: Some(start.elapsed().as_millis() as u64),
|
||||
error: None,
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!(error = %e, "Redis PING failed");
|
||||
ComponentStatus {
|
||||
status: "error".to_string(),
|
||||
latency_ms: Some(start.elapsed().as_millis() as u64),
|
||||
error: Some("connection failed".to_string()),
|
||||
}
|
||||
error: Some("connection failed".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::error!(error = %e, "Redis connection failed");
|
||||
ComponentStatus {
|
||||
|
||||
@@ -2,7 +2,7 @@ use axum::response::Json;
|
||||
use serde_json::Value;
|
||||
use utoipa::OpenApi;
|
||||
|
||||
use crate::{ApiDoc, AuthApiDoc, ConfigApiDoc, WorkflowApiDoc, MessageApiDoc};
|
||||
use crate::{ApiDoc, AuthApiDoc, ConfigApiDoc, MessageApiDoc, WorkflowApiDoc};
|
||||
|
||||
/// GET /docs/openapi.json
|
||||
///
|
||||
|
||||
@@ -46,9 +46,9 @@ where
|
||||
// 确保上传目录存在
|
||||
let base_dir = std::path::Path::new(upload_dir);
|
||||
let tenant_dir = base_dir.join(ctx.tenant_id.to_string());
|
||||
tokio::fs::create_dir_all(&tenant_dir).await.map_err(|e| {
|
||||
AppError::Internal(format!("创建上传目录失败: {}", e))
|
||||
})?;
|
||||
tokio::fs::create_dir_all(&tenant_dir)
|
||||
.await
|
||||
.map_err(|e| AppError::Internal(format!("创建上传目录失败: {}", e)))?;
|
||||
|
||||
// 读取第一个 field 作为上传文件
|
||||
let field = multipart
|
||||
@@ -65,10 +65,7 @@ where
|
||||
// 验证文件类型
|
||||
validate_content_type(&content_type)?;
|
||||
|
||||
let original_name = field
|
||||
.name()
|
||||
.unwrap_or("file")
|
||||
.to_string();
|
||||
let original_name = field.name().unwrap_or("file").to_string();
|
||||
|
||||
let data = field
|
||||
.bytes()
|
||||
|
||||
Reference in New Issue
Block a user