fix(#1743): 批量变体独立选片——完整重跑单视频选片+批次20%重叠避让+查重超阈重渲+封面独立 #1745

Merged
auto-approve-bot merged 2 commits from fix/batch-variant-independent-plans-1743 into develop 2026-09-06 18:07:25 +08:00
Owner

根因

Issue #1743(P0 批量生成降重失效):批量生成的变体 1..N 走 clone_plan_for_variant,只重算起点,素材/顺序/速度与源 plan 完全相同,导致 N 条成片片段同源(实测批次查重率 60.1%/33.3%,3 个任务共用同一 plan a2989c05、同片段 asset)。

修复原则

多视频 = 单视频逻辑 × N,只是 1 条和多条的区别。 宁可不生成也不出同源成片。

改动

1. 新增选片纯核心 packages/domain/variant_plan_selector.py

  • 源 plan 片段骨架(clip_type/order/duration/文案/转场/速度)保留——保留模板结构与用户编辑结果
  • 素材池 shuffle(组合随机)+ main 片段顺序洗牌(顺序随机)
  • 起点走 _resolve_start_time(与单视频同一入口:镜头洗牌/随机起点/历史区间避让)
  • 批次内同素材时间区间重叠 >20% 自动重选起点(最多 6 次)
  • 空源片段/空素材池/时长全 0 → ValueError(严禁退回同源)

2. EditPlanService.reselect_plan_for_variant

  • 素材池 = 源 plan 素材 ∪ 批次任务素材
  • 源 plan 片段区间作为批次避让初始集;新片段区间 record_used_segments 写回素材 metadata(跨变体/跨任务避让,N 变体串行选片天然互避)
  • 事务性 replace 落库(透传 playback_speed/transition/text/config)

3. 正式生成 generation_tasks.py

  • 创建任何任务【之前】预生成 N-1 个独立 plan,失败直接中断(无脏数据)
  • 变体 0 保留用户预览 plan;变体 1..N-1 各自 reselect
  • count>1 无源 plan(前端未传 + 模板兜底查不到)→ 400 中断、零任务创建
  • 任务循环兜底块加批量守卫:count>1 缺 plan 直接 500,严禁 N 任务共用同一 plan

4. 批量预览 generation_preview.py

  • count==1:保持 clone 原行为(N=1 零回归)
  • count>1:变体 0 用源 plan、变体 1..N-1 reselect 真实选片——预览变体差异即正式成片差异(所见即所得);素材不足 400

5. worker 渲染 generation.py

  • 上传 OSS 与落库查重拆分:_upload_rendered_video(仅上传,重渲版 _v1 后缀不覆盖首版)/ _record_video_and_dedup
  • 批次任务 batch_similarity > 20%_reselect_plan_for_batch_retry 重选 plan 回写任务后重渲一次(最多 1 次;重选失败保留首版)
  • 封面:批次任务按 task_id md5 稳定哈希从 3 个候选帧分散选取(同任务重试稳定、跨任务分散);非批次仍取首帧
  • 判定逻辑抽纯函数 should_rerender_for_batch_dedup / pick_batch_cover_index(可单测)

6. dedup_helpers.py

  • create_video_record_and_dedup 返回 int → dict:{video_count, is_duplicate, batch_similarity, duplicate_of},支撑重渲判定

测试

  • 新增 24 个单测:
    • test_variant_plan_selector_1743(8):N=3 素材组合/顺序/起点显著不同、20% 重叠避让触发重选、空池/零时长 ValueError、非 main 片段保留骨架、跨变体 batch_segments 累加
    • test_reselect_plan_variant_1743(5):独立 plan/骨架复制/片段差异、record_used_segments 每片段写回、源区间避让 ≤20%、无片段/不存在 ValueError
    • test_batch_render_rerender_1743(11):重渲阈值判定全分支、封面哈希稳定/分散/公式一致
    • test_batch_dedup_helpers_1743(6 含既有调整):批次查重 batch_similarity 透传、历史重复跳过批次查重、非批次 None、重选 plan 重试成功/失败
  • 适配 6 个旧测试(clone→reselect mock、dict 返回契约、源码扫描新函数名)
  • 全量 14469 passed(仅 5 个已知 TTS 沙箱 h2.config 失败,CI 正常);diff coverage 63%;mypy/black/isort/ruff 全绿

前端配合

批量预览现在走后端真实变体独立选片(count>1 变体 1..N-1 各自 reselect),前端可直接读真实变体 plan 对齐 variantSeed 假预览(方案 A 所见即所得)。

验收

部署 staging 后请主人实测:N=3 批量生成 → 3 成片片段 asset 组合/顺序/封面不同、批次查重率全部 <20%;N=1 单视频零回归。

## 根因 Issue #1743(P0 批量生成降重失效):批量生成的变体 1..N 走 `clone_plan_for_variant`,只重算起点,**素材/顺序/速度与源 plan 完全相同**,导致 N 条成片片段同源(实测批次查重率 60.1%/33.3%,3 个任务共用同一 plan `a2989c05`、同片段 asset)。 ## 修复原则 **多视频 = 单视频逻辑 × N,只是 1 条和多条的区别。** 宁可不生成也不出同源成片。 ## 改动 ### 1. 新增选片纯核心 `packages/domain/variant_plan_selector.py` - 源 plan 片段骨架(clip_type/order/duration/文案/转场/速度)保留——保留模板结构与用户编辑结果 - 素材池 shuffle(组合随机)+ main 片段顺序洗牌(顺序随机) - 起点走 `_resolve_start_time`(与单视频**同一入口**:镜头洗牌/随机起点/历史区间避让) - 批次内同素材时间区间重叠 >20% 自动重选起点(最多 6 次) - 空源片段/空素材池/时长全 0 → ValueError(严禁退回同源) ### 2. `EditPlanService.reselect_plan_for_variant` - 素材池 = 源 plan 素材 ∪ 批次任务素材 - 源 plan 片段区间作为批次避让初始集;新片段区间 `record_used_segments` 写回素材 metadata(跨变体/跨任务避让,N 变体串行选片天然互避) - 事务性 replace 落库(透传 playback_speed/transition/text/config) ### 3. 正式生成 `generation_tasks.py` - 创建任何任务【之前】预生成 N-1 个独立 plan,失败直接中断(无脏数据) - 变体 0 保留用户预览 plan;变体 1..N-1 各自 reselect - **count>1 无源 plan(前端未传 + 模板兜底查不到)→ 400 中断、零任务创建** - 任务循环兜底块加批量守卫:count>1 缺 plan 直接 500,严禁 N 任务共用同一 plan ### 4. 批量预览 `generation_preview.py` - count==1:保持 clone 原行为(N=1 零回归) - count>1:变体 0 用源 plan、变体 1..N-1 reselect **真实选片**——预览变体差异即正式成片差异(所见即所得);素材不足 400 ### 5. worker 渲染 `generation.py` - 上传 OSS 与落库查重拆分:`_upload_rendered_video`(仅上传,重渲版 _v1 后缀不覆盖首版)/ `_record_video_and_dedup` - 批次任务 `batch_similarity > 20%` → `_reselect_plan_for_batch_retry` 重选 plan 回写任务后**重渲一次**(最多 1 次;重选失败保留首版) - 封面:批次任务按 task_id md5 稳定哈希从 3 个候选帧分散选取(同任务重试稳定、跨任务分散);非批次仍取首帧 - 判定逻辑抽纯函数 `should_rerender_for_batch_dedup` / `pick_batch_cover_index`(可单测) ### 6. `dedup_helpers.py` - `create_video_record_and_dedup` 返回 int → dict:`{video_count, is_duplicate, batch_similarity, duplicate_of}`,支撑重渲判定 ## 测试 - 新增 24 个单测: - `test_variant_plan_selector_1743`(8):N=3 素材组合/顺序/起点显著不同、20% 重叠避让触发重选、空池/零时长 ValueError、非 main 片段保留骨架、跨变体 batch_segments 累加 - `test_reselect_plan_variant_1743`(5):独立 plan/骨架复制/片段差异、record_used_segments 每片段写回、源区间避让 ≤20%、无片段/不存在 ValueError - `test_batch_render_rerender_1743`(11):重渲阈值判定全分支、封面哈希稳定/分散/公式一致 - `test_batch_dedup_helpers_1743`(6 含既有调整):批次查重 batch_similarity 透传、历史重复跳过批次查重、非批次 None、重选 plan 重试成功/失败 - 适配 6 个旧测试(clone→reselect mock、dict 返回契约、源码扫描新函数名) - 全量 **14469 passed**(仅 5 个已知 TTS 沙箱 h2.config 失败,CI 正常);**diff coverage 63%**;mypy/black/isort/ruff 全绿 ## 前端配合 批量预览现在走后端**真实变体独立选片**(count>1 变体 1..N-1 各自 reselect),前端可直接读真实变体 plan 对齐 variantSeed 假预览(方案 A 所见即所得)。 ## 验收 部署 staging 后请主人实测:N=3 批量生成 → 3 成片片段 asset 组合/顺序/封面不同、批次查重率全部 <20%;N=1 单视频零回归。
xiaoxia added 1 commit 2026-09-06 17:53:34 +08:00
fix(#1743): 批量变体独立选片——完整重跑单视频选片流程+批次20%重叠避让+查重超阈重渲+封面独立
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Build Staging Worker 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 / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web 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 / Check if frontend-only change (pull_request) Successful in 1m31s
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 Web Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Style (pull_request) Successful in 1m49s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 33s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 2m8s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m32s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m32s
AI Code Review / AI Code Review (pull_request) Failing after 3m15s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m12s
CI/CD Pipeline / Integration Tests (pull_request) Failing after 2m57s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m37s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 6m32s
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 / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 3s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m57s
21d7a6f45a
根因:批量生成的变体 1..N 走 clone_plan_for_variant 只重算起点,
素材/顺序/速度与源 plan 完全相同,导致 N 条成片片段同源(批次查重率 60.1%/33.3%)。

修复(多视频 = 单视频逻辑 × N):
- 新增 packages/domain/variant_plan_selector.py 纯核心:
  素材池 shuffle + main 片段顺序洗牌 + _resolve_start_time 起点重选
  (镜头洗牌/随机起点/历史区间避让,与单视频同一入口)+ 批次内同素材
  区间重叠 >20% 自动重选起点(最多 6 次)
- EditPlanService.reselect_plan_for_variant:源 plan 骨架(clip_type/order/
  duration/文案/转场/速度)保留,素材池=源素材∪批次素材,新片段区间
  record_used_segments 写回(跨变体/跨任务避让),replace 事务落库
- 正式生成(generation_tasks):创建任务前预生成 N-1 个独立 plan,
  变体0保留用户预览 plan;count>1 无源 plan 直接 400(严禁 N 任务兜底
  共用同一 plan);任务循环兜底块加批量守卫(缺 plan 500 中断)
- 批量预览(generation_preview):count>1 变体0用源 plan、变体1..N-1
  reselect 真实选片(所见即所得);count==1 保持 clone 零回归
- worker 渲染:上传 OSS 与落库查重拆分(_upload_rendered_video/
  _record_video_and_dedup);批次任务 batch_similarity>20% 重选 plan
  重渲一次(最多1次,重选失败保留首版,首版_v1后缀不覆盖);
  封面按 task_id md5 稳定哈希分散选候选帧(非批次仍取首帧)
- dedup_helpers.create_video_record_and_dedup 返回 dict:
  {video_count,is_duplicate,batch_similarity,duplicate_of}

测试:新增 24 个单测(纯核心选片差异化/重叠避让/骨架保留、服务层
reselect、重渲阈值判定、封面哈希、批次查重 dict 契约),适配 6 个旧测试,
全量 14469 passed;diff coverage 63%。

🚀 预览环境已部署

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

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

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

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

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1745 | | 预览链接 | [https://pr-1745.preview.xiaoxiajianji.com](https://pr-1745.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:3 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

  1. [apps/api/app/api/routes/generation_preview.py: 437行] variant_plan_ids 列表内容逻辑错误

    • 问题类型:逻辑bug
    • 问题描述:在 count > 1 的分支中,代码执行了 variant_plan_ids.append(source_plan_id),随后又循环添加新生成的变体 plan。这导致 variant_plan_ids 列表包含了源 plan 和所有变体 plan(共 N 个)。然而,对比 generation_tasks.py 中的逻辑(以及通常的批量任务关联逻辑),variant_plan_ids 往往仅用于存储“变体” plan(即 N-1 个),任务 0 直接使用源 plan。
    • 后果:如果后续关联任务的逻辑与 generation_tasks.py 一致(即 if task_index > 0: effective_plan_id = variant_plan_ids[task_index - 1]),那么任务 1 将会错误地获取到源 plan,任务 2 获取到变体 1 的 plan,导致所有任务的剪辑计划错位。
    • 修改建议:移除 variant_plan_ids.append(source_plan_id) 这一行,确保 variant_plan_ids 仅包含新生成的变体 plan,保持与 generation_tasks.py 的数据结构一致。
  2. [apps/api/app/services/edit_plan_service.py: 539-545行] 事务完整性风险导致元数据脏写

    • 问题类型:数据损坏风险
    • 问题描述:在 reselect_plan_for_variant 方法中,record_used_segments(记录素材使用区间)在 replace_all_clips_transactional(事务性替换片段)之前被调用。如果 replace_all_clips_transactional 执行失败并抛出异常回滚,前面写入的素材元数据(metadata)将无法回滚,导致系统认为该片段已被使用,但实际上对应的 Plan 并未创建成功。
    • 后果:素材区间被错误地标记为“已使用”,影响后续视频生成的去重逻辑,可能导致生成失败或素材利用率降低。
    • 修改建议:将 record_used_segments 的调用移至 replace_all_clips_transactional 内部,或者确保 record_used_segments 在同一个数据库事务中执行,保证原子性。
  3. [apps/api/app/api/routes/generation_preview.py: 435-501行] 预览任务对源 Plan 的污染风险

    • 问题类型:逻辑bug
    • 问题描述:代码注释明确指出“预览不污染源 plan”。在 count == 1 时,代码确实克隆了源 plan。但在 count > 1 时,代码直接将 source_plan_id 放入 variant_plan_ids 供任务 0 使用。这意味着批量预览的第一个任务将直接引用并可能修改用户的原始编辑计划。
    • 后果:如果预览任务执行过程中更新了 plan 的状态或元数据,用户的原始草稿 plan 将被意外修改(污染),违反了预览功能的设计原则。
    • 修改建议:为了保持一致性,count > 1 时的任务 0 也应该克隆一份源 plan,而不是直接引用。或者,如果业务逻辑允许任务 0 引用源 plan,则需确认其是否为只读操作,并更新注释说明此处的行为差异。

💡 改进建议(不阻塞合并)

  1. [apps/worker/video_processing/dedup_helpers.py: 38行] 返回值变更的兼容性风险
    • 具体内容:函数 create_video_record_and_dedup 的返回值从 int 变更为 dict。这是一个破坏性变更。虽然 diff 中未显示调用方代码,但必须确保所有调用方(如 generation.py 中的 Worker 任务)都已同步更新以处理字典返回值,否则会导致运行时崩溃。建议在合并前全库搜索该函数的调用点进行确认。

良好实践

  • generation_tasks.py 中增加了对批量生成时源 plan 缺失的严格校验(第 481 行),避免了 N 个任务共用同一 plan 导致内容重复的严重问题,逻辑严谨。
  • reselect_plan_for_variant 方法中实现了完善的素材池去重和分页加载逻辑,代码健壮性较好。

🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 09:56:37 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:3 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/api/app/api/routes/generation_preview.py: 437行] `variant_plan_ids` 列表内容逻辑错误** - 问题类型:逻辑bug - 问题描述:在 `count > 1` 的分支中,代码执行了 `variant_plan_ids.append(source_plan_id)`,随后又循环添加新生成的变体 plan。这导致 `variant_plan_ids` 列表包含了源 plan 和所有变体 plan(共 N 个)。然而,对比 `generation_tasks.py` 中的逻辑(以及通常的批量任务关联逻辑),`variant_plan_ids` 往往仅用于存储“变体” plan(即 N-1 个),任务 0 直接使用源 plan。 - 后果:如果后续关联任务的逻辑与 `generation_tasks.py` 一致(即 `if task_index > 0: effective_plan_id = variant_plan_ids[task_index - 1]`),那么任务 1 将会错误地获取到源 plan,任务 2 获取到变体 1 的 plan,导致所有任务的剪辑计划错位。 - 修改建议:移除 `variant_plan_ids.append(source_plan_id)` 这一行,确保 `variant_plan_ids` 仅包含新生成的变体 plan,保持与 `generation_tasks.py` 的数据结构一致。 2. **[apps/api/app/services/edit_plan_service.py: 539-545行] 事务完整性风险导致元数据脏写** - 问题类型:数据损坏风险 - 问题描述:在 `reselect_plan_for_variant` 方法中,`record_used_segments`(记录素材使用区间)在 `replace_all_clips_transactional`(事务性替换片段)之前被调用。如果 `replace_all_clips_transactional` 执行失败并抛出异常回滚,前面写入的素材元数据(metadata)将无法回滚,导致系统认为该片段已被使用,但实际上对应的 Plan 并未创建成功。 - 后果:素材区间被错误地标记为“已使用”,影响后续视频生成的去重逻辑,可能导致生成失败或素材利用率降低。 - 修改建议:将 `record_used_segments` 的调用移至 `replace_all_clips_transactional` 内部,或者确保 `record_used_segments` 在同一个数据库事务中执行,保证原子性。 3. **[apps/api/app/api/routes/generation_preview.py: 435-501行] 预览任务对源 Plan 的污染风险** - 问题类型:逻辑bug - 问题描述:代码注释明确指出“预览不污染源 plan”。在 `count == 1` 时,代码确实克隆了源 plan。但在 `count > 1` 时,代码直接将 `source_plan_id` 放入 `variant_plan_ids` 供任务 0 使用。这意味着批量预览的第一个任务将直接引用并可能修改用户的原始编辑计划。 - 后果:如果预览任务执行过程中更新了 plan 的状态或元数据,用户的原始草稿 plan 将被意外修改(污染),违反了预览功能的设计原则。 - 修改建议:为了保持一致性,`count > 1` 时的任务 0 也应该克隆一份源 plan,而不是直接引用。或者,如果业务逻辑允许任务 0 引用源 plan,则需确认其是否为只读操作,并更新注释说明此处的行为差异。 ### 💡 改进建议(不阻塞合并) 1. **[apps/worker/video_processing/dedup_helpers.py: 38行] 返回值变更的兼容性风险** - 具体内容:函数 `create_video_record_and_dedup` 的返回值从 `int` 变更为 `dict`。这是一个破坏性变更。虽然 diff 中未显示调用方代码,但必须确保所有调用方(如 `generation.py` 中的 Worker 任务)都已同步更新以处理字典返回值,否则会导致运行时崩溃。建议在合并前全库搜索该函数的调用点进行确认。 ### ✅ 良好实践 - 在 `generation_tasks.py` 中增加了对批量生成时源 plan 缺失的严格校验(第 481 行),避免了 N 个任务共用同一 plan 导致内容重复的严重问题,逻辑严谨。 - `reselect_plan_for_variant` 方法中实现了完善的素材池去重和分页加载逻辑,代码健壮性较好。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-09-06 09:56:37 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia added 1 commit 2026-09-06 18:01:49 +08:00
test(#1743): 集成测试适配批量无plan守卫——无plan 400中断+有源plan独立变体plan成功链路
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
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 Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API 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 API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 29s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 28s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m38s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m48s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m57s
CI/CD Pipeline / Validate - Style (pull_request) Successful in 2m12s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 2m37s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m17s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 4m52s
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 2m16s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 6s
AI Code Review / AI Code Review (pull_request) Successful in 6m37s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m25s
c83febed61
auto-approve-bot merged commit 0469272bd6 into develop 2026-09-06 18:07:25 +08:00
auto-approve-bot deleted branch fix/batch-variant-independent-plans-1743 2026-09-06 18:07:25 +08:00

🗑️ 预览环境已清理

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

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

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