将 P1R-4 AI 41 个 operation 推进到 dedicated / needs_verification,退役 AI contract fallback,并补齐 runtime、SSE、job、audit、source、coverage 与 PostgreSQL/Flyway 门禁。 保留 completedOperations=0;真实 New-API chat、Security owner、Knowledge/RAGFlow、Market 和统一 events 仍留在后续验收。
559 lines
23 KiB
SQL
559 lines
23 KiB
SQL
-- P1R-4 AI Real API 扩展 Schema。
|
||
-- 说明:本迁移只追加 AI owner 自有事实;New-API、Security、Content、Meta、Knowledge、Market 主流程不在此处伪造。
|
||
|
||
CREATE TABLE muse_ai_command (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
command_id VARCHAR(128) NOT NULL,
|
||
operation_id VARCHAR(128) NOT NULL,
|
||
actor_user_id BIGINT NOT NULL,
|
||
owner_user_id BIGINT NOT NULL,
|
||
target_type VARCHAR(64) NOT NULL,
|
||
target_id BIGINT,
|
||
target_key VARCHAR(160) NOT NULL,
|
||
request_hash CHAR(64) NOT NULL,
|
||
result_snapshot JSONB,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_command UNIQUE (tenant_id, command_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_command_target
|
||
ON muse_ai_command(tenant_id, target_type, target_key);
|
||
CREATE TRIGGER trg_muse_ai_command_updated_at
|
||
BEFORE UPDATE ON muse_ai_command
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
ALTER TABLE muse_ai_generation
|
||
ADD COLUMN IF NOT EXISTS command_id VARCHAR(128),
|
||
ADD COLUMN IF NOT EXISTS request_hash CHAR(64),
|
||
ADD COLUMN IF NOT EXISTS job_id VARCHAR(128),
|
||
ADD COLUMN IF NOT EXISTS correlation_id VARCHAR(200),
|
||
ADD COLUMN IF NOT EXISTS source_snapshot_id VARCHAR(128),
|
||
ADD COLUMN IF NOT EXISTS runtime_permission_envelope_id VARCHAR(128),
|
||
ADD COLUMN IF NOT EXISTS owner_user_id BIGINT,
|
||
ADD COLUMN IF NOT EXISTS runtime_status VARCHAR(32),
|
||
ADD COLUMN IF NOT EXISTS runtime_summary JSONB,
|
||
ADD COLUMN IF NOT EXISTS source_summary JSONB,
|
||
ADD COLUMN IF NOT EXISTS runtime_permission_summary JSONB;
|
||
|
||
CREATE UNIQUE INDEX uk_muse_ai_generation_command
|
||
ON muse_ai_generation(tenant_id, command_id)
|
||
WHERE command_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_generation_owner_status
|
||
ON muse_ai_generation(tenant_id, owner_user_id, status, create_time)
|
||
WHERE owner_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_generation_job
|
||
ON muse_ai_generation(tenant_id, job_id)
|
||
WHERE job_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_generation_correlation
|
||
ON muse_ai_generation(tenant_id, correlation_id)
|
||
WHERE correlation_id IS NOT NULL;
|
||
|
||
CREATE TABLE muse_ai_runtime_call (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
correlation_id VARCHAR(200) NOT NULL,
|
||
task_id VARCHAR(128) NOT NULL,
|
||
job_id VARCHAR(128) NOT NULL,
|
||
command_id VARCHAR(128),
|
||
operation_id VARCHAR(128) NOT NULL,
|
||
actor_user_id BIGINT NOT NULL,
|
||
owner_user_id BIGINT NOT NULL,
|
||
target_type VARCHAR(64) NOT NULL,
|
||
target_id BIGINT,
|
||
target_key VARCHAR(160) NOT NULL,
|
||
attempt_no INT NOT NULL DEFAULT 1,
|
||
model_key VARCHAR(128),
|
||
prompt_template_version VARCHAR(80),
|
||
status VARCHAR(32) NOT NULL,
|
||
request_hash CHAR(64),
|
||
request_summary JSONB,
|
||
response_summary JSONB,
|
||
usage_summary JSONB,
|
||
cost_cents BIGINT,
|
||
provider_request_id VARCHAR(200),
|
||
failure_type VARCHAR(64),
|
||
provider_status_code INT,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
retryable BOOLEAN NOT NULL DEFAULT FALSE,
|
||
next_retry_at TIMESTAMP,
|
||
started_at TIMESTAMP,
|
||
finished_at TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_runtime_call_attempt UNIQUE (tenant_id, correlation_id, attempt_no)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_runtime_call_owner_status
|
||
ON muse_ai_runtime_call(tenant_id, owner_user_id, status, create_time);
|
||
CREATE INDEX idx_muse_ai_runtime_call_task
|
||
ON muse_ai_runtime_call(tenant_id, task_id, attempt_no);
|
||
CREATE INDEX idx_muse_ai_runtime_call_job
|
||
ON muse_ai_runtime_call(tenant_id, job_id, attempt_no);
|
||
CREATE TRIGGER trg_muse_ai_runtime_call_updated_at
|
||
BEFORE UPDATE ON muse_ai_runtime_call
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_task_event (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
task_id VARCHAR(128) NOT NULL,
|
||
sequence_no BIGINT NOT NULL,
|
||
event_type VARCHAR(40) NOT NULL,
|
||
task_status VARCHAR(32) NOT NULL,
|
||
owner_user_id BIGINT NOT NULL,
|
||
actor_user_id BIGINT,
|
||
job_id VARCHAR(128),
|
||
correlation_id VARCHAR(200),
|
||
payload_summary JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
emitted_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_task_event_sequence UNIQUE (tenant_id, task_id, sequence_no)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_task_event_owner_status
|
||
ON muse_ai_task_event(tenant_id, owner_user_id, task_status, create_time);
|
||
CREATE UNIQUE INDEX uk_muse_ai_task_event_terminal
|
||
ON muse_ai_task_event(tenant_id, task_id)
|
||
WHERE event_type IN ('done', 'error');
|
||
CREATE INDEX idx_muse_ai_task_event_job
|
||
ON muse_ai_task_event(tenant_id, job_id, sequence_no)
|
||
WHERE job_id IS NOT NULL;
|
||
CREATE TRIGGER trg_muse_ai_task_event_updated_at
|
||
BEFORE UPDATE ON muse_ai_task_event
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_job (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
job_id VARCHAR(128) NOT NULL,
|
||
job_type VARCHAR(64) NOT NULL,
|
||
task_id VARCHAR(128),
|
||
command_id VARCHAR(128),
|
||
request_hash CHAR(64),
|
||
operation_id VARCHAR(128) NOT NULL,
|
||
actor_user_id BIGINT NOT NULL,
|
||
owner_user_id BIGINT NOT NULL,
|
||
work_id BIGINT,
|
||
status VARCHAR(32) NOT NULL,
|
||
retry_count INT NOT NULL DEFAULT 0,
|
||
retryable BOOLEAN NOT NULL DEFAULT FALSE,
|
||
retry_group_id VARCHAR(128),
|
||
next_retry_at TIMESTAMP,
|
||
source_snapshot_id VARCHAR(128),
|
||
runtime_permission_envelope_id VARCHAR(128),
|
||
correlation_id VARCHAR(200),
|
||
input_summary JSONB,
|
||
result_summary JSONB,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
started_at TIMESTAMP,
|
||
finished_at TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_job UNIQUE (tenant_id, job_id),
|
||
CONSTRAINT uk_muse_ai_job_command UNIQUE (tenant_id, command_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_job_owner_status
|
||
ON muse_ai_job(tenant_id, owner_user_id, status, create_time);
|
||
CREATE INDEX idx_muse_ai_job_work_status
|
||
ON muse_ai_job(tenant_id, work_id, status, create_time)
|
||
WHERE work_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_job_retry_group
|
||
ON muse_ai_job(tenant_id, retry_group_id, create_time)
|
||
WHERE retry_group_id IS NOT NULL;
|
||
CREATE UNIQUE INDEX uk_muse_ai_job_active_retry_group
|
||
ON muse_ai_job(tenant_id, retry_group_id)
|
||
WHERE retry_group_id IS NOT NULL
|
||
AND operation_id = 'adminRetryJob'
|
||
AND status IN ('queued', 'running', 'streaming')
|
||
AND deleted = FALSE;
|
||
CREATE TRIGGER trg_muse_ai_job_updated_at
|
||
BEFORE UPDATE ON muse_ai_job
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_source_event (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
source_event_id VARCHAR(128) NOT NULL,
|
||
source_owner VARCHAR(64) NOT NULL,
|
||
source_type VARCHAR(64) NOT NULL,
|
||
source_id VARCHAR(128) NOT NULL,
|
||
source_revision VARCHAR(80),
|
||
owner_user_id BIGINT NOT NULL,
|
||
work_id BIGINT,
|
||
status VARCHAR(32) NOT NULL DEFAULT 'blocked',
|
||
action_policy VARCHAR(64) NOT NULL DEFAULT 'blocked',
|
||
command_id VARCHAR(128),
|
||
job_id VARCHAR(128),
|
||
event_summary JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_source_event UNIQUE (tenant_id, source_event_id),
|
||
CONSTRAINT chk_muse_ai_source_event_status
|
||
CHECK (status IN ('active', 'stale', 'revoked', 'recalled', 'delisted', 'blocked', 'owner_missing', 'unauthorized')),
|
||
CONSTRAINT chk_muse_ai_source_event_action_policy
|
||
CHECK (action_policy IN ('allowed', 'read_only', 'blocked', 'needs_recheck'))
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_source_event_owner_status
|
||
ON muse_ai_source_event(tenant_id, owner_user_id, status, create_time);
|
||
CREATE INDEX idx_muse_ai_source_event_admin_list
|
||
ON muse_ai_source_event(tenant_id, source_type, status, create_time);
|
||
CREATE INDEX idx_muse_ai_source_event_source
|
||
ON muse_ai_source_event(tenant_id, source_owner, source_type, source_id, create_time);
|
||
CREATE TRIGGER trg_muse_ai_source_event_updated_at
|
||
BEFORE UPDATE ON muse_ai_source_event
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_source_status_projection (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
source_owner VARCHAR(64) NOT NULL,
|
||
source_type VARCHAR(64) NOT NULL,
|
||
source_id VARCHAR(128) NOT NULL,
|
||
source_revision VARCHAR(80),
|
||
owner_user_id BIGINT NOT NULL,
|
||
work_id BIGINT,
|
||
status VARCHAR(32) NOT NULL DEFAULT 'blocked',
|
||
action_policy VARCHAR(64) NOT NULL DEFAULT 'blocked',
|
||
last_event_id VARCHAR(128),
|
||
status_summary JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||
checked_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_source_status UNIQUE (tenant_id, owner_user_id, source_owner, source_type, source_id),
|
||
CONSTRAINT chk_muse_ai_source_status_projection_status
|
||
CHECK (status IN ('active', 'stale', 'revoked', 'recalled', 'delisted', 'blocked', 'owner_missing', 'unauthorized')),
|
||
CONSTRAINT chk_muse_ai_source_status_projection_action_policy
|
||
CHECK (action_policy IN ('allowed', 'read_only', 'blocked', 'needs_recheck'))
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_source_status_owner_status
|
||
ON muse_ai_source_status_projection(tenant_id, owner_user_id, status, create_time);
|
||
CREATE INDEX idx_muse_ai_source_status_work
|
||
ON muse_ai_source_status_projection(tenant_id, work_id, status, create_time)
|
||
WHERE work_id IS NOT NULL;
|
||
CREATE TRIGGER trg_muse_ai_source_status_updated_at
|
||
BEFORE UPDATE ON muse_ai_source_status_projection
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_agent_slot_precheck (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
precheck_id VARCHAR(128) NOT NULL,
|
||
command_id VARCHAR(128) NOT NULL,
|
||
request_hash CHAR(64) NOT NULL,
|
||
work_id BIGINT NOT NULL,
|
||
slot_key VARCHAR(160) NOT NULL,
|
||
source_agent_id BIGINT NOT NULL,
|
||
source_agent_version INT NOT NULL,
|
||
expected_slot_revision INT,
|
||
authorization_snapshot_id VARCHAR(128),
|
||
status VARCHAR(32) NOT NULL,
|
||
expires_at TIMESTAMP NOT NULL,
|
||
consumed_at TIMESTAMP,
|
||
result_summary JSONB,
|
||
owner_user_id BIGINT NOT NULL,
|
||
actor_user_id BIGINT NOT NULL,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_agent_slot_precheck_id UNIQUE (tenant_id, precheck_id),
|
||
CONSTRAINT uk_muse_ai_agent_slot_precheck_command UNIQUE (tenant_id, command_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_agent_slot_precheck_work_slot_status
|
||
ON muse_ai_agent_slot_precheck(tenant_id, work_id, slot_key, status);
|
||
CREATE INDEX idx_muse_ai_agent_slot_precheck_owner_status
|
||
ON muse_ai_agent_slot_precheck(tenant_id, owner_user_id, status, expires_at);
|
||
CREATE TRIGGER trg_muse_ai_agent_slot_precheck_updated_at
|
||
BEFORE UPDATE ON muse_ai_agent_slot_precheck
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_suggestion_decision (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
suggestion_id BIGINT NOT NULL,
|
||
decision_id VARCHAR(128) NOT NULL,
|
||
decision VARCHAR(32) NOT NULL,
|
||
reason_code VARCHAR(64),
|
||
owner_user_id BIGINT NOT NULL,
|
||
actor_user_id BIGINT NOT NULL,
|
||
work_id BIGINT,
|
||
command_id VARCHAR(128) NOT NULL,
|
||
request_hash CHAR(64) NOT NULL,
|
||
decision_summary JSONB,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_suggestion_decision UNIQUE (tenant_id, decision_id),
|
||
CONSTRAINT uk_muse_ai_suggestion_decision_command UNIQUE (tenant_id, command_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_suggestion_decision_owner
|
||
ON muse_ai_suggestion_decision(tenant_id, owner_user_id, create_time);
|
||
CREATE INDEX idx_muse_ai_suggestion_decision_suggestion
|
||
ON muse_ai_suggestion_decision(tenant_id, suggestion_id, create_time);
|
||
CREATE TRIGGER trg_muse_ai_suggestion_decision_updated_at
|
||
BEFORE UPDATE ON muse_ai_suggestion_decision
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_evaluation_run (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
run_id VARCHAR(128) NOT NULL,
|
||
policy_key VARCHAR(100) NOT NULL,
|
||
policy_version_no INT,
|
||
job_id VARCHAR(128),
|
||
command_id VARCHAR(128),
|
||
actor_user_id BIGINT NOT NULL,
|
||
owner_user_id BIGINT,
|
||
status VARCHAR(32) NOT NULL,
|
||
sample_count INT NOT NULL DEFAULT 0,
|
||
passed_count INT NOT NULL DEFAULT 0,
|
||
failed_count INT NOT NULL DEFAULT 0,
|
||
metric_summary JSONB,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
started_at TIMESTAMP,
|
||
finished_at TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_evaluation_run UNIQUE (tenant_id, run_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_evaluation_run_owner_status
|
||
ON muse_ai_evaluation_run(tenant_id, owner_user_id, status, create_time)
|
||
WHERE owner_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_evaluation_run_policy
|
||
ON muse_ai_evaluation_run(tenant_id, policy_key, create_time);
|
||
CREATE TRIGGER trg_muse_ai_evaluation_run_updated_at
|
||
BEFORE UPDATE ON muse_ai_evaluation_run
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_ai_evaluation_sample_result (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
run_id VARCHAR(128) NOT NULL,
|
||
sample_id VARCHAR(128) NOT NULL,
|
||
owner_user_id BIGINT,
|
||
status VARCHAR(32) NOT NULL,
|
||
score NUMERIC(10, 4),
|
||
metric_summary JSONB,
|
||
input_summary JSONB,
|
||
output_summary JSONB,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_ai_evaluation_sample UNIQUE (tenant_id, run_id, sample_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_ai_evaluation_sample_owner_status
|
||
ON muse_ai_evaluation_sample_result(tenant_id, owner_user_id, status, create_time)
|
||
WHERE owner_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_ai_evaluation_sample_run
|
||
ON muse_ai_evaluation_sample_result(tenant_id, run_id, create_time);
|
||
CREATE TRIGGER trg_muse_ai_evaluation_sample_updated_at
|
||
BEFORE UPDATE ON muse_ai_evaluation_sample_result
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_api_access_log_projection (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
access_id VARCHAR(128) NOT NULL,
|
||
operation_id VARCHAR(128) NOT NULL,
|
||
actor_user_id BIGINT,
|
||
owner_user_id BIGINT,
|
||
side VARCHAR(32) NOT NULL,
|
||
method VARCHAR(16) NOT NULL,
|
||
path VARCHAR(300) NOT NULL,
|
||
status_code INT,
|
||
business_code INT,
|
||
command_id VARCHAR(128),
|
||
correlation_id VARCHAR(200),
|
||
request_summary JSONB,
|
||
response_summary JSONB,
|
||
sanitized_client_ip_hash CHAR(64),
|
||
duration_ms BIGINT,
|
||
occurred_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||
CONSTRAINT uk_muse_api_access_log UNIQUE (tenant_id, access_id)
|
||
);
|
||
|
||
CREATE INDEX idx_muse_api_access_log_owner
|
||
ON muse_api_access_log_projection(tenant_id, owner_user_id, occurred_at)
|
||
WHERE owner_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_api_access_log_tenant_time
|
||
ON muse_api_access_log_projection(tenant_id, occurred_at);
|
||
CREATE INDEX idx_muse_api_access_log_actor_time
|
||
ON muse_api_access_log_projection(tenant_id, actor_user_id, occurred_at)
|
||
WHERE actor_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_api_access_log_operation
|
||
ON muse_api_access_log_projection(tenant_id, operation_id, occurred_at);
|
||
CREATE TRIGGER trg_muse_api_access_log_updated_at
|
||
BEFORE UPDATE ON muse_api_access_log_projection
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
CREATE TABLE muse_business_audit_event (
|
||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||
operation_id VARCHAR(128) NOT NULL,
|
||
actor_user_id BIGINT,
|
||
owner_user_id BIGINT,
|
||
side VARCHAR(32) NOT NULL,
|
||
target_type VARCHAR(64) NOT NULL,
|
||
target_id BIGINT,
|
||
command_id VARCHAR(128),
|
||
request_hash CHAR(64),
|
||
correlation_id VARCHAR(200),
|
||
request_summary JSONB,
|
||
response_summary JSONB,
|
||
risk_summary JSONB,
|
||
status VARCHAR(32) NOT NULL,
|
||
error_code VARCHAR(64),
|
||
error_message TEXT,
|
||
creator VARCHAR(64) NOT NULL DEFAULT '',
|
||
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
updater VARCHAR(64) NOT NULL DEFAULT '',
|
||
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||
tenant_id BIGINT NOT NULL DEFAULT 0
|
||
);
|
||
|
||
CREATE INDEX idx_muse_business_audit_owner
|
||
ON muse_business_audit_event(tenant_id, owner_user_id, create_time)
|
||
WHERE owner_user_id IS NOT NULL;
|
||
CREATE INDEX idx_muse_business_audit_tenant_time
|
||
ON muse_business_audit_event(tenant_id, create_time);
|
||
CREATE INDEX idx_muse_business_audit_operation
|
||
ON muse_business_audit_event(tenant_id, operation_id, create_time);
|
||
CREATE INDEX idx_muse_business_audit_correlation
|
||
ON muse_business_audit_event(tenant_id, correlation_id)
|
||
WHERE correlation_id IS NOT NULL;
|
||
CREATE TRIGGER trg_muse_business_audit_updated_at
|
||
BEFORE UPDATE ON muse_business_audit_event
|
||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||
|
||
-- WHY:历史环境可能已经因为缺少 partial unique index 而存在同一 Prompt 多个 active 版本;
|
||
-- 父表 muse_prompt.active_version 是既有线上指针,优先保留它指向的 active 行,避免迁移把业务正在使用的版本误降级。
|
||
WITH ranked_prompt_active AS (
|
||
SELECT version.id,
|
||
ROW_NUMBER() OVER (
|
||
PARTITION BY version.tenant_id, version.prompt_key
|
||
ORDER BY CASE WHEN prompt.active_version = version.version THEN 0 ELSE 1 END,
|
||
version.update_time DESC, version.create_time DESC, version.id DESC
|
||
) AS rn
|
||
FROM muse_prompt_version version
|
||
LEFT JOIN muse_prompt prompt
|
||
ON prompt.tenant_id = version.tenant_id
|
||
AND prompt.prompt_key = version.prompt_key
|
||
AND prompt.deleted = FALSE
|
||
WHERE version.status = 'active' AND version.deleted = FALSE
|
||
)
|
||
UPDATE muse_prompt_version version
|
||
SET status = 'draft',
|
||
update_time = CURRENT_TIMESTAMP
|
||
FROM ranked_prompt_active duplicate
|
||
WHERE version.id = duplicate.id
|
||
AND duplicate.rn > 1;
|
||
|
||
WITH kept_prompt_active AS (
|
||
SELECT tenant_id, prompt_key, version
|
||
FROM muse_prompt_version
|
||
WHERE status = 'active' AND deleted = FALSE
|
||
)
|
||
UPDATE muse_prompt prompt
|
||
SET active_version = kept.version,
|
||
update_time = CURRENT_TIMESTAMP
|
||
FROM kept_prompt_active kept
|
||
WHERE prompt.tenant_id = kept.tenant_id
|
||
AND prompt.prompt_key = kept.prompt_key
|
||
AND prompt.deleted = FALSE
|
||
AND prompt.active_version IS DISTINCT FROM kept.version;
|
||
|
||
CREATE UNIQUE INDEX uk_muse_prompt_version_active
|
||
ON muse_prompt_version(tenant_id, prompt_key)
|
||
WHERE status = 'active' AND deleted = FALSE;
|
||
|
||
-- WHY:历史环境可能已经因为缺少 partial unique index 而存在同一质量策略多个 active 版本;
|
||
-- 父表 muse_quality_policy.active_version 存 varchar,而 version 表是 int,必须按 version_no::text 优先保留父表指向版本。
|
||
WITH ranked_quality_policy_active AS (
|
||
SELECT version.id,
|
||
ROW_NUMBER() OVER (
|
||
PARTITION BY version.tenant_id, version.policy_key
|
||
ORDER BY CASE WHEN policy.active_version = version.version_no::text THEN 0 ELSE 1 END,
|
||
version.update_time DESC, version.create_time DESC, version.id DESC
|
||
) AS rn
|
||
FROM muse_quality_policy_version version
|
||
LEFT JOIN muse_quality_policy policy
|
||
ON policy.tenant_id = version.tenant_id
|
||
AND policy.policy_key = version.policy_key
|
||
AND policy.deleted = FALSE
|
||
WHERE version.active_flag = TRUE AND version.deleted = FALSE
|
||
)
|
||
UPDATE muse_quality_policy_version version
|
||
SET active_flag = FALSE,
|
||
update_time = CURRENT_TIMESTAMP
|
||
FROM ranked_quality_policy_active duplicate
|
||
WHERE version.id = duplicate.id
|
||
AND duplicate.rn > 1;
|
||
|
||
WITH kept_quality_policy_active AS (
|
||
SELECT tenant_id, policy_key, version_no
|
||
FROM muse_quality_policy_version
|
||
WHERE active_flag = TRUE AND deleted = FALSE
|
||
)
|
||
UPDATE muse_quality_policy policy
|
||
SET active_version = kept.version_no::text,
|
||
update_time = CURRENT_TIMESTAMP
|
||
FROM kept_quality_policy_active kept
|
||
WHERE policy.tenant_id = kept.tenant_id
|
||
AND policy.policy_key = kept.policy_key
|
||
AND policy.deleted = FALSE
|
||
AND policy.active_version IS DISTINCT FROM kept.version_no::text;
|
||
|
||
CREATE UNIQUE INDEX uk_muse_quality_policy_version_active
|
||
ON muse_quality_policy_version(tenant_id, policy_key)
|
||
WHERE active_flag = TRUE AND deleted = FALSE;
|