147 lines
8.8 KiB
Markdown
147 lines
8.8 KiB
Markdown
# 流程人工核查与恢复 API / SDK
|
||
|
||
状态:六类内部恢复已接入公共HTTP和独立SDK。所有路径以 `/v1/workflows/{id}/recovery/` 开头,均为POST,要求 `workflows:recover`、全部固定队列范围、Bearer凭据、稳定Idempotency-Key及application/json。成功首次与重复响应均为200。身份、读查询、错误码见[实例接口](workflows.md)。
|
||
|
||
恢复只针对NEEDS_REVIEW实例。SDK不会自动重试、补齐声明、刷新版本或生成新键。核查前应读取当前实例、当前步骤、相关任务及外部证据;每次新决定使用当前版本,响应未知则用原决定原键核对。输入和结果最多256 KiB,请求体总计最多512 KiB。
|
||
|
||
## 1. 公共字段
|
||
|
||
所有请求包含WorkflowRecoveryDecision的**扁平字段**:
|
||
|
||
| 字段 | 必填与语义 |
|
||
| --- | --- |
|
||
| expected_revision | 必填,当前实例的非零revision十进制字符串,不能用control_revision替代 |
|
||
| reason | 必填,1–1024个Unicode字符;不允许全空白或NUL |
|
||
| evidence_ref | 必填,1–512个Unicode字符,不含空白或控制字符;平台不访问引用、不存放秘密 |
|
||
|
||
步骤类请求还包含WorkflowStepDecision的扁平字段:step_key(固定定义步骤名,最多64个ASCII字符)、activation_id(当前32位激活ID)、expected_step_revision(当前非零步骤版本字符串)。实例版本、步骤版本及激活身份一起检查,旧激活不能操作新工作。
|
||
|
||
服务端检查待消费/隔离Inbox、历史任务归属、仍在执行的尝试及未释放许可。声明为true是操作者确认,不替代服务端验证。恢复不会重置原绝对截止、次数或业务关联;已有停止目标不会被撤销。
|
||
|
||
## 2. 六类命令
|
||
|
||
| 路径后缀 | SDK方法 / 请求类型 | 额外必填字段与结果 |
|
||
| --- | --- | --- |
|
||
| task-review | ReviewWorkflowTask / ReviewWorkflowTaskRequest | task_id、expected_task_revision字符串、execution_settled=true、outcome=SUCCEEDED或FAILED、非null result;核实本实例任一历史激活的待核查执行 |
|
||
| step-resolve | ResolveWorkflowStep / ResolveWorkflowStepRequest | 步骤公共字段、execution_settled=true、outcome=SUCCEEDED或FAILED、result;确认当前叶子步骤的逻辑结论 |
|
||
| continue | ContinueWorkflow / ContinueWorkflowRequest | review_resolved=true;确认全部核查事项已处理后解除核查 |
|
||
| step-retry | RetryWorkflowStep / RetryWorkflowStepRequest | 步骤公共字段、safe_to_retry=true;为TASK/POLL创建新激活,保留原预算和截止 |
|
||
| poll-continue | ContinueWorkflowPoll / ContinueWorkflowPollRequest | 步骤公共字段、pending_confirmed=true;权威结果已确认为PENDING时按原间隔恢复等待,不重查同轮 |
|
||
| wait-rearm | RearmWorkflowWait / RearmWorkflowWaitRequest | 步骤公共字段、wait_verified=true;独立SIGNAL/TIMER在原截止内更换等待代次,含首次最多32代 |
|
||
|
||
所有确认布尔值必须在HTTP中显式提供且为true。拒绝嵌套`Decision`、伪造actor_id、大小写别名和未声明字段。
|
||
|
||
执行核查请求示例:
|
||
|
||
```json
|
||
{
|
||
"expected_revision":"8",
|
||
"reason":"已核实请求完成且外部作业仍在处理",
|
||
"evidence_ref":"evidence:query-001",
|
||
"task_id":"88888888888888888888888888888888",
|
||
"expected_task_revision":"4",
|
||
"execution_settled":true,
|
||
"outcome":"SUCCEEDED",
|
||
"result":"PENDING"
|
||
}
|
||
```
|
||
|
||
ReviewTask只改变执行结论,旧UNKNOWN尝试和证据保持原样。它产生新的内部结果,必须等待后台消费,当前步骤及实例不会自动解除核查。POLL请求成功不等于流程业务成功;ResolveStep对POLL的成功结果必须映射到固定的业务成功值,不能把PENDING写成步骤成功。TIMER成功只能在首次等待时长满足后确认,result必须为显式null。
|
||
|
||
PENDING接续请求示例:
|
||
|
||
```json
|
||
{
|
||
"expected_revision":"11",
|
||
"reason":"沿原间隔继续查询外部作业",
|
||
"evidence_ref":"evidence:query-001",
|
||
"step_key":"query",
|
||
"activation_id":"66666666666666666666666666666666",
|
||
"expected_step_revision":"3",
|
||
"pending_confirmed":true
|
||
}
|
||
```
|
||
|
||
相同字段布局适用于step-resolve、step-retry和wait-rearm,额外字段按上表替换。Continue只有实例公共字段及review_resolved,不要求步骤字段。
|
||
|
||
## 3. 回执与当前视图
|
||
|
||
六个方法统一返回WorkflowRecoveryResult;HTTP的data字段为该对象:
|
||
|
||
| 字段 | 含义 |
|
||
| --- | --- |
|
||
| instance | 首次管理事务完成时的完整实例快照,字段同[启动回执](workflows.md#2-固定版本启动) |
|
||
| audit_id | 本次流程管理审计ID,可用GetWorkflowOperation读取原因、证据及前后摘要 |
|
||
| step | 步骤类操作返回当前步骤快照,包含激活代次;不是后续实时状态 |
|
||
| task | task-review或step-retry返回执行任务快照;字段同GetTask |
|
||
| task_audit_id | task-review对应的独立任务审计ID,与流程审计同事务保存 |
|
||
| deduplicated | 是否恢复原回执;恢复原键仍检查当前权限 |
|
||
|
||
步骤恢复回执示意,省略字段按协议确实不存在,并非JSON占位:
|
||
|
||
```json
|
||
{
|
||
"request_id":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||
"data":{
|
||
"instance":{
|
||
"id":"22222222222222222222222222222222",
|
||
"namespace_id":"33333333333333333333333333333333",
|
||
"definition_id":"11111111111111111111111111111111",
|
||
"definition_version_id":"44444444444444444444444444444444",
|
||
"version":"v1","state":"NEEDS_REVIEW","revision":"13",
|
||
"paused":false,"control_revision":"3",
|
||
"input":{"n":9007199254740993},"business_key":"operation-001 ",
|
||
"deadline_at":"2026-09-18T08:01:00Z",
|
||
"created_at":"2026-09-18T08:00:00Z","updated_at":"2026-09-18T08:00:10Z"
|
||
},
|
||
"audit_id":"99999999999999999999999999999999",
|
||
"step":{
|
||
"id":"55555555555555555555555555555555","key":"query","kind":"POLL",
|
||
"state":"WAITING","revision":"4",
|
||
"activation_id":"66666666666666666666666666666666","activation_sequence":1
|
||
},
|
||
"deduplicated":false
|
||
}
|
||
}
|
||
```
|
||
|
||
ContinuePoll保留当前激活与信号代次;RetryStep及RearmWait创建新激活。恢复等待或创建新任务后仍须显式Continue解除核查;paused仍为true时还需ControlWorkflow(RESUME)。任何恢复操作都不盲目撤回已发生的外部业务效果。
|
||
|
||
## 4. SDK接入顺序
|
||
|
||
以下为嵌入接入方函数的调用片段,api是已认证Client,workflowID为目标实例,operationKey与本次完整命令需要由调用方持久保存:
|
||
|
||
```go
|
||
current, err := api.GetWorkflowStep(ctx, workflowID, "query")
|
||
if err != nil { return err }
|
||
if current.Step.ActivationID == nil { return errors.New("query is not activated") }
|
||
command := orbit.ContinueWorkflowPollRequest{
|
||
WorkflowStepDecision: orbit.WorkflowStepDecision{
|
||
WorkflowRecoveryDecision: orbit.WorkflowRecoveryDecision{
|
||
ExpectedRevision: current.Revision,
|
||
Reason: "已核实权威PENDING结果,沿原预算接续",
|
||
EvidenceRef: "evidence:query-001",
|
||
},
|
||
StepKey: current.Step.Key,
|
||
ActivationID: *current.Step.ActivationID,
|
||
ExpectedStepRevision: current.Step.Revision,
|
||
},
|
||
PendingConfirmed: true,
|
||
}
|
||
receipt, err := api.ContinueWorkflowPoll(ctx, workflowID, operationKey, command)
|
||
if err != nil { return err } // 不生成新键绕过冲突;结果不明时原命令原键核对。
|
||
audit, err := api.GetWorkflowOperation(ctx, workflowID, receipt.AuditID)
|
||
if err != nil { return err }
|
||
fmt.Println(audit.Action, receipt.Instance.State)
|
||
```
|
||
|
||
完整、可执行的六类SDK场景位于[真实服务集成测试](../../sdk/go/workflow_instances_integration_test.go):UNKNOWN→执行核查→逻辑结论→解除核查;已知失败→剩余预算重试,同时重建信号等待;UNKNOWN查询→核查为PENDING→原间隔接续。运行方式为仓库根目录`make integration`,由脚本创建隔离MySQL、实际服务及凭据。
|
||
|
||
一般步骤是:查询当前事实 → 提交一个有证据的决定 → 等待该决定产生的内部结果消费 → 重新读取当前版本 → 再提交下一决定。不要自动将任意STATE_CONFLICT重试为“最新版本”;冲突可能意味着新的在途结果、权限变化、原截止已到或预算耗尽,应重新核查。相同命令的响应未知则仍使用原版本和原键。
|
||
|
||
## 5. 兼容与剩余范围
|
||
|
||
新路由仅在本开发版本及之后可用;旧服务返回404时不能降级为普通任务重试来绕过Weave所有权。SDK类型独立、版本字段保留uint64精度。规则及数据模型未增加表、字段、外键或级联。
|
||
|
||
本批尚不提供完整历史激活/轮次遍历、实例筛选列表或信号资源审计列表;当前输入结果、当前查询预算、单条信号、流程管理审计及[任务历史激活来源](task-source.md#5-流程固定来源)可读。生产数据库切换、容量及恢复目标继续按P6验证,见[阶段报告](../reports/phase-5-public-api.md)。
|