fix(health): 审计修复 — alert 时序 + outbox 幂等性
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

1. CRITICAL: check_vital_signs_alert 移至 insert 之后执行,
   防止数据未持久化就触发告警
2. CRITICAL: send_system 添加 business_id 幂等检查,
   防止 outbox relay 重放导致重复消息通知
3. 修复 consent_service unused_mut 警告
This commit is contained in:
iven
2026-04-26 03:54:45 +08:00
parent 4ab189283e
commit 5cb4e5e0ec
3 changed files with 31 additions and 3 deletions

View File

@@ -148,6 +148,9 @@ impl MessageService {
}
/// 系统发送消息(由事件处理器调用)。
///
/// 幂等保证:当 `business_id` 存在时,若同 tenant + recipient + business_id 的消息已存在,
/// 直接返回已有消息,避免 outbox relay 重放导致重复通知。
#[allow(clippy::too_many_arguments)]
pub async fn send_system(
tenant_id: Uuid,
@@ -160,6 +163,27 @@ impl MessageService {
db: &sea_orm::DatabaseConnection,
event_bus: &EventBus,
) -> MessageResult<MessageResp> {
// 幂等检查:防止 outbox relay 重放导致重复消息
if let Some(bid) = business_id {
let existing = message::Entity::find()
.filter(message::Column::TenantId.eq(tenant_id))
.filter(message::Column::RecipientId.eq(recipient_id))
.filter(message::Column::BusinessId.eq(bid))
.filter(message::Column::DeletedAt.is_null())
.one(db)
.await
.map_err(|e| MessageError::Validation(e.to_string()))?;
if let Some(m) = existing {
tracing::debug!(
message_id = %m.id,
business_id = %bid,
"消息已存在,跳过重复创建(幂等保护)"
);
return Ok(Self::model_to_resp(&m));
}
}
let id = Uuid::now_v7();
let now = Utc::now();
let system_user = Uuid::nil();