feat: add scoped workflow instance queries and SDK pagination
This commit is contained in:
@@ -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);
|
||||
Reference in New Issue
Block a user