feat: establish Orbit models, migrations and development baseline

This commit is contained in:
2026-09-17 07:04:21 +08:00
commit 4f2935e36f
84 changed files with 4915 additions and 0 deletions

View File

@@ -0,0 +1,816 @@
-- Orbit initial schema, MySQL 8.4+. All times are UTC at microsecond precision.
-- Do not edit an applied migration. Add a new forward migration instead.
CREATE TABLE orbit_applications (
id BINARY(16) NOT NULL COMMENT '应用标识,全局唯一',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用;关闭后拒绝相应的新接入或新操作',
PRIMARY KEY (id),
UNIQUE KEY uq_application_name (name),
CONSTRAINT ck_orbit_applications_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='接入应用,承载通用应用身份与启停配置';
CREATE TABLE orbit_namespaces (
id BINARY(16) NOT NULL COMMENT '命名空间标识,全局唯一',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`application_id` BINARY(16) NOT NULL COMMENT '所属应用标识',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`environment` VARCHAR(32) NOT NULL COMMENT '环境标识,用于区分开发、测试和生产等隔离范围',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用;关闭后拒绝相应的新接入或新操作',
PRIMARY KEY (id),
UNIQUE KEY uq_namespace_name (application_id, environment, name),
CONSTRAINT ck_orbit_namespaces_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='应用在指定环境中的资源隔离边界';
CREATE TABLE orbit_credentials (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`secret_digest` BINARY(32) NOT NULL COMMENT '凭据秘密的 SHA-256 摘要,不保存或输出原文',
`permissions` JSON NOT NULL COMMENT '授权范围的 JSON 快照,必须由服务端解释和校验',
`expires_at` DATETIME(6) NULL COMMENT '凭据过期时间,统一 UTC;为空表示没有配置到期时间',
`revoked_at` DATETIME(6) NULL COMMENT '撤销时间;为空表示尚未撤销',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_credential_name (namespace_id, name),
CONSTRAINT ck_orbit_credentials_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='命名空间凭据,只保存秘密摘要和授权范围';
CREATE TABLE orbit_idempotency_keys (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`operation` VARCHAR(64) NOT NULL COMMENT '稳定操作类型,用于区分不同接口的幂等作用域',
`scope_key` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '资源作用域标识;空字符串表示当前操作的默认作用域',
`key_digest` BINARY(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`request_digest` BINARY(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`resource_kind` VARCHAR(32) NOT NULL COMMENT '关联资源类型;多态关联需要服务层额外校验',
`resource_id` BINARY(16) NOT NULL COMMENT '关联资源标识,不能单独作为访问授权依据',
`response` JSON NOT NULL COMMENT '首次可靠提交后的响应 JSON,供重复请求补取确认',
`expires_at` DATETIME(6) NOT NULL COMMENT '幂等保留截止时间,不应短于约定的重发与恢复窗口',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_idempotency_scope (namespace_id, operation, scope_key, key_digest),
KEY ix_idempotency_expiry (expires_at, namespace_id, id),
CONSTRAINT ck_orbit_idempotency_keys_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='请求幂等记录,关联语义摘要与首次受理响应';
CREATE TABLE orbit_events (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`aggregate_kind` VARCHAR(32) NOT NULL COMMENT '产生事件的聚合类型,例如任务或流程',
`aggregate_id` BINARY(16) NOT NULL COMMENT '产生事件的聚合标识',
`aggregate_revision` BIGINT UNSIGNED NOT NULL COMMENT '来源聚合的状态版本,用于去重与迟到事件判断',
`type` VARCHAR(64) NOT NULL COMMENT '事件或信号的稳定类型标识',
`payload` JSON NOT NULL COMMENT '版本化输入或事件内容;仅承载通用 JSON,不解释行业规则',
`occurred_at` DATETIME(6) NOT NULL COMMENT '事件发生时间,统一 UTC',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_event_revision (namespace_id, aggregate_kind, aggregate_id, aggregate_revision, type),
CONSTRAINT ck_orbit_events_0 CHECK (revision > 0),
CONSTRAINT ck_orbit_events_1 CHECK (aggregate_revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='追加保存的状态事件,供外部订阅或内部流程接续';
CREATE TABLE orbit_subscriptions (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`credential_id` BINARY(16) NOT NULL COMMENT '关联的命名空间凭据标识',
`filter` JSON NOT NULL COMMENT '订阅过滤规则的 JSON 文档',
`enabled` BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用;关闭后拒绝相应的新接入或新操作',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_subscription_name (namespace_id, name),
CONSTRAINT ck_orbit_subscriptions_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='事件订阅配置,绑定授权凭据及过滤规则';
CREATE TABLE orbit_deliveries (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`subscription_id` BINARY(16) NOT NULL COMMENT '目标订阅标识',
`event_id` BINARY(16) NOT NULL COMMENT '来源持久化事件标识,用于消费去重',
`state` VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`available_at` DATETIME(6) NOT NULL COMMENT '该事件最早允许再次交付的时间,统一 UTC',
`lease_owner` BINARY(16) NULL COMMENT '租约持有者标识;未持有租约时为空',
`lease_epoch` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` DATETIME(6) NULL COMMENT '交付租约截止时间;没有交付租约时为空',
`attempts` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已产生的交付尝试次数,不等同于业务执行次数',
`acknowledged_at` DATETIME(6) NULL COMMENT '接收方可靠处理后的确认时间;未确认时为空',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_delivery_event (namespace_id, subscription_id, event_id),
KEY ix_delivery_due (namespace_id, state, available_at, id),
CONSTRAINT ck_orbit_deliveries_0 CHECK (revision > 0),
CONSTRAINT ck_orbit_deliveries_1 CHECK (state IN ('PENDING', 'LEASED', 'ACKED', 'EXPIRED')),
CONSTRAINT ck_orbit_deliveries_2 CHECK ((state = 'LEASED' AND lease_owner IS NOT NULL AND lease_until IS NOT NULL) OR (state <> 'LEASED' AND lease_owner IS NULL AND lease_until IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='单个事件向一个订阅的可靠交付记录';
CREATE TABLE orbit_audit_events (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`operation_id` BINARY(16) NOT NULL COMMENT '管理操作的稳定身份,重复操作必须保留同一身份',
`actor_id` VARCHAR(128) NOT NULL COMMENT '经认证的操作主体标识,不能直接信任请求自报值',
`action` VARCHAR(64) NOT NULL COMMENT '执行的管理动作,例如暂停、取消或核查',
`resource_kind` VARCHAR(32) NOT NULL COMMENT '关联资源类型;多态关联需要服务层额外校验',
`resource_id` BINARY(16) NOT NULL COMMENT '关联资源标识,不能单独作为访问授权依据',
`reason` VARCHAR(1024) NOT NULL COMMENT '操作原因或处理说明,需要保留审计信息',
`before` JSON NULL COMMENT '操作前的受控摘要 JSON,须脱敏',
`after` JSON NULL COMMENT '操作后的受控摘要 JSON,须脱敏',
`evidence_ref` VARCHAR(512) NULL COMMENT '业务核查证据的引用;为空表示没有附加引用',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_audit_operation (namespace_id, operation_id),
KEY ix_audit_resource (namespace_id, resource_kind, resource_id, created_at, id),
CONSTRAINT ck_orbit_audit_events_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='不可改写的管理审计,保留操作身份、原因和变更摘要';
CREATE TABLE pulse_queues (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`paused` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`max_concurrency` INT UNSIGNED NOT NULL COMMENT '允许同时持有的有效执行许可上限,必须大于零',
`rate_per_second` INT UNSIGNED NOT NULL COMMENT '每秒新执行的速率配置;实际限流由共享协调逻辑落实',
`policy` JSON NOT NULL COMMENT '队列资源与执行配置的 JSON 文档',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_queue_name (namespace_id, name),
CONSTRAINT ck_pulse_queues_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_queues_1 CHECK (max_concurrency > 0),
CONSTRAINT ck_pulse_queues_2 CHECK (rate_per_second > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='任务路由与资源控制队列,不要求每个租户单独创建队列';
CREATE TABLE pulse_execution_gates (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`paused` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`control_revision` BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '暂停、继续等控制操作的版本,避免旧操作覆盖新决定',
`reason` VARCHAR(1024) NULL COMMENT '操作原因或处理说明,需要保留审计信息',
PRIMARY KEY (namespace_id, id),
CONSTRAINT ck_pulse_execution_gates_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_execution_gates_1 CHECK (control_revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='通用执行门控,协调暂停与新执行授权的竞争';
CREATE TABLE pulse_worker_sessions (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`worker_instance_id` BINARY(16) NOT NULL COMMENT 'Worker 进程实例标识,重连保留,进程重启应更换',
`credential_id` BINARY(16) NOT NULL COMMENT '关联的命名空间凭据标识',
`node_id` BINARY(16) NOT NULL COMMENT '承载当前连接的平台节点标识',
`session_epoch` BIGINT UNSIGNED NOT NULL COMMENT '该 Worker 实例的连接代次,用于隔离旧会话',
`capabilities` JSON NOT NULL COMMENT '已登记的处理器版本、队列等能力快照',
`capacity` INT UNSIGNED NOT NULL COMMENT 'Worker 声明的执行容量,仍受平台权限和配额约束',
`capacity_sequence` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '会话内容量消息序号,重复上报不得重复增加额度',
`draining` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否正在排空连接;排空时不接收新任务',
`expires_at` DATETIME(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_worker_epoch (namespace_id, worker_instance_id, session_epoch),
KEY ix_worker_expiry (expires_at, namespace_id, id),
CONSTRAINT ck_pulse_worker_sessions_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_worker_sessions_1 CHECK (session_epoch > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次 Worker 连接的持久化身份与能力快照';
CREATE TABLE pulse_tasks (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`queue_id` BINARY(16) NOT NULL COMMENT '任务所属队列,必须属于同一命名空间',
`gate_id` BINARY(16) NULL COMMENT '可选执行门控;为空表示没有流程级门控,仍受队列与权限控制',
`state` VARCHAR(32) NOT NULL DEFAULT 'WAITING' COMMENT '任务状态;与执行尝试状态分开,未知业务效果进入待核查',
`handler` VARCHAR(128) NOT NULL COMMENT '业务 Worker 注册的处理器名称',
`handler_version` VARCHAR(64) NOT NULL COMMENT '处理器兼容版本,受理后不得静默替换',
`payload_version` VARCHAR(32) NOT NULL COMMENT '输入参数的解释版本',
`payload` JSON NOT NULL COMMENT '版本化输入或事件内容;仅承载通用 JSON,不解释行业规则',
`result` JSON NULL COMMENT '已保存的结果或结果引用 JSON;未取得结果时为空',
`policy_snapshot` JSON NOT NULL COMMENT '受理时冻结的实际生效策略 JSON',
`recovery_safety` VARCHAR(32) NOT NULL DEFAULT 'RECONCILE_ONLY' COMMENT '恢复安全等级;未知值按需要核查处理,不能默认自动重跑',
`business_key` VARCHAR(191) NULL COMMENT '业务侧关联键,用于检索追踪,不自动提供业务幂等',
`owner_kind` VARCHAR(32) NULL COMMENT '来源资源类型,例如流程激活;为空表示无来源关联',
`owner_id` BINARY(16) NULL COMMENT '来源资源标识,必须与来源类型同时有值或同时为空',
`priority` SMALLINT NOT NULL DEFAULT 0 COMMENT '同一调度范围内的优先级,不承诺跨队列全局顺序',
`available_at` DATETIME(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
`start_deadline_at` DATETIME(6) NULL COMMENT '最晚允许新尝试开始的时间;为空时仅受总时限约束',
`deadline_at` DATETIME(6) NOT NULL COMMENT '总截止时间,统一 UTC;到期不能证明外部业务没有生效',
`attempt_timeout_ms` BIGINT UNSIGNED NOT NULL COMMENT '单次尝试的超时时长,单位毫秒',
`max_attempts` INT UNSIGNED NOT NULL COMMENT '最多执行尝试数,包含首次尝试',
`attempt_count` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已产生的执行尝试数,恢复时不得重置',
`current_attempt_id` BINARY(16) NULL COMMENT '当前关联的执行尝试,必须属于本任务',
`lease_epoch` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` DATETIME(6) NULL COMMENT '当前执行授权截止时间;没有有效授权时为空',
`cancel_requested_at` DATETIME(6) NULL COMMENT '取消意图的持久化时间;不等于取消已完成',
`retry_of` BINARY(16) NULL COMMENT '来源记录标识,人工重新发起时用于保留历史关联',
`completed_at` DATETIME(6) NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
PRIMARY KEY (namespace_id, id),
KEY ix_task_dispatch (namespace_id, queue_id, state, available_at, priority, id),
KEY ix_task_lease_recovery (state, lease_until, namespace_id, id),
KEY ix_task_business (namespace_id, business_key, created_at, id),
CONSTRAINT ck_pulse_tasks_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_tasks_1 CHECK (state IN ('WAITING', 'LEASED', 'RUNNING', 'NEEDS_REVIEW', 'SUCCEEDED', 'FAILED', 'CANCELLED')),
CONSTRAINT ck_pulse_tasks_2 CHECK (recovery_safety IN ('IDEMPOTENT', 'RECONCILE_ONLY')),
CONSTRAINT ck_pulse_tasks_3 CHECK (max_attempts > 0 AND attempt_count <= max_attempts),
CONSTRAINT ck_pulse_tasks_4 CHECK (attempt_timeout_ms > 0),
CONSTRAINT ck_pulse_tasks_5 CHECK (deadline_at > available_at),
CONSTRAINT ck_pulse_tasks_6 CHECK (start_deadline_at IS NULL OR start_deadline_at <= deadline_at),
CONSTRAINT ck_pulse_tasks_7 CHECK (((state IN ('LEASED', 'RUNNING')) AND current_attempt_id IS NOT NULL AND lease_until IS NOT NULL) OR ((state NOT IN ('LEASED', 'RUNNING')) AND lease_until IS NULL)),
CONSTRAINT ck_pulse_tasks_8 CHECK ((state IN ('SUCCEEDED', 'FAILED', 'CANCELLED') AND completed_at IS NOT NULL) OR (state NOT IN ('SUCCEEDED', 'FAILED', 'CANCELLED') AND completed_at IS NULL)),
CONSTRAINT ck_pulse_tasks_9 CHECK ((owner_kind IS NULL) = (owner_id IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='任务主记录,执行尝试另存历史,终态不自动回退';
CREATE TABLE pulse_attempts (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`task_id` BINARY(16) NOT NULL COMMENT '关联的 Pulse 任务标识',
`epoch` BIGINT UNSIGNED NOT NULL COMMENT '该任务的授权代次,同一任务内唯一且递增',
`session_id` BINARY(16) NOT NULL COMMENT '当前执行归属的 Worker 会话标识',
`token_digest` BINARY(32) NOT NULL COMMENT '执行秘密令牌的 SHA-256 摘要,不输出原令牌',
`state` VARCHAR(32) NOT NULL DEFAULT 'LEASED' COMMENT '当前执行尝试的状态,不能代替整个任务的状态',
`lease_until` DATETIME(6) NOT NULL COMMENT '已确认的租约截止时间,必须用数据库时间核验',
`authorized_at` DATETIME(6) NULL COMMENT '平台允许处理器开始的时间;不能证明业务副作用已经发生',
`ended_at` DATETIME(6) NULL COMMENT '本次尝试结束时间;尚未结束时为空',
`error_code` VARCHAR(64) NULL COMMENT '稳定错误分类,供恢复策略判断;不得写入敏感原始错误',
`result` JSON NULL COMMENT '已保存的结果或结果引用 JSON;未取得结果时为空',
`result_digest` BINARY(32) NULL COMMENT '结果语义摘要,用于识别确认重报与冲突结果',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_attempt_epoch (namespace_id, task_id, epoch),
UNIQUE KEY uq_attempt_task_id (namespace_id, task_id, id),
CONSTRAINT ck_pulse_attempts_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_attempts_1 CHECK (state IN ('LEASED', 'RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED', 'EXPIRED', 'UNKNOWN')),
CONSTRAINT ck_pulse_attempts_2 CHECK (epoch > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次任务执行尝试,保存租约、授权代次与独立结果';
CREATE TABLE pulse_attempt_receipts (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`attempt_id` BINARY(16) NOT NULL COMMENT '关联的独立执行尝试标识',
`operation` VARCHAR(32) NOT NULL COMMENT '稳定操作类型,用于区分不同接口的幂等作用域',
`message_id` BINARY(16) NOT NULL COMMENT '可靠操作消息身份,跨重连重报时保持稳定',
`request_digest` BINARY(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`response` JSON NOT NULL COMMENT '首次可靠提交后的响应 JSON,供重复请求补取确认',
`expires_at` DATETIME(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_attempt_receipt (namespace_id, attempt_id, operation, message_id),
CONSTRAINT ck_pulse_attempt_receipts_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='执行操作的持久化确认,用于断线或确认丢失后的幂等补取';
CREATE TABLE pulse_concurrency_limits (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`scope_key` VARCHAR(64) NOT NULL COMMENT '资源作用域标识;空字符串表示当前操作的默认作用域',
`key_digest` BINARY(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`max_permits` INT UNSIGNED NOT NULL COMMENT '该共享资源允许占用的许可上限',
`used_permits` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已占用的有效许可数,必须与许可记录同事务维护',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_limit_key (namespace_id, scope_key, key_digest),
CONSTRAINT ck_pulse_concurrency_limits_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_concurrency_limits_1 CHECK (max_permits > 0 AND used_permits <= max_permits)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='跨节点共享的并发限制,实际额度更新必须处于事务内';
CREATE TABLE pulse_permits (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`limit_id` BINARY(16) NOT NULL COMMENT '关联的并发限制记录标识',
`attempt_id` BINARY(16) NOT NULL COMMENT '关联的独立执行尝试标识',
`lease_until` DATETIME(6) NOT NULL COMMENT '已确认的租约截止时间,必须用数据库时间核验',
`released_at` DATETIME(6) NULL COMMENT '许可释放时间;为空表示尚未记录释放',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_permit_attempt (namespace_id, limit_id, attempt_id),
KEY ix_permit_expiry (released_at, lease_until, namespace_id, id),
CONSTRAINT ck_pulse_permits_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次执行尝试占用的并发许可及释放历史';
CREATE TABLE pulse_schedules (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`current_version` BIGINT UNSIGNED NOT NULL COMMENT '当前生效的计划版本号,发布时与版本记录原子更新',
`paused` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`next_fire_at` DATETIME(6) NULL COMMENT '下一计划触发时间;没有后续触发时为空',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_schedule_name (namespace_id, name),
KEY ix_schedule_due (paused, next_fire_at, namespace_id, id),
CONSTRAINT ck_pulse_schedules_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_schedules_1 CHECK (current_version > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='调度计划的当前控制状态,规则内容由不可变版本保存';
CREATE TABLE pulse_schedule_versions (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`schedule_id` BINARY(16) NOT NULL COMMENT '所属调度计划标识',
`version` BIGINT UNSIGNED NOT NULL COMMENT '不可变发布版本;同版本不同内容必须拒绝',
`effective_at` DATETIME(6) NOT NULL COMMENT '该计划版本开始生效的时间',
`timezone` VARCHAR(64) NOT NULL COMMENT '计划计算使用的 IANA 时区名称',
`specification` JSON NOT NULL COMMENT '版本化规则定义 JSON;发布后禁止原地修改',
`task_template` JSON NOT NULL COMMENT '每次触发创建任务时采用的输入与策略模板',
`misfire_policy` VARCHAR(16) NOT NULL COMMENT '漏跑策略:跳过、合并或有界补跑',
`overlap_policy` VARCHAR(16) NOT NULL COMMENT '上次未完成时的策略:并行、串行或跳过',
`catchup_limit` INT UNSIGNED NOT NULL COMMENT '单次漏跑补偿上限;补跑策略必须配置正数',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_schedule_version (namespace_id, schedule_id, version),
CONSTRAINT ck_pulse_schedule_versions_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_schedule_versions_1 CHECK (version > 0),
CONSTRAINT ck_pulse_schedule_versions_2 CHECK (misfire_policy IN ('SKIP', 'COALESCE', 'CATCH_UP')),
CONSTRAINT ck_pulse_schedule_versions_3 CHECK (overlap_policy IN ('PARALLEL', 'SERIAL', 'SKIP')),
CONSTRAINT ck_pulse_schedule_versions_4 CHECK (misfire_policy <> 'CATCH_UP' OR catchup_limit > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已发布的不可变计划版本,记录规则与任务模板';
CREATE TABLE pulse_schedule_occurrences (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`schedule_id` BINARY(16) NOT NULL COMMENT '所属调度计划标识',
`schedule_version` BIGINT UNSIGNED NOT NULL COMMENT '该触发点采用的计划版本号',
`scheduled_at` DATETIME(6) NOT NULL COMMENT '原计划触发时间,统一 UTC;参与触发去重',
`decision` VARCHAR(16) NOT NULL COMMENT '触发处理决定:已触发、已跳过或已合并',
`task_id` BINARY(16) NULL COMMENT '关联的 Pulse 任务标识',
`covered_until` DATETIME(6) NULL COMMENT '合并触发覆盖的结束边界;没有合并范围时为空',
`reason` VARCHAR(1024) NULL COMMENT '操作原因或处理说明,需要保留审计信息',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_occurrence_time (namespace_id, schedule_id, scheduled_at),
UNIQUE KEY uq_occurrence_task (namespace_id, task_id),
CONSTRAINT ck_pulse_schedule_occurrences_0 CHECK (revision > 0),
CONSTRAINT ck_pulse_schedule_occurrences_1 CHECK (decision IN ('FIRED', 'SKIPPED', 'COALESCED')),
CONSTRAINT ck_pulse_schedule_occurrences_2 CHECK ((decision = 'SKIPPED' AND task_id IS NULL) OR (decision IN ('FIRED', 'COALESCED') AND task_id IS NOT NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一个原计划触发点的处理记录,包含触发、跳过或合并决定';
CREATE TABLE weave_definitions (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`name` VARCHAR(128) NOT NULL COMMENT '可读名称,唯一性范围由对应数据表约束',
`description` VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '定义用途说明,不承载运行状态',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_definition_name (namespace_id, name),
CONSTRAINT ck_weave_definitions_0 CHECK (revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='流程定义的稳定身份,不保存可直接执行的业务代码';
CREATE TABLE weave_definition_versions (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`definition_id` BINARY(16) NOT NULL COMMENT '稳定流程定义标识',
`version` VARCHAR(64) NOT NULL COMMENT '不可变发布版本;同版本不同内容必须拒绝',
`schema_version` INT UNSIGNED NOT NULL COMMENT '流程定义文档的结构版本',
`specification` JSON NOT NULL COMMENT '版本化规则定义 JSON;发布后禁止原地修改',
`content_digest` BINARY(32) NOT NULL COMMENT '不可变定义内容的 SHA-256 摘要',
`published_by` VARCHAR(128) NOT NULL COMMENT '发布版本的认证主体,用于追溯发布来源',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_definition_version (namespace_id, definition_id, version),
UNIQUE KEY uq_definition_version_id (namespace_id, definition_id, id),
CONSTRAINT ck_weave_definition_versions_0 CHECK (revision > 0),
CONSTRAINT ck_weave_definition_versions_1 CHECK (schema_version > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已发布的不可变流程定义版本';
CREATE TABLE weave_instances (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`definition_id` BINARY(16) NOT NULL COMMENT '稳定流程定义标识',
`definition_version_id` BINARY(16) NOT NULL COMMENT '实例固定使用的定义版本记录,不能随新版本发布而变化',
`gate_id` BINARY(16) NOT NULL COMMENT '执行门控标识,用于检查是否允许新的领取与开始',
`state` VARCHAR(32) NOT NULL DEFAULT 'RUNNING' COMMENT '流程执行状态,与独立的暂停标记同时展示',
`paused` BOOLEAN NOT NULL DEFAULT FALSE COMMENT '暂停标记;停止新的受控工作,不表示在途请求已停止',
`control_revision` BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '暂停、继续等控制操作的版本,避免旧操作覆盖新决定',
`input` JSON NOT NULL COMMENT '本次实例或步骤激活的输入快照 JSON',
`output` JSON NULL COMMENT '已保存的输出 JSON;未完成时可以为空',
`policy_snapshot` JSON NOT NULL COMMENT '受理时冻结的实际生效策略 JSON',
`business_key` VARCHAR(191) NULL COMMENT '业务侧关联键,用于检索追踪,不自动提供业务幂等',
`deadline_at` DATETIME(6) NOT NULL COMMENT '流程总截止时间,暂停默认不延长此业务边界',
`cancel_requested_at` DATETIME(6) NULL COMMENT '取消意图的持久化时间;不等于取消已完成',
`completed_at` DATETIME(6) NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
`retry_of` BINARY(16) NULL COMMENT '来源记录标识,人工重新发起时用于保留历史关联',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_workflow_gate (namespace_id, gate_id),
KEY ix_workflow_state (namespace_id, state, updated_at, id),
KEY ix_workflow_business (namespace_id, business_key, created_at, id),
CONSTRAINT ck_weave_instances_0 CHECK (revision > 0),
CONSTRAINT ck_weave_instances_1 CHECK (state IN ('RUNNING', 'WAITING', 'CANCELLING', 'NEEDS_REVIEW', 'SUCCEEDED', 'FAILED', 'CANCELLED')),
CONSTRAINT ck_weave_instances_2 CHECK (control_revision > 0),
CONSTRAINT ck_weave_instances_3 CHECK ((state IN ('SUCCEEDED', 'FAILED', 'CANCELLED') AND completed_at IS NOT NULL) OR (state NOT IN ('SUCCEEDED', 'FAILED', 'CANCELLED') AND completed_at IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='流程运行实例,固定定义版本,暂停与执行状态分别保存';
CREATE TABLE weave_steps (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`key` VARCHAR(128) NOT NULL COMMENT '定义中的稳定步骤键,在同一流程实例内唯一',
`kind` VARCHAR(32) NOT NULL COMMENT '节点或等待类型,决定由哪类推进规则处理',
`state` VARCHAR(32) NOT NULL DEFAULT 'BLOCKED' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`current_activation_id` BINARY(16) NULL COMMENT '当前激活记录,必须属于本实例的本步骤',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_step_key (namespace_id, workflow_id, `key`),
UNIQUE KEY uq_step_workflow_id (namespace_id, workflow_id, id),
CONSTRAINT ck_weave_steps_0 CHECK (revision > 0),
CONSTRAINT ck_weave_steps_1 CHECK (state IN ('BLOCKED', 'READY', 'ACTIVE', 'WAITING', 'NEEDS_REVIEW', 'SUCCEEDED', 'FAILED', 'CANCELLED', 'SKIPPED')),
CONSTRAINT ck_weave_steps_2 CHECK (kind IN ('TASK', 'BRANCH', 'PARALLEL', 'JOIN', 'SIGNAL', 'TIMER', 'POLL'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='实例中的逻辑步骤,指向该步骤当前的激活记录';
CREATE TABLE weave_activations (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`step_id` BINARY(16) NOT NULL COMMENT '所属逻辑步骤标识',
`sequence` INT UNSIGNED NOT NULL COMMENT '同一步骤的激活序号,人工恢复递增并保留旧记录',
`state` VARCHAR(32) NOT NULL DEFAULT 'READY' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`task_id` BINARY(16) NULL COMMENT '关联的 Pulse 任务标识',
`input` JSON NOT NULL COMMENT '本次实例或步骤激活的输入快照 JSON',
`output` JSON NULL COMMENT '已保存的输出 JSON;未完成时可以为空',
`completed_at` DATETIME(6) NULL COMMENT '终结时间;非终态为空,进入终态时必须写入',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_activation_sequence (namespace_id, step_id, sequence),
UNIQUE KEY uq_activation_workflow_id (namespace_id, workflow_id, id),
UNIQUE KEY uq_activation_step_id (namespace_id, workflow_id, step_id, id),
UNIQUE KEY uq_activation_task (namespace_id, task_id),
CONSTRAINT ck_weave_activations_0 CHECK (revision > 0),
CONSTRAINT ck_weave_activations_1 CHECK (state IN ('BLOCKED', 'READY', 'ACTIVE', 'WAITING', 'NEEDS_REVIEW', 'SUCCEEDED', 'FAILED', 'CANCELLED', 'SKIPPED')),
CONSTRAINT ck_weave_activations_2 CHECK (sequence > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='步骤的一次具体激活,人工恢复通过新激活保留历史';
CREATE TABLE weave_waits (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` BINARY(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`kind` VARCHAR(16) NOT NULL COMMENT '节点或等待类型,决定由哪类推进规则处理',
`state` VARCHAR(32) NOT NULL DEFAULT 'WAITING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`correlation_key` VARCHAR(191) NOT NULL COMMENT '外部业务操作关联键,防止旧信号误用于新工作',
`deadline_at` DATETIME(6) NOT NULL COMMENT '等待截止时间,用可靠受理时间判断信号是否按时到达',
`wake_task_id` BINARY(16) NULL COMMENT '内部定时唤醒任务;无需定时唤醒时为空',
`resolved_at` DATETIME(6) NULL COMMENT '等待或查询节点结清的时间;尚未结清时为空',
PRIMARY KEY (namespace_id, id),
KEY ix_wait_deadline (state, deadline_at, namespace_id, id),
UNIQUE KEY uq_wait_workflow_id (namespace_id, workflow_id, id),
CONSTRAINT ck_weave_waits_0 CHECK (revision > 0),
CONSTRAINT ck_weave_waits_1 CHECK (state IN ('WAITING', 'SATISFIED', 'EXPIRED', 'CANCELLED')),
CONSTRAINT ck_weave_waits_2 CHECK (kind IN ('SIGNAL', 'TIMER', 'POLL'))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='可恢复的信号或时间等待,不长期占用业务 Worker';
CREATE TABLE weave_signals (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`key_digest` BINARY(32) NOT NULL COMMENT '稳定幂等键或资源键的 SHA-256 摘要',
`request_digest` BINARY(32) NOT NULL COMMENT '规范化请求语义的 SHA-256 摘要,用于识别同键不同内容',
`type` VARCHAR(64) NOT NULL COMMENT '事件或信号的稳定类型标识',
`target_step_key` VARCHAR(128) NOT NULL COMMENT '信号目标步骤键,用于早到信号的后续匹配',
`correlation_key` VARCHAR(191) NOT NULL COMMENT '外部业务操作关联键,防止旧信号误用于新工作',
`payload` JSON NOT NULL COMMENT '版本化输入或事件内容;仅承载通用 JSON,不解释行业规则',
`actor_id` VARCHAR(128) NOT NULL COMMENT '经认证的操作主体标识,不能直接信任请求自报值',
`state` VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`accepted_at` DATETIME(6) NOT NULL COMMENT '信号可靠受理时间,不能用稍后的消费时间替代',
`expires_at` DATETIME(6) NOT NULL COMMENT '过期时间,统一 UTC;到期后的行为由对应资源策略决定',
`consumed_wait_id` BINARY(16) NULL COMMENT '消费该信号的等待记录;尚未消费时为空',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_signal_identity (namespace_id, workflow_id, key_digest),
KEY ix_signal_match (namespace_id, workflow_id, target_step_key, correlation_key, state, accepted_at),
CONSTRAINT ck_weave_signals_0 CHECK (revision > 0),
CONSTRAINT ck_weave_signals_1 CHECK (state IN ('PENDING', 'CONSUMED', 'EXPIRED', 'REJECTED')),
CONSTRAINT ck_weave_signals_2 CHECK ((state = 'CONSUMED' AND consumed_wait_id IS NOT NULL) OR (state <> 'CONSUMED' AND consumed_wait_id IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='已可靠受理的外部信号,受理与消费是两个阶段';
CREATE TABLE weave_poll_states (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` BINARY(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`max_rounds` INT UNSIGNED NOT NULL COMMENT '业务查询最多轮次,不等于单轮请求重试次数',
`used_rounds` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已创建的查询轮次,重启或暂停继续不得重置',
`max_attempts_per_round` INT UNSIGNED NOT NULL COMMENT '每轮 Pulse 任务最多尝试数,包含该轮首次请求',
`interval_ms` BIGINT UNSIGNED NOT NULL COMMENT '相邻业务查询轮次的等待间隔,单位毫秒',
`deadline_at` DATETIME(6) NOT NULL COMMENT '查询节点总截止时间,轮次和单轮重试都受此边界限制',
`next_poll_at` DATETIME(6) NULL COMMENT '最早允许下一轮查询的时间;为空表示当前不能直接推进',
`current_task_id` BINARY(16) NULL COMMENT '当前在途查询任务;非空时禁止重叠开启下一轮',
`resolved_at` DATETIME(6) NULL COMMENT '等待或查询节点结清的时间;尚未结清时为空',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_poll_activation (namespace_id, workflow_id, activation_id),
CONSTRAINT ck_weave_poll_states_0 CHECK (revision > 0),
CONSTRAINT ck_weave_poll_states_1 CHECK (max_rounds > 0 AND used_rounds <= max_rounds),
CONSTRAINT ck_weave_poll_states_2 CHECK (max_attempts_per_round > 0 AND interval_ms > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='有界查询节点的持久化预算与恢复检查点';
CREATE TABLE weave_poll_rounds (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`activation_id` BINARY(16) NOT NULL COMMENT '所属步骤激活,区分旧轮次和人工恢复后的新轮次',
`round` INT UNSIGNED NOT NULL COMMENT '本次激活内的查询轮次编号,从 1 开始',
`task_id` BINARY(16) NOT NULL COMMENT '关联的 Pulse 任务标识',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_poll_round (namespace_id, workflow_id, activation_id, round),
UNIQUE KEY uq_poll_task (namespace_id, task_id),
CONSTRAINT ck_weave_poll_rounds_0 CHECK (revision > 0),
CONSTRAINT ck_weave_poll_rounds_1 CHECK (round > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='一次业务查询轮次,一轮对应一个 Pulse 任务';
CREATE TABLE weave_inbox (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`event_id` BINARY(16) NOT NULL COMMENT '来源持久化事件标识,用于消费去重',
`state` VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '当前状态;只允许定义的状态转换并配合事务校验',
`available_at` DATETIME(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
`lease_owner` BINARY(16) NULL COMMENT '租约持有者标识;未持有租约时为空',
`lease_epoch` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '递增的执行或消费代次,用于隔离旧授权',
`lease_until` DATETIME(6) NULL COMMENT '内部消费租约截止时间;没有消费租约时为空',
`processed_at` DATETIME(6) NULL COMMENT '内部事件完成消费的时间;尚未消费时为空',
`error_code` VARCHAR(64) NULL COMMENT '稳定错误分类,供恢复策略判断;不得写入敏感原始错误',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_inbox_event (namespace_id, event_id),
KEY ix_inbox_due (state, available_at, namespace_id, id),
CONSTRAINT ck_weave_inbox_0 CHECK (revision > 0),
CONSTRAINT ck_weave_inbox_1 CHECK (state IN ('PENDING', 'LEASED', 'PROCESSED', 'QUARANTINED')),
CONSTRAINT ck_weave_inbox_2 CHECK ((state = 'LEASED' AND lease_owner IS NOT NULL AND lease_until IS NOT NULL) OR (state <> 'LEASED' AND lease_owner IS NULL AND lease_until IS NULL))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='Weave 内部事件消费记录,和流程推进一起确认消费';
CREATE TABLE weave_pending_advances (
namespace_id BINARY(16) NOT NULL COMMENT '资源所属命名空间,参与主键、授权与关联校验',
id BINARY(16) NOT NULL COMMENT '记录标识;与命名空间一起定位运行资源',
revision BIGINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '乐观并发版本,从 1 开始;更新时必须核对预期版本',
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '创建时间,统一 UTC,数据库精度为微秒',
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) COMMENT '最后写入时间,统一 UTC;不能代替并发版本',
`workflow_id` BINARY(16) NOT NULL COMMENT '所属流程实例标识',
`step_id` BINARY(16) NOT NULL COMMENT '所属逻辑步骤标识',
`expected_step_revision` BIGINT UNSIGNED NOT NULL COMMENT '恢复推进时要求的步骤版本,避免使用过期检查点',
`checkpoint` JSON NOT NULL COMMENT '分批或暂停后继续推进所需的持久化 JSON 检查点',
`available_at` DATETIME(6) NOT NULL COMMENT '最早可被领取或处理的时间,统一 UTC',
PRIMARY KEY (namespace_id, id),
UNIQUE KEY uq_advance_step (namespace_id, workflow_id, step_id),
KEY ix_advance_due (available_at, namespace_id, id),
CONSTRAINT ck_weave_pending_advances_0 CHECK (revision > 0),
CONSTRAINT ck_weave_pending_advances_1 CHECK (expected_step_revision > 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_as_cs COMMENT='暂停或分批推进后的续接检查点,避免仅依赖内存唤醒';
ALTER TABLE orbit_namespaces ADD CONSTRAINT fk_orbit_namespaces_0
FOREIGN KEY (application_id) REFERENCES orbit_applications (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_credentials ADD CONSTRAINT fk_orbit_credentials_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_idempotency_keys ADD CONSTRAINT fk_orbit_idempotency_keys_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_events ADD CONSTRAINT fk_orbit_events_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_subscriptions ADD CONSTRAINT fk_orbit_subscriptions_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_subscriptions ADD CONSTRAINT fk_orbit_subscriptions_1
FOREIGN KEY (namespace_id, credential_id) REFERENCES orbit_credentials (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_deliveries ADD CONSTRAINT fk_orbit_deliveries_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_deliveries ADD CONSTRAINT fk_orbit_deliveries_1
FOREIGN KEY (namespace_id, subscription_id) REFERENCES orbit_subscriptions (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_deliveries ADD CONSTRAINT fk_orbit_deliveries_2
FOREIGN KEY (namespace_id, event_id) REFERENCES orbit_events (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE orbit_audit_events ADD CONSTRAINT fk_orbit_audit_events_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_queues ADD CONSTRAINT fk_pulse_queues_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_execution_gates ADD CONSTRAINT fk_pulse_execution_gates_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_worker_sessions ADD CONSTRAINT fk_pulse_worker_sessions_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_worker_sessions ADD CONSTRAINT fk_pulse_worker_sessions_1
FOREIGN KEY (namespace_id, credential_id) REFERENCES orbit_credentials (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_tasks ADD CONSTRAINT fk_pulse_tasks_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_tasks ADD CONSTRAINT fk_pulse_tasks_1
FOREIGN KEY (namespace_id, queue_id) REFERENCES pulse_queues (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_tasks ADD CONSTRAINT fk_pulse_tasks_2
FOREIGN KEY (namespace_id, gate_id) REFERENCES pulse_execution_gates (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_tasks ADD CONSTRAINT fk_pulse_tasks_3
FOREIGN KEY (namespace_id, retry_of) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_tasks ADD CONSTRAINT fk_pulse_tasks_4
FOREIGN KEY (namespace_id, id, current_attempt_id) REFERENCES pulse_attempts (namespace_id, task_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_attempts ADD CONSTRAINT fk_pulse_attempts_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_attempts ADD CONSTRAINT fk_pulse_attempts_1
FOREIGN KEY (namespace_id, task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_attempts ADD CONSTRAINT fk_pulse_attempts_2
FOREIGN KEY (namespace_id, session_id) REFERENCES pulse_worker_sessions (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_attempt_receipts ADD CONSTRAINT fk_pulse_attempt_receipts_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_attempt_receipts ADD CONSTRAINT fk_pulse_attempt_receipts_1
FOREIGN KEY (namespace_id, attempt_id) REFERENCES pulse_attempts (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_concurrency_limits ADD CONSTRAINT fk_pulse_concurrency_limits_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_permits ADD CONSTRAINT fk_pulse_permits_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_permits ADD CONSTRAINT fk_pulse_permits_1
FOREIGN KEY (namespace_id, limit_id) REFERENCES pulse_concurrency_limits (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_permits ADD CONSTRAINT fk_pulse_permits_2
FOREIGN KEY (namespace_id, attempt_id) REFERENCES pulse_attempts (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedules ADD CONSTRAINT fk_pulse_schedules_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedule_versions ADD CONSTRAINT fk_pulse_schedule_versions_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedule_versions ADD CONSTRAINT fk_pulse_schedule_versions_1
FOREIGN KEY (namespace_id, schedule_id) REFERENCES pulse_schedules (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedule_occurrences ADD CONSTRAINT fk_pulse_schedule_occurrences_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedule_occurrences ADD CONSTRAINT fk_pulse_schedule_occurrences_1
FOREIGN KEY (namespace_id, schedule_id, schedule_version) REFERENCES pulse_schedule_versions (namespace_id, schedule_id, version) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE pulse_schedule_occurrences ADD CONSTRAINT fk_pulse_schedule_occurrences_2
FOREIGN KEY (namespace_id, task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_definitions ADD CONSTRAINT fk_weave_definitions_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_definition_versions ADD CONSTRAINT fk_weave_definition_versions_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_definition_versions ADD CONSTRAINT fk_weave_definition_versions_1
FOREIGN KEY (namespace_id, definition_id) REFERENCES weave_definitions (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_instances ADD CONSTRAINT fk_weave_instances_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_instances ADD CONSTRAINT fk_weave_instances_1
FOREIGN KEY (namespace_id, definition_id, definition_version_id) REFERENCES weave_definition_versions (namespace_id, definition_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_instances ADD CONSTRAINT fk_weave_instances_2
FOREIGN KEY (namespace_id, gate_id) REFERENCES pulse_execution_gates (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_instances ADD CONSTRAINT fk_weave_instances_3
FOREIGN KEY (namespace_id, retry_of) REFERENCES weave_instances (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_steps ADD CONSTRAINT fk_weave_steps_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_steps ADD CONSTRAINT fk_weave_steps_1
FOREIGN KEY (namespace_id, workflow_id) REFERENCES weave_instances (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_steps ADD CONSTRAINT fk_weave_steps_2
FOREIGN KEY (namespace_id, workflow_id, id, current_activation_id) REFERENCES weave_activations (namespace_id, workflow_id, step_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_activations ADD CONSTRAINT fk_weave_activations_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_activations ADD CONSTRAINT fk_weave_activations_1
FOREIGN KEY (namespace_id, workflow_id, step_id) REFERENCES weave_steps (namespace_id, workflow_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_activations ADD CONSTRAINT fk_weave_activations_2
FOREIGN KEY (namespace_id, task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_waits ADD CONSTRAINT fk_weave_waits_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_waits ADD CONSTRAINT fk_weave_waits_1
FOREIGN KEY (namespace_id, workflow_id, activation_id) REFERENCES weave_activations (namespace_id, workflow_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_waits ADD CONSTRAINT fk_weave_waits_2
FOREIGN KEY (namespace_id, wake_task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_signals ADD CONSTRAINT fk_weave_signals_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_signals ADD CONSTRAINT fk_weave_signals_1
FOREIGN KEY (namespace_id, workflow_id) REFERENCES weave_instances (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_signals ADD CONSTRAINT fk_weave_signals_2
FOREIGN KEY (namespace_id, workflow_id, consumed_wait_id) REFERENCES weave_waits (namespace_id, workflow_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_states ADD CONSTRAINT fk_weave_poll_states_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_states ADD CONSTRAINT fk_weave_poll_states_1
FOREIGN KEY (namespace_id, workflow_id, activation_id) REFERENCES weave_activations (namespace_id, workflow_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_states ADD CONSTRAINT fk_weave_poll_states_2
FOREIGN KEY (namespace_id, current_task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_rounds ADD CONSTRAINT fk_weave_poll_rounds_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_rounds ADD CONSTRAINT fk_weave_poll_rounds_1
FOREIGN KEY (namespace_id, workflow_id, activation_id) REFERENCES weave_poll_states (namespace_id, workflow_id, activation_id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_poll_rounds ADD CONSTRAINT fk_weave_poll_rounds_2
FOREIGN KEY (namespace_id, task_id) REFERENCES pulse_tasks (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_inbox ADD CONSTRAINT fk_weave_inbox_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_inbox ADD CONSTRAINT fk_weave_inbox_1
FOREIGN KEY (namespace_id, workflow_id) REFERENCES weave_instances (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_inbox ADD CONSTRAINT fk_weave_inbox_2
FOREIGN KEY (namespace_id, event_id) REFERENCES orbit_events (namespace_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_pending_advances ADD CONSTRAINT fk_weave_pending_advances_0
FOREIGN KEY (namespace_id) REFERENCES orbit_namespaces (id) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE weave_pending_advances ADD CONSTRAINT fk_weave_pending_advances_1
FOREIGN KEY (namespace_id, workflow_id, step_id) REFERENCES weave_steps (namespace_id, workflow_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT;
-- Published versions and event history are append-only. Retention deletes require
-- a separate administrative identity and must respect active references.
CREATE TRIGGER trg_definition_version_immutable BEFORE UPDATE ON weave_definition_versions
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Published workflow versions are immutable';
CREATE TRIGGER trg_schedule_version_immutable BEFORE UPDATE ON pulse_schedule_versions
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Published schedule versions are immutable';
CREATE TRIGGER trg_audit_event_immutable BEFORE UPDATE ON orbit_audit_events
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Audit events are append-only';
CREATE TRIGGER trg_event_immutable BEFORE UPDATE ON orbit_events
FOR EACH ROW SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'State events are append-only';