fix: 查重流程全面核实修复 — 两阶段持久化 + 重新计算查重API (#1664) #1684
Reference in New Issue
Block a user
Delete Branch "fix/dedup-flow-verification-1664"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
问题根因
全量排查了查重流程从后端→API→前端的全链路代码,发现以下问题:
后端
dedup_helpers.py事务问题(核心 bug):视频记录先commit入库,然后再算指纹/查重率。如果指纹计算(cv2异常)或查重率计算(DB异常)中途失败,视频已经在库里但duplicate_rate=None/visual_similarity=None,且没有任何重试机制前端(需前端工程师配套修复)
visual_similarity显示 bug:后端返回 0~1(归一化),ProductInfoPanel.tsx:59直接.toFixed(1)%显示成 "0.7%" 而非 "70%"types.ts注释写的 "0-100",实际后端返回 "0-1"修复
后端(本 PR)
dedup_helpers.py重构为两阶段持久化:Phase 1 构建内存对象 → Phase 2 计算指纹+查重(全部在内存) → Phase 3 一次性create()+commit()。消除中间态,保证要么完整写入要么整体回滚videos.py新增POST /videos/recompute-dedup:对缺少duplicate_rate/video_fingerprint的视频触发异步check_duplicate任务重新计算。支持指定 video_ids 或全用户范围。含安全校验(只处理当前用户的视频)前端(需前端工程师配套 PR)
ProductInfoPanel.tsx:59:visual_similarity显示需×100products/types.ts:27,80:注释 "0-100" 改为 "0-1"新增测试
test_dedup_two_phase_commit.py: 5 个测试覆盖两阶段提交场景test_recompute_dedup_api.py: 5 个测试覆盖重新计算 APItest_dedup_helpers_user_id.py适配新持久化模式🚀 预览环境已部署
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
[apps/api/app/api/routes/videos.py: 第298行] 缺少必要的导入导致运行时错误
recompute_dedup函数中使用了celery_app(第298行)和logger(第301行),但在文件头部的导入块中未看到这两个变量的导入声明(celery_app通常从app.core.celery或类似模块导入,logger需实例化)。这会导致函数运行时抛出NameError。celery_app和logger的正确导入语句。[apps/worker/video_processing/dedup_helpers.py: 第134行] 异常处理逻辑缺失
create_video_record_and_dedup函数末尾的except Exception as e:块在 diff 中显示为空。如果session.commit()或video_repo.create()抛出异常,代码将进入此块但什么都不做。这会导致:session.rollback()未调用),可能导致连接泄漏或锁死。None,而调用方期望返回0(失败)或1(成功),可能导致调用方逻辑错误。test_commit_not_called_on_total_failure明确断言了session.rollback会被调用且返回值为 0,当前代码会导致该测试失败。except块中添加session.rollback()并返回0,或者重新抛出异常(视业务需求而定),确保与单元测试预期一致。💡 改进建议(不阻塞合并)
[apps/api/app/api/routes/videos.py: 第268行] 潜在的内存溢出风险
request.video_ids为空时,调用repo.list_by_user(user_id)获取当前用户所有视频。如果用户视频量巨大(如数万条),这将一次性加载所有数据到内存,可能导致 OOM。建议使用迭代器或分页处理。[apps/worker/video_processing/dedup_helpers.py: 第124行] 移除
update_thumbnail的逻辑确认video_repo.update_thumbnail(...),新代码中仅在GeneratedVideo构造时传入了thumbnail_url并直接create。请确认update_thumbnail方法中没有包含额外的副作用逻辑(如额外的日志、通知或外部存储操作),如果仅仅是更新 DB 字段,当前修改是合理的优化。✅ 良好实践
dedup_helpers.py的重构很好地解决了“部分写入”的问题,先在内存计算完所有查重数据再一次性提交,避免了计算失败导致数据库中出现只有记录无查重数据的脏数据。videos.py中的recompute_dedup接口正确地过滤了user_id,防止用户越权操作他人的视频。test_dedup_two_phase_commit.py和test_recompute_dedup_api.py)非常详尽,覆盖了正常流程、边界条件和异常场景,特别是对rollback的测试非常有价值。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-09-04 04:46:07 | 模型:
058a8d7307to61e9262c0a🗑️ 预览环境已清理
PR #1684 已关闭或合并,对应的预览环境已被清理。