refactor(wave113): 抽离transition_config领域模型 + 49单测 #999

Closed
xiaoxia wants to merge 1 commits from test/wave113-transition-config into develop
Owner

变更内容

  • 新建 packages/domain/transition_config.py:纯逻辑配置层

    • TransitionType 枚举(14 种转场 + 10+ 别名映射,不区分大小写/下划线/中划线)
    • TransitionConfig 数据类(parse 解析 + is_cut / ffmpeg_transition / validate
    • MIN_TRANSITION_DURATION / MAX_TRANSITION_DURATION / DEFAULT_TRANSITION_DURATION / CUT_TRANSITION 常量
    • StrEnum 兼容性处理(Python 3.10 及以下)
  • 精简 apps/worker/video_processing/transition_engine.py

    • 381→172行(-209行,-55%
    • 枚举/数据类/常量/纯逻辑全部委托给 transition_config
    • 保留模块级导出,完全向后兼容
  • 新增 49 个单测(test_transition_config.py)

    • 常量验证(2 个)
    • TransitionType(10 个):all_supported / is_supported 各种格式 / 别名 / 未知
    • TransitionConfig 默认值(3 个)
    • TransitionConfig.parse(19 个):各种 effect + duration 边界 + 降级
    • ffmpeg_transition 映射(7 个)
    • validate 校验(7 个)

验证

  • 本地全绿:131 passed(82 原有 + 49 新增,含 transition_engine + transition_presets 全部测试)
  • black 格式化通过

关联

后端单测覆盖率提升 wave113,transition_engine 大文件拆分。

## 变更内容 - **新建** `packages/domain/transition_config.py`:纯逻辑配置层 - `TransitionType` 枚举(14 种转场 + 10+ 别名映射,不区分大小写/下划线/中划线) - `TransitionConfig` 数据类(`parse` 解析 + `is_cut` / `ffmpeg_transition` / `validate`) - `MIN_TRANSITION_DURATION` / `MAX_TRANSITION_DURATION` / `DEFAULT_TRANSITION_DURATION` / `CUT_TRANSITION` 常量 - StrEnum 兼容性处理(Python 3.10 及以下) - **精简** `apps/worker/video_processing/transition_engine.py` - 381→172行(-209行,**-55%**) - 枚举/数据类/常量/纯逻辑全部委托给 transition_config - 保留模块级导出,**完全向后兼容** - **新增** 49 个单测(test_transition_config.py) - 常量验证(2 个) - TransitionType(10 个):all_supported / is_supported 各种格式 / 别名 / 未知 - TransitionConfig 默认值(3 个) - TransitionConfig.parse(19 个):各种 effect + duration 边界 + 降级 - ffmpeg_transition 映射(7 个) - validate 校验(7 个) ## 验证 - 本地全绿:131 passed(82 原有 + 49 新增,含 transition_engine + transition_presets 全部测试) - black 格式化通过 ## 关联 后端单测覆盖率提升 wave113,transition_engine 大文件拆分。
xiaoxia added 1 commit 2026-07-27 01:03:23 +08:00
refactor(wave113): 抽离transition_config领域模型 + 49单测
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m3s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m56s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 38s
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 / Validate - Migration (alembic) (pull_request) Successful in 56s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 34s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 45s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m2s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 53s
AI Code Review / AI Code Review (pull_request) Successful in 2m10s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m0s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m29s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
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 Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m20s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m48s
CI/CD Pipeline / Deploy Production (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 / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 19s
254ad761b2
- 新建 packages/domain/transition_config.py:纯逻辑配置层
  + TransitionType 枚举(14种转场 + 别名映射)
  + TransitionConfig 数据类(parse / is_cut / ffmpeg_transition / validate)
  + MIN/MAX/DEFAULT 时长常量 + CUT_TRANSITION 常量
- transition_engine.py: 381→172行 (-209行, -55%)
  保留模块级导出,完全向后兼容
- 新增 49 个单测覆盖枚举 + 数据类 + 纯逻辑

🚀 预览环境已部署

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

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

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

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

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

代码审查结果 - PR #999

⚠️ 问题(2个需要修改)

  1. packages/domain/transition_config.py 第168行float(duration) 转换未处理 NaNInfinity

    • 原因:当 durationfloat('nan')float('inf') 时,后续的边界检查 d < MINd > MAX 均为 False,导致 NaN 被作为合法时长写入配置。
    • 后果:后续传给 FFmpeg 时可能导致未定义行为或渲染崩溃。
    • 建议:在 try 块中增加 math.isnan(d)math.isinf(d) 的检查,或使用 d.is_integer() 等辅助判断,将非法数值钳制或使用默认值。
  2. packages/domain/transition_config.py 第236行validate 方法对 NoneNaN 的校验逻辑存在隐患。

    • 原因:代码直接使用 self.duration < MIN 进行比较。如果 self.durationNone(直接实例化时可能发生)会抛出 TypeError;如果是 NaN,比较结果为 False,导致校验错误地返回 (True, "")
    • 后果:非法状态的对象通过校验,进入后续处理流程引发异常。
    • 建议:增加类型检查(isinstance(self.duration, (int, float)))和 NaN 检查。

💡 建议(2个可选)

  1. packages/domain/transition_config.py 第148行:建议增加 __post_init__ 方法以强化数据一致性。

    • 具体内容:当前 TransitionConfig 是 dataclass,允许绕过 parse 方法直接实例化(如 TransitionConfig(effect="invalid"))。这会导致 ffmpeg_transition 属性静默降级为 "fade",而 validate 方法却返回 False,行为不一致。建议在 __post_init__ 中调用标准化逻辑,或将字段设为私有强制使用工厂方法。
  2. packages/domain/transition_config.py 第152行effect 参数处理缺乏类型容错。

    • 具体内容:代码调用了 effect.strip(),如果传入非字符串类型(如 int),会抛出 AttributeError。虽然类型注解为 str | None,但考虑到 duration 参数做了 try/except 容错,建议此处也保持一致的防御性编程风格。

格式检查通过 | 逻辑审查需修改 | 性能良好


🤖 由 AI 代码审查机器人自动生成 | 2026-07-26 17:56:17 | 模型:

## 代码审查结果 - PR #999 ### ⚠️ 问题(2个需要修改) 1. **packages/domain/transition_config.py 第168行**:`float(duration)` 转换未处理 `NaN` 和 `Infinity`。 - **原因**:当 `duration` 为 `float('nan')` 或 `float('inf')` 时,后续的边界检查 `d < MIN` 和 `d > MAX` 均为 False,导致 `NaN` 被作为合法时长写入配置。 - **后果**:后续传给 FFmpeg 时可能导致未定义行为或渲染崩溃。 - **建议**:在 `try` 块中增加 `math.isnan(d)` 和 `math.isinf(d)` 的检查,或使用 `d.is_integer()` 等辅助判断,将非法数值钳制或使用默认值。 2. **packages/domain/transition_config.py 第236行**:`validate` 方法对 `None` 和 `NaN` 的校验逻辑存在隐患。 - **原因**:代码直接使用 `self.duration < MIN` 进行比较。如果 `self.duration` 为 `None`(直接实例化时可能发生)会抛出 `TypeError`;如果是 `NaN`,比较结果为 False,导致校验错误地返回 `(True, "")`。 - **后果**:非法状态的对象通过校验,进入后续处理流程引发异常。 - **建议**:增加类型检查(`isinstance(self.duration, (int, float))`)和 NaN 检查。 ### 💡 建议(2个可选) 1. **packages/domain/transition_config.py 第148行**:建议增加 `__post_init__` 方法以强化数据一致性。 - **具体内容**:当前 `TransitionConfig` 是 dataclass,允许绕过 `parse` 方法直接实例化(如 `TransitionConfig(effect="invalid")`)。这会导致 `ffmpeg_transition` 属性静默降级为 "fade",而 `validate` 方法却返回 False,行为不一致。建议在 `__post_init__` 中调用标准化逻辑,或将字段设为私有强制使用工厂方法。 2. **packages/domain/transition_config.py 第152行**:`effect` 参数处理缺乏类型容错。 - **具体内容**:代码调用了 `effect.strip()`,如果传入非字符串类型(如 `int`),会抛出 `AttributeError`。虽然类型注解为 `str | None`,但考虑到 `duration` 参数做了 `try/except` 容错,建议此处也保持一致的防御性编程风格。 --- ✅ 格式检查通过 | ❌ 逻辑审查需修改 | ✅ 性能良好 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-26 17:56:17 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia closed this pull request 2026-07-27 15:26:22 +08:00

🗑️ 预览环境已清理

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

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

🗑️ **预览环境已清理** PR #999 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 25s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m3s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m56s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 38s
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 / Validate - Migration (alembic) (pull_request) Successful in 56s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 34s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 45s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m2s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 53s
AI Code Review / AI Code Review (pull_request) Successful in 2m10s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m0s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m29s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
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 Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m20s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m48s
CI/CD Pipeline / Deploy Production (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 / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
ACR Cleanup / ACR Image Cleanup (pull_request_target) Has been cancelled
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 19s

Pull request closed

Sign in to join this conversation.