核心功能: - 公告状态机(草稿/已发布/已撤销)支持发布、撤销和重新发布 - 发布者范围区分平台级和租户级公告 - 目标受众定向推送(全部租户/指定角色/指定用户) - 平台管理、租户管理和应用端查询API - 已读/未读管理和未读统计 技术实现: - CQRS+DDD架构,清晰的领域边界和事件驱动 - 查询性能优化:数据库端排序和限制,估算策略减少内存占用 - 并发控制:修复RowVersion配置(IsRowVersion→IsConcurrencyToken) - 完整的FluentValidation验证器和输入保护 测试验证: - 36个测试全部通过(27单元+9集成) - 性能测试达标(1000条数据<5秒) - 代码质量评级A(优秀) 文档: - 完整的ADR、API文档和迁移指南 - 交付报告和技术债务记录
53 lines
1.7 KiB
Markdown
53 lines
1.7 KiB
Markdown
# ADR 0001:公告状态机与多租户平台公告方案
|
||
|
||
> 最后更新日期:2025-12-20
|
||
|
||
## Context
|
||
|
||
公告模块需要支持草稿、发布、撤销等完整生命周期,且平台与租户公告必须在同一数据模型中统一管理。同时要支持并发更新与审计追踪,避免已发布公告被“悄然修改”引发合规风险。
|
||
|
||
## Decision
|
||
|
||
1. 使用 `Status` 枚举替代 `IsActive` 布尔值作为主状态字段(Draft / Published / Revoked)。
|
||
2. `Published` 状态不可变:已发布公告不允许编辑,需先撤销再重新发布。
|
||
3. 使用 `TenantId = 0` 表示平台公告,统一在 `tenant_announcements` 表中存储。
|
||
4. 使用 `RowVersion` 字段进行乐观并发控制。
|
||
|
||
```csharp
|
||
public enum AnnouncementStatus
|
||
{
|
||
Draft = 0,
|
||
Published = 1,
|
||
Revoked = 2
|
||
}
|
||
```
|
||
|
||
```mermaid
|
||
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`。
|