feat: add scoped workflow instance queries and SDK pagination

This commit is contained in:
2026-09-18 08:34:45 +08:00
parent 17a8e0126c
commit 082898e705
33 changed files with 1598 additions and 18 deletions

View File

@@ -0,0 +1,57 @@
-- 固定版本查询范围与列表索引;禁止外键,不改写版本、实例或任务历史。
CREATE TABLE weave_version_scopes (
namespace_id BINARY(16) NOT NULL COMMENT '命名空间,参与版本身份及查询授权',
definition_version_id BINARY(16) NOT NULL COMMENT '固定定义版本标识,范围包含所有未执行分支',
definition_id BINARY(16) NOT NULL COMMENT '所属定义标识,服务端核对其与版本及实例的归属',
content_digest BINARY(32) NOT NULL COMMENT '原不可变定义摘要,防止跨版本使用范围',
queue_ids JSON NOT NULL COMMENT '去重队列标识数组,空数组表示无任务队列;只用于查询筛选,返回前仍需核验原定义',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '查询索引建立时间,UTC;不能替代原定义发布时间',
PRIMARY KEY(namespace_id,definition_version_id),
KEY ix_version_scope_definition(namespace_id,definition_id,definition_version_id),
CONSTRAINT ck_version_scope_queues CHECK (JSON_SCHEMA_VALID('{"type":"array","maxItems":128,"uniqueItems":true,"items":{"type":"string","pattern":"^[0-9a-f]{32}$"}}',queue_ids))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='不可变流程版本的查询队列范围,供实例列表在数据库内筛选当前权限';
-- 只遍历定义结构中的步骤块,不将输入常量中的task/queue_id误当成流程权限。
-- 合法结构最多4层组合嵌套;此处多保留一层用于识别异常数据,公共读取仍严格校验原定义。
INSERT INTO weave_version_scopes(namespace_id,definition_version_id,definition_id,content_digest,queue_ids)
WITH RECURSIVE nodes AS (
SELECT v.namespace_id,v.id AS version_id,s.node,0 AS depth
FROM weave_definition_versions v
JOIN JSON_TABLE(v.specification,'$.body.steps[*]' COLUMNS(node JSON PATH '$')) s
UNION ALL
SELECT n.namespace_id,n.version_id,s.node,n.depth+1
FROM nodes n
JOIN JSON_TABLE(
CASE JSON_UNQUOTE(JSON_EXTRACT(n.node,'$.kind'))
WHEN 'BRANCH' THEN JSON_MERGE_PRESERVE(COALESCE(JSON_EXTRACT(n.node,'$.branch.cases[*].body.steps[*]'),JSON_ARRAY()),COALESCE(JSON_EXTRACT(n.node,'$.branch.default.steps[*]'),JSON_ARRAY()))
WHEN 'PARALLEL' THEN COALESCE(JSON_EXTRACT(n.node,'$.parallel.branches[*].body.steps[*]'),JSON_ARRAY())
ELSE JSON_ARRAY()
END,'$[*]' COLUMNS(node JSON PATH '$')) s
WHERE n.depth<5
), distinct_queues AS (
SELECT DISTINCT namespace_id,version_id,
CASE JSON_UNQUOTE(JSON_EXTRACT(node,'$.kind'))
WHEN 'TASK' THEN JSON_UNQUOTE(JSON_EXTRACT(node,'$.task.queue_id'))
WHEN 'POLL' THEN JSON_UNQUOTE(JSON_EXTRACT(node,'$.poll.task.queue_id'))
END AS queue_id
FROM nodes
WHERE JSON_UNQUOTE(JSON_EXTRACT(node,'$.kind')) IN ('TASK','POLL')
), scopes AS (
SELECT namespace_id,version_id,JSON_ARRAYAGG(queue_id) AS queue_ids
FROM distinct_queues GROUP BY namespace_id,version_id
)
SELECT v.namespace_id,v.id,v.definition_id,v.content_digest,COALESCE(s.queue_ids,JSON_ARRAY())
FROM weave_definition_versions v LEFT JOIN scopes s ON s.namespace_id=v.namespace_id AND s.version_id=v.id;
CREATE TRIGGER trg_version_scope_immutable BEFORE UPDATE ON weave_version_scopes
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Workflow query scopes are immutable';
-- 定义、业务键及状态都是可选等值筛选;创建时间和ID作为稳定分页位置。
ALTER TABLE weave_instances
ADD KEY ix_workflow_created(namespace_id,created_at,id),
ADD KEY ix_workflow_state_created(namespace_id,state,created_at,id),
ADD KEY ix_workflow_business_state_created(namespace_id,business_key,state,created_at,id),
ADD KEY ix_workflow_definition_created(namespace_id,definition_id,created_at,id),
ADD KEY ix_workflow_definition_state_created(namespace_id,definition_id,state,created_at,id),
ADD KEY ix_workflow_definition_business_created(namespace_id,definition_id,business_key,created_at,id),
ADD KEY ix_workflow_definition_business_state_created(namespace_id,definition_id,business_key,state,created_at,id);