7896a6d20b
CI / backend-test (push) Successful in 11m35s
creation schema 三表(generation_models / generation_styles / generation_jobs)逐列取自已评审目标模型 patbond_postgresql.sql (schema 60/68 + 对象 556-717),含 14 索引与 3 个 updated_at 触发器。 - 零外键需要裁剪:这是第一个不用砍跨 schema 外键的 baseline 迁移, identity/media(V1)与 pet_health(V3)目标 schema 均已存在 - 按 V5 文件头指令「M4 补回」补回 community.posts.generation_job_id → creation.generation_jobs(id) ON DELETE SET NULL;约束名显式写为 posts_generation_job_id_fkey,即目标模型内联声明时 PostgreSQL 会 自动生成的名字,使 V1..V6 建库与照目标模型建库约束名一致 - posts.region_id 保持裸列(区域系统属 M5,ADR-018 裁剪,M5 补回) - 两条偏索引对齐 worker 语句:ix_generation_jobs_queue 的列序与出队 ORDER BY 完全一致(SKIP LOCKED 领取走索引扫描不排序); ix_generation_jobs_running 驱动租约回收与待轮询扫描 两处刻意偏离目标模型,文件头已逐条记录原因: 1. input_asset_id 改可空(目标模型 NOT NULL)——参考图选填拍板;原 NOT NULL 会使文生图无法表达。未发明 requires_input 标记(不超出 已评审模型),「某模型是否必须有输入」由应用层查目录判断 2. 新增 first_attempt_at(目标模型无此列)——iteration-4/06 §4.2 指标 口径要求。目标模型无法表达:其 ck_generation_jobs_state 强制 queued 分支 started_at IS NULL,故重排队必然擦除首次尝试时间, 导致排队时长与纯执行耗时永久无法分离。该列仅首次进入 running 时 写入、不覆盖,并刻意排除在 queued 分支的置空要求之外; ck_generation_jobs_first_attempt 钉住其与 attempt_count 的不变式 测试: - 新增 CreationMigrationIntegrationTest(12 项)。重点覆盖「日后同步回 目标模型会静默改回去」的行为:复合外键真实拦截跨 media_kind 引用、 queued→running→failed→queued 全程后 first_attempt_at 保留而 started_at 被清空、不变式双向拒绝、provider_request_id 部分唯一索引 (NULL 可共存、同值冲突)、idempotency_key 的按用户作用域 - CommunityMigrationIntegrationTest 原断言 %generation% 与 %region% 外键合计为 0,V6 后必然变红(iteration-4/02 已预警)。拆为两条独立 断言(generation=1、region=0)而非改成合计 1,使任一侧回退可单独定位 全量 381 → 393,零失败零跳过(auth 40 / common 3 / community 107 / pet 100 / user 131→143)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>