feat(health+dialysis): 补全 8 组权限码 + 修复 N+1 查询 + 防御性编码
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

权限补全:
- 新增 14 个权限声明(危急值告警/阈值/随访模板/日常监测/知情同意/用药记录/药物提醒)
- 更新 8 个 handler 使用正确的专属权限码
- erp-dialysis 新增 health.dialysis.stats 权限

性能优化:
- article_service list_articles 标签加载从 N+1 改为批量查询
- follow_up_template_service 字段计数从 N+1 改为批量 GROUP BY

防御性编码:
- alert_engine/article/critical_alert 的 unwrap() 替换为 unwrap_or/expect
This commit is contained in:
iven
2026-04-30 10:22:14 +08:00
parent 931edc3025
commit 13f553590b
13 changed files with 219 additions and 36 deletions

View File

@@ -27,7 +27,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.critical-alert.list")?;
require_permission(&ctx, "health.critical-alerts.list")?;
let page = query.page.unwrap_or(1);
let page_size = query.page_size.unwrap_or(20);
@@ -54,7 +54,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.critical-alert.list")?;
require_permission(&ctx, "health.critical-alerts.list")?;
let alert = critical_alert_service::get_alert(&state, ctx.tenant_id, id).await?;
Ok(axum::Json(ApiResponse::ok(alert)))
}
@@ -74,7 +74,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.critical-alert.manage")?;
require_permission(&ctx, "health.critical-alerts.manage")?;
critical_alert_service::acknowledge_alert(
&state,
ctx.tenant_id,

View File

@@ -37,7 +37,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.list")?;
require_permission(&ctx, "health.critical-value-thresholds.list")?;
let list = critical_value_threshold_service::find_thresholds(&state.db, ctx.tenant_id).await?;
Ok(Json(ApiResponse::ok(list)))
}
@@ -51,7 +51,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.critical-value-thresholds.manage")?;
let result = critical_value_threshold_service::create_threshold(
&state.db,
ctx.tenant_id,
@@ -78,7 +78,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.critical-value-thresholds.manage")?;
let result = critical_value_threshold_service::update_threshold(
&state.db,
ctx.tenant_id,
@@ -104,7 +104,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.critical-value-thresholds.manage")?;
critical_value_threshold_service::delete_threshold(&state.db, ctx.tenant_id, id, Some(ctx.user_id))
.await?;
Ok(Json(ApiResponse::ok(())))

View File

@@ -36,7 +36,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.list")?;
require_permission(&ctx, "health.daily-monitoring.list")?;
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(20);
let result = daily_monitoring_service::list_daily_monitoring(
@@ -55,7 +55,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.list")?;
require_permission(&ctx, "health.daily-monitoring.list")?;
let result = daily_monitoring_service::get_daily_monitoring(
&state, ctx.tenant_id, record_id,
)
@@ -72,7 +72,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.daily-monitoring.manage")?;
let mut req = req;
req.sanitize();
let result = daily_monitoring_service::create_daily_monitoring(
@@ -92,7 +92,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.daily-monitoring.manage")?;
let mut data = req.data;
data.sanitize();
let result = daily_monitoring_service::update_daily_monitoring(
@@ -112,7 +112,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.daily-monitoring.manage")?;
daily_monitoring_service::delete_daily_monitoring(
&state, ctx.tenant_id, record_id, Some(ctx.user_id), req.version,
)

View File

@@ -37,7 +37,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.list")?;
require_permission(&ctx, "health.follow-up-templates.list")?;
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(20);
let result = follow_up_template_service::list_templates(
@@ -56,7 +56,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.list")?;
require_permission(&ctx, "health.follow-up-templates.list")?;
let result = follow_up_template_service::get_template(&state, ctx.tenant_id, id).await?;
Ok(Json(ApiResponse::ok(result)))
}
@@ -70,7 +70,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.manage")?;
require_permission(&ctx, "health.follow-up-templates.manage")?;
let mut req = req;
req.sanitize();
let result = follow_up_template_service::create_template(
@@ -90,7 +90,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.manage")?;
require_permission(&ctx, "health.follow-up-templates.manage")?;
let mut data = req.data;
data.sanitize();
let result = follow_up_template_service::update_template(
@@ -110,7 +110,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.follow-up.manage")?;
require_permission(&ctx, "health.follow-up-templates.manage")?;
follow_up_template_service::delete_template(
&state, ctx.tenant_id, id, Some(ctx.user_id), req.version,
)

View File

@@ -24,7 +24,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.list")?;
require_permission(&ctx, "health.medication-reminders.list")?;
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(20);
let result = medication_reminder_service::list_reminders(
@@ -42,7 +42,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.medication-reminders.manage")?;
req.sanitize();
let result = medication_reminder_service::create_reminder(
&state, ctx.tenant_id, Some(ctx.user_id), req.0,
@@ -67,7 +67,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.medication-reminders.manage")?;
let mut data = req.data;
data.sanitize();
let result = medication_reminder_service::update_reminder(
@@ -91,7 +91,7 @@ where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.health-data.manage")?;
require_permission(&ctx, "health.medication-reminders.manage")?;
medication_reminder_service::delete_reminder(
&state, ctx.tenant_id, id, Some(ctx.user_id), req.version,
).await?;