docs: 5 份实施计划 — 性能/安全/事件/前端/可观测性
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

对应 5 份设计规格,共 75 个 Task:

1. 性能优化 (12 Task) — 批量INSERT/N+1内联name/合并COUNT/按需重绘/chunk拆分
2. 安全纵深防御 (8 Task) — RLS/行级数据范围/Redis session_key/审计哈希链
3. 事件驱动架构 (10 Task) — 11个缺失事件补发/LISTEN+NOTIFY/schema版本化
4. 前端工程化 (10 Task) — hook统一/组件拆分/Bundle优化
5. 可观测性运维 (10 Task) — 深度健康检查/Prometheus/OTel/生产Docker/告警
This commit is contained in:
iven
2026-04-27 08:00:50 +08:00
parent 215fb35e0e
commit b410fa9f78
5 changed files with 809 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
# 事件驱动架构增强实施计划
> 设计规格: `docs/superpowers/specs/2026-04-26-event-driven-architecture-design.md`
> 日期: 2026-04-26 | 状态: draft | 总周期: 2 周
---
## Phase 1: 高优先级事件补发Week 1
### Task 1: dialysis_service 添加 dialysis_record.created/reviewed 事件
**涉及文件**: `crates/erp-health/src/service/dialysis_service.rs`
**步骤**: `create_dialysis_record()` 成功后发布 `dialysis_record.created`data: patient_id, dialysis_type, status, dialysis_date, duration, ultrafiltration_volume。审核状态变更时发布 `dialysis_record.reviewed`data: patient_id, reviewer_id, complication_notes。payload 遵循统一信封schema_version: "v1")。发布失败仅 warn 不阻断业务。
**验收**: 创建/审核后 domain_events 表出现对应事件;`cargo test` 通过。
### Task 2: diagnosis_service 添加 diagnosis.created/updated 事件
**涉及文件**: `crates/erp-health/src/service/diagnosis_service.rs`
**步骤**: `create_diagnosis()` 后发布 `diagnosis.created`data: patient_id, icd_code, diagnosis_name, severity`update_diagnosis()` 后发布 `diagnosis.updated`,计算变更 diffchanged_fields[], old_values{}, new_values{})。
**验收**: diagnosis.updated 事件 data 含 changed_fields 差异;`cargo test` 通过。
### Task 3: consent_service 添加 consent.granted/revoked 事件
**涉及文件**: `crates/erp-health/src/service/consent_service.rs`
**步骤**: 签署时发布 `consent.granted`data: patient_id, consent_type, consent_scope, granted_by, expires_at。撤销时发布 `consent.revoked`data: patient_id, consent_type, revoked_by, reason
**验收**: 签署/撤销后 domain_events 表出现事件;`cargo test` 通过。
---
## Phase 2: 中低优先级事件 + Outbox 优化Week 2
### Task 4: points_service 添加 points.earned/exchanged 事件
**涉及文件**: `crates/erp-health/src/service/points_service.rs`
**步骤**: earn 成功后发布 `points.earned`data: patient_id, points, source_type, balance_after。exchange 成功后发布 `points.exchanged`data: patient_id, points, product_name, order_id, balance_after。确保在事务提交后发布。
**验收**: 积分变动后 domain_events 出现事件balance_after 正确反映余额。
### Task 5: article_service 添加 article.published/rejected 事件
**涉及文件**: `crates/erp-health/src/service/article_service.rs`
**步骤**: 审核通过发布 `article.published`data: title, author_id, category_id, tags[])。审核驳回发布 `article.rejected`data: title, reviewer_id, reason
**验收**: 审核操作后 domain_events 出现事件;`cargo test` 通过。
### Task 6: daily_monitoring_service 添加 daily_monitoring.created 事件
**涉及文件**: `crates/erp-health/src/service/daily_monitoring_service.rs`
**步骤**: 记录创建后发布 `daily_monitoring.created`data: patient_id, monitoring_date, monitoring_type, values{})。
**验收**: 创建记录后 domain_events 出现事件;`cargo test` 通过。
### Task 7: Outbox relay 从轮询改为 LISTEN/NOTIFY
**涉及文件**: `crates/erp-server/src/outbox.rs`, `crates/erp-core/src/events.rs`
**步骤**: `EventBus::publish()` 持久化后执行 `NOTIFY outbox_channel, '<event_id>'`。outbox relay 用 `sqlx::PgListener` 监听 + `tokio::select!`LISTEN 触发 + 30s 兜底轮询)。保留 `process_pending_events()` 不变仅改变触发方式。PgListener 添加断线自动重连。
**验收**: 事件延迟 < 100msDB 轮询频率从 5s 降为 30s 兜底;`cargo test --workspace` 通过。
---
## Phase 3: 事件 schema 版本化 + 清理Week 2
### Task 8: 事件 payload 添加 schema_version 字段
**涉及文件**: `crates/erp-core/src/events.rs`, `crates/erp-health/src/service/` 下所有发布事件的 service
**步骤**: 在 erp-core 创建 `build_event_payload()` 辅助函数,自动填充 schema_version/timestamp/metadata。逐个 service14 个模块)替换手动构建为调用辅助函数,统一信封格式。
**验收**: 所有事件 payload 含 schema_version 字段;`cargo test --workspace` 通过。
### Task 9: Outbox 表分区或定期清理策略
**涉及文件**: `migration/src/m000075_domain_events_cleanup.rs`(新增), `erp-server/src/tasks/events_cleanup.rs`(新增)
**步骤**: 迁移创建 `domain_events_archive` 表,添加 `cleanup_old_published_events()` SQL 函数(>90 天 published 事件迁移到归档表)。后台任务每日执行清理。归档表只读防篡改。
**验收**: 清理任务正确迁移 >90 天事件;`cargo test` 通过。
### Task 10: 消费者幂等性dedup key 检查)
**涉及文件**: `migration/src/m000076_processed_events.rs`(新增), `crates/erp-core/src/events.rs`
**步骤**: 迁移创建 `processed_events`event_id + consumer_id 联合主键 + processed_at。erp-core 添加 `is_processed()` / `mark_processed()` 辅助函数。消费者模式:收到事件 -> 查已处理 -> 跳过或执行 -> 插入记录。添加 7 天 TTL 清理任务。
**验收**: 重复消费同一事件时第二次被跳过;`cargo test --workspace` 通过。
---
## 执行原则
1. **每 Task 完成后立即提交** — 不积压
2. **Phase 1 优先** — P0 事件(透析/诊断)是核心医疗流程
3. **事件发布不阻断业务** — publish 失败仅 warnOutbox relay 兜底
4. **统一信封格式** — 使用 `build_event_payload` 保证一致性
5. **LISTEN/NOTIFY 保留兜底轮询** — 30s 轮询防 NOTIFY 丢失