Commit Graph

1 Commits

Author SHA1 Message Date
lixi 7896a6d20b feat(db): V6 creation schema 地基 + 补回 posts.generation_job_id 外键(T4-01)
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>
2026-09-18 16:35:36 +08:00