Skip to content
bitzorcas
中EN

Guide

历史、归档与分析

说明审批轨迹、实例与业务 Timeline、归档事务、报表计算、查询端口降级、精度缺口和运营验证。

Last updated

Workflow 历史包含 ActivityRecord、运行中实例视图和归档实例。它可解释流程发生了什么,但当前不是不可篡改合规账本:记录与业务回调、通知、外部事件没有统一证据链,也没有签名/WORM 保留。

1. 读取端口

IWorkflowHistoryQuery 提供:

  • 单实例审批轨迹;
  • 运行/归档实例摘要;
  • 单实例 Timeline;
  • 同一 BusinessKey 的跨流程 Timeline;
  • 业务状态时间线与当前状态汇总。

IWorkflowArchivePort 负责终态实例归档;IWorkflowAnalyticsPort 负责实例、时效、审批人、瓶颈、驳回、趋势和部署分布。

2. ActivityRecord

运行操作追加 ActionType、NodeFrom/To、Executor、UserTo、Comment、FlowStateFrom/To、StatusFrom/To 与 Timestamp。它跟随大多数运行时事务写入,因此可用于解释并发成功路径。

Runtime operation

instance Version

task/execution mutation

ActivityRecord

Timeline

Business timeline

并非每个外部副作用都在记录内:通知发送结果、业务回调响应、Timer attempt 和缓存失效没有统一关联 ID。

3. 实例与 Timeline

GetInstance 先查归档表,再查运行表。运行终态的 EndTime 取最后一条 ActivityRecord;没有记录时返回 null,不用查询时刻伪造。

GetTimelineView 当前先查运行表。实例归档后已从运行表删除,因此该方法可能返回空 Timeline,即使 GetInstance 能从归档表读取摘要。归档后的 Timeline 可用性需要集成测试与实现补齐。

跨业务 Timeline 接受 businessKey,不带 tenantId;隔离依赖 Store 的当前租户过滤。BusinessKey 不全局唯一时,独立宿主必须加租户/业务类型边界。

4. 归档

Archive 只接受非 Running/Suspended 实例,先检查历史表实现幂等,然后在事务中保存 WorkflowHistoryInstanceData 并删除运行实例。

当前归档事务
await using var transaction =
await store.BeginTransactionAsync(cancellationToken);
// 先保存最小历史摘要,再删除活动实例。
await store.SaveHistoryInstanceAsync(history, cancellationToken);
await store.DeleteInstanceAsync(instanceId, cancellationToken);
// 当前事务没有显式删除任务、执行、变量、Timer 等子记录。
await transaction.CommitAsync(cancellationToken);

当前归档没有删除 Execution、Task、Candidate 或 Timer;ActivityRecord 明确保留。若数据库没有级联约束,运行子表会成为孤儿;若有级联,任务历史可能丢失。必须用双 ORM Schema 和真实数据库验证,而不是从方法名推断。

DefinitionName 被写成 DefinitionKey,EndReason 写成 Status 字符串。归档不是完整展示快照。

5. 报表来源

IWorkflowQueryStore 提供实例、已完成任务、驳回记录和部署统计原始数据。引擎在内存计算节点时效、审批人效能、瓶颈、驳回热点和趋势。

IWorkflowQueryStore

instances

completed tasks

reject records

trend / instance statistics

duration / approver / bottleneck

reject hotspots

没有 QueryStore 时,实例统计返回零值,其他报表多返回空集合。成功的 HTTP 200 不代表报表能力可用。

6. 时效精度

TaskDuration 使用 CompleteTime-CreateTime,可计算平均、P50、P90 和超时率。Approver 与 Bottleneck 同样基于已完成任务。

Trend 当前把“在期间创建且已终态”的实例视为完成,并把 AvgDuration 固定为 TimeSpan.Zero;它没有使用归档 EndTime。StatisticsAggregationJob 的 AvgDurationSeconds 与 MaxDurationSeconds 也固定为 0。

7. 时间区间与时区

趋势查询不再以 DateTimeOffset.MinValue/当前时钟补齐缺失端点。GetTrendReportQueryRule 要求 From、To 同时存在且 From≤To,失败返回 Workflow.Report.PeriodInvalid;合法值原样传给 IWorkflowAnalyticsPort。当前没有最大跨度规则,调用方仍应采用有界窗口。

StatisticsAggregationJob 用传入 date.Date 构造 UTC 零点,按 DefinitionKey、TenantId、OfficeId 分组。业务租户若按本地日统计,需要明确时区转换、夏令时和迟到数据回补。

AggregateRange 顺序逐日执行,没有 checkpoint/lease;SaveStatisticsDaily 以稳定 ID 覆盖,具备结果幂等倾向,但并发、部分失败和重跑仍需 Provider 测试。

8. 报表示例

查询审批时效
var filter = new ReportFilter
{
// 所有报表必须显式限定可信租户与时间窗。
TenantId = currentTenantId,
DefinitionKey = "matter-intake-approval",
From = fromUtc,
To = toUtc,
TopN = 20
};
IReadOnlyList<TaskDurationReport> rows =
await analytics.GetTaskDurationReportAsync(
filter,
cancellationToken);
// 空结果既可能是没有数据,也可能是 QueryStore 未组合。

Platform Handler 必须从 CurrentUser 限定 TenantId;不要直接接受管理员请求体中的任意 TenantId。

9. 隐私与保留

ActivityRecord.Comment、变量和任务名称可能包含个人或敏感业务数据。当前 Workflow 没有独立 retention/erasure 编排,也没有对归档表、轨迹、报表、缓存和备份的统一数据主体清理。

保留策略需定义:

  • 运行任务与候选人保留多久;
  • 轨迹意见是否允许删除或脱敏;
  • 归档实例与业务事实谁是主记录;
  • 报表聚合是否可追溯到个人;
  • 法务保全如何覆盖自动清理;
  • 删除后如何处理备份恢复再删除。

10. 运营指标

监控 active/pending/overdue、完成与驳回率、任务年龄 P95、Timer Pending/Fired/failed、归档 backlog、QueryStore latency、报表扫描行数、缓存命中和跨实例陈旧。标签禁止 taskId、businessKey、comment 或用户 ID。

11. 测试清单

  • 运行/归档实例读取一致;
  • 归档后 Timeline、Task、ActivityRecord 行为;
  • 归档重复与事务中断;
  • 双 ORM 的级联/孤儿差异;
  • QueryStore 缺失的显式降级;
  • 时区、跨日、迟到完成与大区间;
  • P50/P90 小样本与空集合;
  • 跨租户 businessKey 冲突;
  • 删除/保留与法务保全。

12. 源码核查

Terminal window
rg -n "ArchiveAsync|SaveHistoryInstance|DeleteInstanceAsync" src/Framework/BitzOrcas.Workflow -g '*.cs'
rg -n "TimeSpan.Zero|AvgDurationSeconds = 0|QueryStore" src/Framework/BitzOrcas.Workflow/BitzOrcas.Workflow.Engine -g '*.cs'

下一篇:迁移与导入

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%