fix(p0): finalize 400(extra_meta漏传)+ 查重失效(fingerprint_chunks漏存) #2068

Merged
auto-approve-bot merged 3 commits from fix/p0-finalize-extra-meta-fingerprint into develop 2026-09-27 20:47:14 +08:00
Owner

P0:finalize 400 + 查重失效双修复

Bug 1:finalize 报 400(rendered_output.file_url 为空)

根因:SQLAlchemyGenerationTaskRepository 的 _to_domain()、create()、update() 三个方法都漏传/漏写了 extra_meta 字段。
Worker 渲染完成后把 rendered_output 写入了 GenerationTask.metadata 列,但 API 进程读出来的 task.extra_meta 永远是 {},导致 finalize 时读不到 rendered_output.file_url,抛 ValueError 映射成 HTTP 400。

修复:

  • _to_domain() 补 extra_meta=dict(model.extra_meta) if model.extra_meta else {}
  • create() 初始化 model 时补 extra_meta=...
  • update() flush 时补 model.extra_meta = dict(task.extra_meta) if task.extra_meta else {}

Bug 2:查重失效(fingerprint_chunks 恒为 None)

根因:两处字段名/路径不一致:

  1. Worker _precompute_render_metadata 返回 fingerprint_dict(VideoFingerprint.to_dict(),含嵌套 chunks、md5)和顶层 fingerprint_chunks、is_duplicate 等。
  2. 但保存 meta["rendered_output"] 时手写字段白名单,漏写了 fingerprint_chunks / is_duplicate / duplicate_of / duplicate_rate / match_count / visual_similarity / video_fingerprint_md5,最终 DB 里只存了 fingerprint_dict 一个字段。
  3. RenderedOutput.from_dict() 只读顶层 fingerprint_chunks(已被丢弃),导致分片指纹永远为空,finalize 无法写入 VideoFingerprintChunk,查重历史比对失效。

修复:

  • Worker 保存 rendered_output 改为 {**rendered_output, file_url, file_size, duration} 展开,彻底消除字段白名单漏传问题(顺手清理冗余代码)。
  • RenderedOutput.from_dict() 兼容两种历史数据格式:
    • 顶层 fingerprint_chunks(正常路径,compute_render 返回直存)
    • 嵌套 fingerprint_dict["chunks"](兜底,老数据 / 直接用 fp.to_dict() 路径)
    • video_fingerprint_md5 同样从 fingerprint_dict["md5"] 兜底。

影响

  • 纯后端修复,前端无改动。
  • 用户已渲染完成、卡在 awaiting_cover 的任务(如 a2b18e91...db2e1766)数据完好,无需重渲染,修复部署后直接点「完成」即可 finalize 成功,查重结果自动复用。
  • 不会影响已 completed 的历史任务(幂等:已入库的 finalize 走幂等分支直接返回)。
## P0:finalize 400 + 查重失效双修复 ### Bug 1:finalize 报 400(rendered_output.file_url 为空) **根因**:`SQLAlchemyGenerationTaskRepository` 的 `_to_domain()`、`create()`、`update()` 三个方法都漏传/漏写了 `extra_meta` 字段。 Worker 渲染完成后把 rendered_output 写入了 `GenerationTask.metadata` 列,但 API 进程读出来的 `task.extra_meta` 永远是 `{}`,导致 finalize 时读不到 `rendered_output.file_url`,抛 ValueError 映射成 HTTP 400。 **修复**: - `_to_domain()` 补 `extra_meta=dict(model.extra_meta) if model.extra_meta else {}` - `create()` 初始化 model 时补 `extra_meta=...` - `update()` flush 时补 `model.extra_meta = dict(task.extra_meta) if task.extra_meta else {}` ### Bug 2:查重失效(fingerprint_chunks 恒为 None) **根因**:两处字段名/路径不一致: 1. Worker `_precompute_render_metadata` 返回 `fingerprint_dict`(`VideoFingerprint.to_dict()`,含嵌套 `chunks`、`md5`)和顶层 `fingerprint_chunks`、`is_duplicate` 等。 2. 但保存 `meta["rendered_output"]` 时手写字段白名单,**漏写了 `fingerprint_chunks` / `is_duplicate` / `duplicate_of` / `duplicate_rate` / `match_count` / `visual_similarity` / `video_fingerprint_md5`**,最终 DB 里只存了 `fingerprint_dict` 一个字段。 3. `RenderedOutput.from_dict()` 只读顶层 `fingerprint_chunks`(已被丢弃),导致分片指纹永远为空,finalize 无法写入 `VideoFingerprintChunk`,查重历史比对失效。 **修复**: - Worker 保存 rendered_output 改为 `{**rendered_output, file_url, file_size, duration}` 展开,彻底消除字段白名单漏传问题(顺手清理冗余代码)。 - `RenderedOutput.from_dict()` 兼容两种历史数据格式: - 顶层 `fingerprint_chunks`(正常路径,compute_render 返回直存) - 嵌套 `fingerprint_dict["chunks"]`(兜底,老数据 / 直接用 fp.to_dict() 路径) - `video_fingerprint_md5` 同样从 `fingerprint_dict["md5"]` 兜底。 ### 影响 - 纯后端修复,前端无改动。 - 用户已渲染完成、卡在 awaiting_cover 的任务(如 a2b18e91...db2e1766)数据完好,无需重渲染,修复部署后直接点「完成」即可 finalize 成功,查重结果自动复用。 - 不会影响已 completed 的历史任务(幂等:已入库的 finalize 走幂等分支直接返回)。
xiaoxia added 3 commits 2026-09-27 20:37:03 +08:00
fix(worker): rendered_output 改为 dict 展开,避免手写字段白名单漏传 fingerprint_chunks/is_duplicate 等字段
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 1s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m27s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 18s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 16s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m6s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m32s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m2s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 4m20s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 4m32s
AI Code Review / AI Code Review (pull_request) Successful in 6m38s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 9m30s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 1s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 7m1s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 35s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 4m3s
6c355f5200

🚀 预览环境已部署

项目 详情
PR号 #2068
预览链接 https://pr-2068.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #2068 | | 预览链接 | [https://pr-2068.preview.xiaoxiajianji.com](https://pr-2068.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
auto-approve-bot merged commit 59c05148ab into develop 2026-09-27 20:47:14 +08:00
auto-approve-bot deleted branch fix/p0-finalize-extra-meta-fingerprint 2026-09-27 20:47:16 +08:00

🗑️ 预览环境已清理

PR #2068 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #2068 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.