dc9e827656
build / build (push) Failing after 17s
- 新增 library_versions:测试封存、生产生效、生产预备份三类分开登记,
生产生效版本唯一(旧版本必须先 supersede),测试快照不能顶替生产版本
- 新增 library_jobs + library_job_stages:业务作业身份、阶段、错误与恢复说明,
分项计数用 NULL 表示"总量未知";互斥与幂等由数据库唯一索引保证
- 新增 GET /api/v1/library/overview、/jobs、/jobs/{id};POST /syncs 闸口未齐
返回 503 缺项且不建作业
- 封存作业落库:先建业务作业再入队,worker 推进 export 阶段并登记 test_sealed
- 发布管理读真实状态:生产未知不再顶替、差异 unknown、启动同步按缺项禁用、
同步明细/四类分项来自持久阶段;阶段勾选只认当前作业证据
- 准备信息标注封存时间与范围,不声称实时测试库已就绪
57 lines
2.9 KiB
SQL
57 lines
2.9 KiB
SQL
-- 整库版本与作业:把"测试封存 / 生产生效 / 生产预备份"三种版本与持久作业分开记录。
|
|
-- 现有 jobs 表是队列与租约;这里记录业务身份、阶段与结果,重启后仍可读。
|
|
CREATE TABLE library_versions (
|
|
id VARCHAR(64) PRIMARY KEY,
|
|
scope VARCHAR(16) NOT NULL CHECK (scope IN ('internal','external')),
|
|
kind VARCHAR(24) NOT NULL CHECK (kind IN ('test_sealed','production_effective','production_prebackup')),
|
|
snapshot_id VARCHAR(64) NOT NULL DEFAULT '',
|
|
version_label VARCHAR(64) NOT NULL DEFAULT '',
|
|
source_job_id VARCHAR(64) NOT NULL DEFAULT '',
|
|
evidence JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
created_by VARCHAR(128) NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL,
|
|
superseded_at TIMESTAMPTZ
|
|
);
|
|
CREATE INDEX library_versions_scope_kind ON library_versions(scope, kind, created_at DESC, id DESC);
|
|
-- 每个目标只有一个"当前生产生效版本";写入新版本时旧的必须先被 supersede。
|
|
CREATE UNIQUE INDEX library_versions_effective ON library_versions(scope)
|
|
WHERE kind = 'production_effective' AND superseded_at IS NULL;
|
|
|
|
CREATE TABLE library_jobs (
|
|
id VARCHAR(64) PRIMARY KEY,
|
|
scope VARCHAR(16) NOT NULL CHECK (scope IN ('internal','external')),
|
|
kind VARCHAR(16) NOT NULL CHECK (kind IN ('seal','sync')),
|
|
state VARCHAR(16) NOT NULL CHECK (state IN ('pending','running','succeeded','failed','cancelled')),
|
|
stage VARCHAR(32) NOT NULL DEFAULT '',
|
|
idempotency_key VARCHAR(255) NOT NULL,
|
|
request_digest VARCHAR(64) NOT NULL,
|
|
request JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
queue_job_id VARCHAR(64) NOT NULL DEFAULT '',
|
|
snapshot_id VARCHAR(64) NOT NULL DEFAULT '',
|
|
target_snapshot_id VARCHAR(64) NOT NULL DEFAULT '',
|
|
actor VARCHAR(128) NOT NULL DEFAULT '',
|
|
error TEXT NOT NULL DEFAULT '',
|
|
recovery VARCHAR(255) NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL,
|
|
updated_at TIMESTAMPTZ NOT NULL,
|
|
finished_at TIMESTAMPTZ
|
|
);
|
|
CREATE UNIQUE INDEX library_jobs_idempotency ON library_jobs(idempotency_key);
|
|
-- 同一目标同一类作业只能有一个在飞:互斥由数据库保证,不依赖前端或单 worker 部署。
|
|
CREATE UNIQUE INDEX library_jobs_active ON library_jobs(scope, kind)
|
|
WHERE state IN ('pending','running');
|
|
CREATE INDEX library_jobs_recent ON library_jobs(scope, created_at DESC, id DESC);
|
|
|
|
CREATE TABLE library_job_stages (
|
|
job_id VARCHAR(64) NOT NULL REFERENCES library_jobs(id) ON DELETE CASCADE,
|
|
stage VARCHAR(32) NOT NULL,
|
|
state VARCHAR(16) NOT NULL DEFAULT 'pending' CHECK (state IN ('pending','running','succeeded','failed','skipped')),
|
|
-- NULL 表示"总量未知":绝不能当成 0,也不据此算百分比。
|
|
total BIGINT,
|
|
completed BIGINT,
|
|
bytes_total BIGINT,
|
|
bytes_done BIGINT,
|
|
detail TEXT NOT NULL DEFAULT '',
|
|
updated_at TIMESTAMPTZ NOT NULL,
|
|
PRIMARY KEY (job_id, stage)
|
|
); |