refactor(schema): 迁移 043 schema 收敛——42→19 张表,统一迁移 runner
- 迁移 043 一次到位:runtime_instance/environment_binding 并入 browser_env(账号即环境)、 credential_reference 并入 social_account、work_source/metric_plan 并入 creator_work、 sync 租约并入 creator_collection_checkpoint(kind='sync')、audit_event 瘦列、 creator_settings 去转写列、TRUNCATE 账号域(竞品采集数据无损保留) - 统一迁移 runner:environment.Open 串起 001 账号基座 + hub 链 + 038 creator 版本回填 (v+1000) + creator 1017-1042 + 043;account/creator Open 不再迁移 - 三域 store SQL 全量适配:CreateBoundEnv 就绪门禁、SetRuntimeCleanupPending fence 语义(未知代 MissingRuntimeID 允许登记并释放活跃实例)、metric_plan 列并入 work、 checkpoint sync 租约、deletion 链路重写 - api 适配:envView 去 runtime_instance_id、audit filter 去任务列、browser_env 单表查询 - 测试:迁移 043 形态探针、迁移不可变映射新路径、legacy 迁移重放子测试重写、 fence/出口生命周期/单来源 upsert 语义覆盖;CREATORHUB_POSTGRES_TEST_URL 全绿, environment 70%/creator 67.5% 覆盖率,tsc 通过
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
CREATE TABLE credential_reference (
|
||||
id text PRIMARY KEY,
|
||||
provider text NOT NULL CHECK (provider IN ('os_keyring', 'secret_manager')),
|
||||
reference_key text NOT NULL UNIQUE,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE social_account (
|
||||
id text PRIMARY KEY CHECK (id ~ '^[a-z0-9][a-z0-9-]{0,31}$'),
|
||||
credential_reference_id text NOT NULL UNIQUE REFERENCES credential_reference(id),
|
||||
profile_id text NOT NULL UNIQUE,
|
||||
version bigint NOT NULL DEFAULT 1 CHECK (version > 0),
|
||||
status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'paused')),
|
||||
paused_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE runtime_instance (
|
||||
id text PRIMARY KEY,
|
||||
account_id text NOT NULL REFERENCES social_account(id),
|
||||
runtime_id text NOT NULL,
|
||||
acquired_at timestamptz NOT NULL DEFAULT now(),
|
||||
lease_until timestamptz NOT NULL,
|
||||
released_at timestamptz
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX one_active_runtime_per_account
|
||||
ON runtime_instance (account_id) WHERE released_at IS NULL;
|
||||
CREATE UNIQUE INDEX one_account_per_active_runtime
|
||||
ON runtime_instance (runtime_id) WHERE released_at IS NULL;
|
||||
|
||||
CREATE TABLE content_draft (
|
||||
id text PRIMARY KEY,
|
||||
account_id text NOT NULL REFERENCES social_account(id),
|
||||
version bigint NOT NULL CHECK (version > 0),
|
||||
content text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE confirmation (
|
||||
id text PRIMARY KEY,
|
||||
account_id text NOT NULL REFERENCES social_account(id),
|
||||
account_version bigint NOT NULL CHECK (account_version > 0),
|
||||
draft_id text NOT NULL REFERENCES content_draft(id),
|
||||
draft_version bigint NOT NULL CHECK (draft_version > 0),
|
||||
version bigint NOT NULL CHECK (version > 0),
|
||||
confirmed_by text NOT NULL DEFAULT 'local-user' CHECK (confirmed_by = 'local-user'),
|
||||
confirmed_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE operation_task (
|
||||
id text PRIMARY KEY,
|
||||
idempotency_key text NOT NULL UNIQUE,
|
||||
account_id text NOT NULL REFERENCES social_account(id),
|
||||
account_version bigint NOT NULL CHECK (account_version > 0),
|
||||
draft_id text NOT NULL REFERENCES content_draft(id),
|
||||
draft_version bigint NOT NULL CHECK (draft_version > 0),
|
||||
confirmation_id text REFERENCES confirmation(id),
|
||||
confirmation_version bigint CHECK (confirmation_version > 0),
|
||||
state text NOT NULL DEFAULT 'queued' CHECK (state IN (
|
||||
'queued', 'executing', 'succeeded', 'failed',
|
||||
'needs_confirmation', 'policy_hold', 'cancelled'
|
||||
)),
|
||||
lease_owner text,
|
||||
lease_until timestamptz,
|
||||
current_attempt_id text,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
CHECK ((confirmation_id IS NULL) = (confirmation_version IS NULL))
|
||||
);
|
||||
|
||||
CREATE TABLE execution_attempt (
|
||||
id text PRIMARY KEY,
|
||||
task_id text NOT NULL UNIQUE REFERENCES operation_task(id),
|
||||
started_at timestamptz NOT NULL DEFAULT now(),
|
||||
finished_at timestamptz,
|
||||
outcome text CHECK (outcome IN ('succeeded', 'failed', 'uncertain', 'policy_hold')),
|
||||
result jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
ALTER TABLE operation_task
|
||||
ADD CONSTRAINT operation_task_current_attempt_fk
|
||||
FOREIGN KEY (current_attempt_id) REFERENCES execution_attempt(id);
|
||||
|
||||
CREATE TABLE audit_event (
|
||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
event_type text NOT NULL,
|
||||
account_id text REFERENCES social_account(id),
|
||||
confirmation_id text REFERENCES confirmation(id),
|
||||
confirmation_version bigint,
|
||||
attempt_id text REFERENCES execution_attempt(id),
|
||||
task_id text REFERENCES operation_task(id),
|
||||
details jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE FUNCTION reject_audit_event_mutation() RETURNS trigger
|
||||
LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
RAISE EXCEPTION 'audit_event is append-only';
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE TRIGGER audit_event_append_only
|
||||
BEFORE UPDATE OR DELETE ON audit_event
|
||||
FOR EACH ROW EXECUTE FUNCTION reject_audit_event_mutation();
|
||||
Reference in New Issue
Block a user