针对不同类型实体的可扩展审批流程的系统设计

ani*_*lca -3 c# workflow system-design

我正在寻找一种有效的方法来创建草稿并为我的域中的某些实体启动审批工作流程。用户应该轻松跟踪更改并批准或拒绝更改。您能否建议一个通用模型/方法/路线图来轻松提供这些功能?

假设我有这个模型:

public class CourierDistributionArea
{
    public City City { get; set; }
    public Courier Courier { get; set; }
}

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Courier
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

假设用户添加、更新或删除一些 CourierDistributionArea 实体。您将如何存储这些实体的新待批准版本?您将如何设计该系统以轻松添加要在此审批工作流程中使用的新型实体?您将如何向最终用户呈现变更集?

Cre*_*yke 5

有很多选项,这些选项取决于您的用户可能进行的更改、多个用户是否可以同时提供替代草稿以及您想要使用的存储(我无知地假设一些基于表的 RDBMS,如 SQL Server) 。

1. 草稿桌

在桌子旁边创建一个CarDraft桌子Car。目标表中的所有列都应出现在草稿表中,以及与草稿本身相关的元数据所需的任何其他列。当草稿获得批准后,将相关列更新插入到目标表中并删除草稿。

优点

  • 无需支持同一个表中同一实体的多个版本
  • 草稿不会以任何方式影响目标表上的 OLTP

缺点

  • 需要维护的附加表

2. 版本化实体

在目标表上创建VersionPublished列,并放松对使用原始主键强制执行单行的约束,而不是允许多行,但只允许某一列设置Published为 true 的行。

优点

  • 无需维护额外的表
  • 无需两次写入行(只需Published在单个事务中删除旧行并翻转新行上的位)

缺点

  • 可能更复杂的约束/应用程序验证
  • 连接Published列时的附加检查(容易忘记)

3. 改造审批

同样,根据用户可以执行的修改实体的操作,您可以将更改操作本身而不是新状态存储为草稿。例如,这可以存储在CarModifications表中,可能作为部分 JSON 对象,或者作为数字或行,每个数字代表目标表上的列的值更改。如果需要,可以将多行分组为单个OperationId。

优点

  • 目标表没有变化
  • 跨多个表的多个更改可以在单个操作 ID 上键入并应用于事务中

缺点

  • 建模更复杂
  • 更复杂的验证