fix(health): 审计修复 — alert 时序 + outbox 幂等性
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:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user