- 迁移 044:9 张表换 bigint IDENTITY 主键,account_id/exit_id/competitor_id/work_id/comment_id/job_id/rule_id 降级 UNIQUE; 引用表 FK 重指 bigint;checkpoint 删派生文本 id;creator_settings 布尔 PK 换 bigint identity + 单行表达式唯一索引; social_account.profile_id 死列删除 - seed 派生改 SQL:CreateBoundEnv 用 jsonb_set(account.id+1000),deriveSeed 删除;Fingerprint.Validate 允许 Seed=0(派生态) - 三域 store SQL 列名适配;appendAudit/审计过滤经 JOIN 读回文本标识;UPDATE..RETURNING..FROM 拆两段式 - 对外 API 契约不变:模型/JSON/URL 全部保持文本 ID - account 域补 PG 生命周期集成测试(列表/凭据解析/暂停吊销恢复/审计过滤/删除链路),覆盖率 22.4%→73.9%
76 lines
4.2 KiB
Go
76 lines
4.2 KiB
Go
package environment
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
)
|
|
|
|
func TestMigration043ConsolidatedSchemaShape(t *testing.T) {
|
|
databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
|
|
if databaseURL == "" {
|
|
t.Skip("set CREATORHUB_POSTGRES_TEST_URL")
|
|
}
|
|
ctx := context.Background()
|
|
testURL := isolatedDatabaseURL(t, databaseURL)
|
|
store, err := Open(ctx, testURL)
|
|
if err != nil {
|
|
t.Fatalf("open store (applies all migrations incl 043): %v", err)
|
|
}
|
|
defer store.Close()
|
|
|
|
db, err := sql.Open("pgx", testURL)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// 最终 19 张表
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.tables WHERE table_schema = current_schema()
|
|
AND table_name IN ('social_account','gateway','network_exit','browser_env','audit_event',
|
|
'creator_competitor','creator_competitor_share_job','creator_work','creator_work_metric','creator_work_cover',
|
|
'creator_comment','creator_comment_rule_result','creator_lead_rule','creator_account_profile','creator_account_password',
|
|
'creator_account_metric','creator_collection_checkpoint','creator_settings','schema_migration')`, 19)
|
|
// 已删表不再存在
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.tables WHERE table_schema = current_schema()
|
|
AND table_name IN ('runtime_instance','environment_binding','credential_reference','content_draft','confirmation',
|
|
'operation_task','execution_attempt','runtime_use_lease','creator_event','creator_strategy','creator_operation',
|
|
'creator_conversation','creator_message','creator_cooldown','creator_listener_state','creator_listener_boundary',
|
|
'creator_relation','creator_material_job','creator_event_strategy_trace','creator_work_source','creator_metric_plan',
|
|
'creator_source_sync_lease','creator_schema_migration')`, 0)
|
|
// browser_env 合并列
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'browser_env' AND column_name IN ('account_id','exit_id','gateway_id','runtime_cleanup_pending',
|
|
'runtime_cleanup_binding_version','runtime_cleanup_runtime_id','runtime_cleanup_network_id',
|
|
'runtime_id','runtime_lease_until','runtime_network_id','runtime_node_id','updated_at')`, 12)
|
|
// social_account 凭据列
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'social_account' AND column_name IN ('credential_provider','credential_key')`, 2)
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'social_account' AND column_name = 'credential_reference_id'`, 0)
|
|
// creator_work 调度列
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'creator_work' AND column_name IN ('metric_plan_published_at','metric_monitoring_end','metric_plan_next_at',
|
|
'metric_plan_interval_seconds','metric_plan_multiplier','metric_plan_max_interval_seconds','metric_plan_point_index','metric_plan_stopped')`, 8)
|
|
// checkpoint 支持 sync kind
|
|
var kindCheck string
|
|
if err := db.QueryRow(`SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conname = 'creator_collection_checkpoint_collection_kind_check' AND conrelid = 'creator_collection_checkpoint'::regclass`).Scan(&kindCheck); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strings.Contains(kindCheck, "'sync'") {
|
|
t.Fatalf("checkpoint kind check missing sync: %s", kindCheck)
|
|
}
|
|
// creator_settings 转写列已删
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'creator_settings' AND column_name LIKE 'transcription%'`, 0)
|
|
// audit_event 任务列已删
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM information_schema.columns WHERE table_schema = current_schema()
|
|
AND table_name = 'audit_event' AND column_name IN ('confirmation_id','confirmation_version','attempt_id','task_id','runtime_instance_id')`, 0)
|
|
// 统一登记表:1-38(除 36)、1017-1042、43 全部登记
|
|
assertDatabaseCount(t, db, `SELECT count(*) FROM schema_migration`, 49)
|
|
}
|