快照 + 事件溯源

SNAPSHOT + Event sourcing

细节决定成败。我正在研究在现有的餐饮应用程序上实施事件源。我有一张可以关联到公司、公司部门或公司员工的发票。

设置

用例:

领域模型

Invoice
  -> invoice Id
  -> Status
  -> CompanyId 
  -> DeptId  
  -> EmployeeId 
  -> Balance

关系Table

| p_key | invoice_id | Reltn_Table | Reltn_id |
|-------|------------|-------------|----------|
| 1     | 12345      | Company     | 245242   |
| 2     | 67890      | Company     | 1241243  |
| 3     | 79166      | Dept        | 534214   |
| 4     | 792131     | Dept        | 412213   |
| 5     | 489965     | Employee    | 412323   |

假设部门和员工 table 在某种程度上与公司 table 有关。

我有另一个事件源 Table,域模型为 INVOICE

活动商店Table.

| event_id | invoice_id | Event            | Payload |
|----------|------------|------------------|---------|
| 1        | 12345      | Invoice_InReview | JSON    |
| 2        | 12345      | Invoice_Billed   | JSON    |
| 3        | 12345      | Invoice_Paid     | JSON    |
| 4        | 12345      | Invoice_Reversed | JSON    |
| 5        | 12345      | Invoice_Paid     | JSON    |

休息服务有时会传入员工、部门或员工 ID 以将更新应用于发票。

问题

我想看看是否有一种方法可以让事件存储处理不需要查询关系 table 来检索 invoice/invoices 然后将事件应用于它的场景。

我最初倾向于拥有域模型的快照,但问题仍然存在,因为部门或公司 ID 在 JSON 我无法 运行 基于它检索事件。

无论我看到什么方式,我都会先调用检索 invoice/invoices,然后才能应用事件或做任何事情。有什么我遗漏的可以帮助我摆脱 Relational Table 还是傻子做的梦?

又是一道题外话

快照保存在与事件存储相同的 table 中,正确吗?事件类型是 SNAPSHOT 对吗?如果我在这方面有误,请纠正我

I wanted to see if there is a way for event store to handle scenario where it does not need to query the relation table to retrieve the invoice/invoices and then apply events to it.

事件存储不应查询任何其他 table 除了它自己的。而且,事件存储不应该负责加载聚合并将事件应用于它(重新水化聚合)。这是使用事件存储的存储库的责任。

Event store在下层,应该有这两个方法:

interface EventStore
{
    EventStream loadEvents(aggregateId);
    void appendEvents(aggregateId, previousEventStream, eventsToBeAppended);
}

可能有其他方法,但与上面的抽象级别相同。

另一方面,事件源感知发票存储库将具有此接口:

interface InvoiceRepository {
   Invoice loadInvoice(invoiceId);
   void persistInvoice(invoiceId, invoiceNewEvents);
}

Here 是此类(尽管是通用的)存储库的示例。

我的拱门。对于上述问题将是:

发票汇总 状态 有薪酬的 发票信息

发票信息 公司发票信息 债务发票信息 员工发票信息

已创建发票 发票审核中 已开具发票

即将进行活动回顾

基本上都是api在agg上。应该要求 invoice_id 进一步处理:

用户如何获取并调用 API?

  1. 在生成发票并将收据提供给用户时或在写有发票 ID 的邮件中?
  2. 列出员工、公司或部门的所有发票?我需要一个 table(EmployeeInvoice) 有 (EmployeeId and InvoiceId and InvoiceStatus) ,一个 table (CompanyInvoice) 有 (CompanyId, InvoiceId , InvoiceStatus) 和 DeptInvoice(DeptId, CompanyId , InvoiceStatus)

从这里可以点击 Api 获取 InvoiceUpdate ,这里也有 InvoiceId。

  1. 需要将 API 暴露给外部世界的情况,例如 /updateInvoice?employeeId= 或 /updateInvoice?companyId= 或 /updateInvoice?deptId= 这里已经从 API 知道了需要查询哪一种table结构。

现在回答你的问题:

  1. 您将需要一些 table 来查询发票 ID,以防 API InvoiceId 不是必需的。 table 可以像我在上面所做的那样展平,也可以像你在那里做的那样展平。正如在聚合或 EventStore 模型中一样,事件存储始终基于单个 ID,并且 API 很多时候需要从 diff 中查询它。企业 ID。