Files
TakeoutSaaS.TenantApi/docs/adr/0001-announcement-status-state-machine.md
MSuMshk 857f776447 feat: 实现完整的多租户公告管理系统
核心功能:
- 公告状态机(草稿/已发布/已撤销)支持发布、撤销和重新发布
- 发布者范围区分平台级和租户级公告
- 目标受众定向推送(全部租户/指定角色/指定用户)
- 平台管理、租户管理和应用端查询API
- 已读/未读管理和未读统计

技术实现:
- CQRS+DDD架构,清晰的领域边界和事件驱动
- 查询性能优化:数据库端排序和限制,估算策略减少内存占用
- 并发控制:修复RowVersion配置(IsRowVersion→IsConcurrencyToken)
- 完整的FluentValidation验证器和输入保护

测试验证:
- 36个测试全部通过(27单元+9集成)
- 性能测试达标(1000条数据<5秒)
- 代码质量评级A(优秀)

文档:
- 完整的ADR、API文档和迁移指南
- 交付报告和技术债务记录
2025-12-20 19:57:09 +08:00

1.7 KiB
Raw Blame History

ADR 0001公告状态机与多租户平台公告方案

最后更新日期2025-12-20

Context

公告模块需要支持草稿、发布、撤销等完整生命周期,且平台与租户公告必须在同一数据模型中统一管理。同时要支持并发更新与审计追踪,避免已发布公告被“悄然修改”引发合规风险。

Decision

  1. 使用 Status 枚举替代 IsActive 布尔值作为主状态字段Draft / Published / Revoked
  2. Published 状态不可变:已发布公告不允许编辑,需先撤销再重新发布。
  3. 使用 TenantId = 0 表示平台公告,统一在 tenant_announcements 表中存储。
  4. 使用 RowVersion 字段进行乐观并发控制。
public enum AnnouncementStatus
{
    Draft = 0,
    Published = 1,
    Revoked = 2
}
stateDiagram-v2
  [*] --> Draft
  Draft --> Published: publish
  Published --> Revoked: revoke
  Revoked --> Published: republish

Consequences

  • 优点
    • 状态语义清晰,支持审计与合规追踪。
    • 平台与租户公告统一查询与筛选逻辑(TenantId IN (current, 0))。
    • RowVersion 能防止并发覆盖更新。
  • 代价
    • 需要迁移与兼容历史 IsActive 字段。
    • 已发布公告不可编辑,操作流程增加一步(撤销后重发)。

Alternatives Considered

  1. 继续使用 IsActive
    • 问题:无法表达撤销、草稿等状态,审计语义不足。
  2. 平台公告单独表
    • 问题:跨表查询复杂,重复实现过滤与排序。
  3. 使用悲观锁或数据库触发器
    • 问题:增加数据库负担,难以跨服务扩展。

该 ADR 对应迁移:20251220160000_AddTenantAnnouncementStatusAndPublisher