feat(health): 补全事件发布 — consent/points/article 6 个领域事件
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

- consent.granted/revoked: 知情同意授权/撤销
- points.earned/exchanged: 积分获得/兑换
- article.published/rejected: 文章审核发布/拒绝

所有事件通过 EventBus 发布,支持跨模块订阅和审计追溯。
This commit is contained in:
iven
2026-04-27 13:33:11 +08:00
parent a5646ddbb3
commit a36720cbbc
4 changed files with 59 additions and 0 deletions

View File

@@ -12,6 +12,14 @@ pub const APPOINTMENT_CREATED: &str = "appointment.created";
// 告警
pub const ALERT_TRIGGERED: &str = "alert.triggered";
// 知情同意
pub const CONSENT_GRANTED: &str = "consent.granted";
pub const CONSENT_REVOKED: &str = "consent.revoked";
// 文章
pub const ARTICLE_PUBLISHED: &str = "article.published";
pub const ARTICLE_REJECTED: &str = "article.rejected";
// 咨询
pub const CONSULTATION_OPENED: &str = "consultation.opened";
pub const CONSULTATION_CLOSED: &str = "consultation.closed";
@@ -39,6 +47,8 @@ pub const PATIENT_DECEASED: &str = "patient.deceased";
// 积分
pub const POINTS_EXPIRED: &str = "points.expired";
pub const POINTS_EARNED: &str = "points.earned";
pub const POINTS_EXCHANGED: &str = "points.exchanged";
/// 兼容旧签名 — 不做任何实际订阅(逻辑已迁移到 on_startup
pub fn register_handlers(_bus: &EventBus) {

View File

@@ -8,6 +8,7 @@ use uuid::Uuid;
use erp_core::audit::AuditLog;
use erp_core::audit_service;
use erp_core::error::check_version;
use erp_core::events::DomainEvent;
use erp_core::types::PaginatedResponse;
use crate::dto::article_dto::{ArticleListItem, ArticleResp, CreateArticleReq, ReviewArticleReq, UpdateArticleReq};
@@ -184,6 +185,13 @@ pub async fn approve_article(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::ARTICLE_PUBLISHED, tenant_id, serde_json::json!({
"article_id": m.id, "title": m.title, "category": m.category,
})),
&state.db,
).await;
let tags = load_article_tags(state, m.id).await?;
Ok(full_model_to_resp(m, tags))
}
@@ -220,6 +228,13 @@ pub async fn reject_article(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::ARTICLE_REJECTED, tenant_id, serde_json::json!({
"article_id": m.id, "title": m.title,
})),
&state.db,
).await;
let tags = load_article_tags(state, m.id).await?;
Ok(full_model_to_resp(m, tags))
}

View File

@@ -6,6 +6,7 @@ use uuid::Uuid;
use erp_core::audit::AuditLog;
use erp_core::audit_service;
use erp_core::error::check_version;
use erp_core::events::DomainEvent;
use erp_core::types::PaginatedResponse;
use crate::dto::consent_dto::*;
@@ -107,6 +108,14 @@ pub async fn grant_consent(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::CONSENT_GRANTED, tenant_id, serde_json::json!({
"consent_id": m.id, "patient_id": m.patient_id,
"consent_type": m.consent_type, "consent_scope": m.consent_scope,
})),
&state.db,
).await;
Ok(model_to_resp(m))
}
@@ -145,6 +154,14 @@ pub async fn revoke_consent(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::CONSENT_REVOKED, tenant_id, serde_json::json!({
"consent_id": m.id, "patient_id": m.patient_id,
"consent_type": m.consent_type,
})),
&state.db,
).await;
Ok(model_to_resp(m))
}

View File

@@ -9,6 +9,7 @@ use uuid::Uuid;
use erp_core::audit::AuditLog;
use erp_core::audit_service;
use erp_core::error::check_version;
use erp_core::events::DomainEvent;
use erp_core::types::PaginatedResponse;
use crate::dto::points_dto::*;
@@ -190,6 +191,14 @@ pub async fn earn_points(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::POINTS_EARNED, tenant_id, serde_json::json!({
"transaction_id": inserted.id, "account_id": inserted.account_id,
"amount": inserted.amount, "balance_after": inserted.balance_after,
})),
&state.db,
).await;
Ok(PointsTransactionResp {
id: inserted.id,
account_id: inserted.account_id,
@@ -923,6 +932,14 @@ pub async fn exchange_product(
&state.db,
).await;
state.event_bus.publish(
DomainEvent::new(crate::event::POINTS_EXCHANGED, tenant_id, serde_json::json!({
"order_id": inserted_order.id, "patient_id": inserted_order.patient_id,
"product_id": inserted_order.product_id, "points_cost": inserted_order.points_cost,
})),
&state.db,
).await;
Ok(PointsOrderResp {
id: inserted_order.id,
patient_id: inserted_order.patient_id,