Files
orbit/docs/api/workflow-queries.md

115 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 流程实例筛选与分页
状态:已实现HTTP和独立Go SDK。查询返回有限元数据,不聚合业务输入输出。单个实例的完整视图和步骤详情见[实例接口](workflows.md),历史激活、轮次与信号见[历史查询](workflow-history.md)。
## 接口与权限
`GET /v1/workflows`,要求显式 `workflows:read`。命名空间取自认证凭据,不接受查询参数覆盖;返回的每个实例必须满足其**启动时固定定义版本的全部队列权限**,包含尚未执行的分支、后续步骤和POLL队列。只拥有某个已生成任务的权限不代表可以读整个流程。
没有权限覆盖的实例在数据库中被过滤。指定定义/版本但当前范围没有匹配项,返回空列表;该结果不能用于断言资源不存在。只有SIGNAL/TIMER且不引用队列的版本仍需要 `workflows:read`,队列集合为空。不额外要求 `tasks:read` 或定义发布权限。
| 参数 | 语义 |
| --- | --- |
| `definition_id` | 可选,32位小写十六进制定义ID;不传则查询命名空间内可读实例 |
| `version` | 可选,必须同时指定definition_id;1–64位发布版本名,首位字母/数字,后续可含`_ . -` |
| `state` | 可选:RUNNING、WAITING、CANCELLING、NEEDS_REVIEW、SUCCEEDED、FAILED、CANCELLED |
| `paused` | 可选,只接受`true`或`false`;与state独立,false不等于不筛选 |
| `business_key` | 可选,非空且最多191个Unicode字符,无NUL;精确匹配,保留大小写、换行和尾部空格,URL必须正确编码 |
| `created_from` | 创建时间下界,包含;RFC3339,最多微秒精度 |
| `created_before` | 创建时间上界,不包含;与下界同时提供时必须晚于下界 |
| `limit` | 默认20,1–100 |
| `cursor` | 上一页next_cursor,最多1024字节 |
时间规范化到UTC,UTC年份2000–9998;拒绝微秒以下精度。拒绝未知、重复、空值参数和无效URL编码。业务键空字符串在SDK中表示不筛选;HTTP显式`business_key=`被拒绝,首版不提供“只查无业务键”条件。
请求示意:
```http
GET /v1/workflows?definition_id=11111111111111111111111111111111&version=v1&state=WAITING&paused=false&business_key=object-001%20&limit=20
Authorization: Bearer <private-token>
```
响应信封使用 `request_id` 与 `data`:
```json
{
"request_id": "example-request",
"data": {
"items": [{
"id": "22222222222222222222222222222222",
"namespace_id": "33333333333333333333333333333333",
"definition_id": "11111111111111111111111111111111",
"definition_version_id": "44444444444444444444444444444444",
"version": "v1",
"state": "WAITING",
"revision": "2",
"paused": false,
"control_revision": "1",
"business_key": "object-001 ",
"deadline_at": "2026-09-18T01:00:00Z",
"created_at": "2026-09-18T00:00:00Z",
"updated_at": "2026-09-18T00:00:00Z"
}]
}
}
```
摘要另可包含 `cancel_requested_at`、`stop_kind`、`stop_requested_at`、`completed_at`。版本数值使用十进制字符串;state和paused可以独立变化。没有 `input`、`output`、定义正文或策略快照,读取正文使用 `GetWorkflow`。空列表为 `items: []`;没有更多结果时省略 `next_cursor`。
## 翻页一致性
按 `created_at DESC, id DESC` 排序,两个字段共同定位,时间相同也不会因只按时间定位而漏项。每页最多返回100条,数据库读取最多limit+1个候选用于判断下一页。队列范围在LIMIT前筛选,不全量加载后在Go中裁剪。
游标绑定命名空间、全部筛选和规范化队列权限范围,不绑定页长。后续页可调整limit,不能删掉筛选重试;不同权限范围必须重新从第一页查询。队列权限顺序变化不影响游标。游标不授予权限,每页仍重新认证并核验版本归属和原定义。
分页不提供跨页数据库快照。期间新建的较新实例不会出现在已有游标后,状态或paused变化可能令实例进入或离开筛选。需要长期同步应另外设计有提交水位的事件消费,不能拿列表游标代替结果订阅确认。
## SDK
```go
paused := false
query := orbit.ListWorkflowsRequest{
DefinitionID: definitionID,
Version: "v1",
State: "WAITING",
Paused: &paused,
BusinessKey: "object-001 ",
CreatedFrom: &from,
CreatedBefore: &before,
Limit: 20,
}
for {
page, err := client.ListWorkflows(ctx, query)
if err != nil {
return err // 保留筛选;不能降级成全量查询
}
for _, item := range page.Items {
fmt.Println(item.ID, item.State, item.ControlRevision)
}
if page.NextCursor == "" {
break
}
query.Cursor = page.NextCursor
}
```
这是函数内片段,完整初始化、发布、创建、分页和取消清理见[可运行示例](../examples/workflow-query.md)。SDK采用独立 `WorkflowSummary`,不引用服务端模型。
## 存储与错误边界
迁移000024增加 `weave_version_scopes`,保存每个不可变版本的完整去重队列集合和原内容摘要。发布版本与范围索引同事务,升级从原DSL节点结构回填,输入/输出常量中的同名queue_id不计入范围。模型与SQL字段均有中文注释,**没有外键或级联约束**。
索引只协助SQL过滤。返回前仍严格验证原定义及其摘要、队列集合、固定版本/定义/门控归属和冻结策略;数据损坏时整页失败,不返回部分已读数据,也不把缺失范围解释为无需队列权限。范围中错误增加的队列可能使合法记录被隐藏,应通过数据库运维修复损坏,不能以放宽权限绕过。列表不验证实例的完整输入/输出正文;这些数据由单实例详情与运行器按固定契约核验。
八种定义/业务键/状态组合使用固定复合索引;version与paused作为附加筛选。授权过滤稀疏或paused选择性低时,扫描行数可能高于返回行数,limit不是扫描上限。P6须评估队列权限分布、数据保留量、索引写放大和查询超时预算,当前回归不构成百万租户容量结论。
| 情况 | 返回 |
| --- | --- |
| 参数、游标、筛选或权限指纹不匹配 | 400 / INVALID_ARGUMENT |
| 无workflows:read | 403 / PERMISSION_DENIED |
| 当前筛选无可读记录 | 200 / 空items |
| 关联或范围损坏 | 拒绝返回该页;可能为404或内部错误,保留原请求定位数据,禁止自动删条件重试 |
| 数据库暂不可用 | 保留原筛选及游标按有限退避重试,不解释为无匹配记录 |
本迁移按维护窗口执行:先停止旧版本的流程发布写入,完成范围回填,再启动新版服务开放发布。回填后仍由旧节点发布会生成缺少范围索引的版本,新查询会拒绝返回,不能靠重试修复;不支持新旧发布写节点无协调并行升级。旧服务没有此GET集合接口,不支持时SDK返回服务端错误,不静默降级。验证记录见[本阶段报告](../reports/phase-5-queries.md)。