test(wave115): 抽离watermark_config领域模型 + 76单测 #1001

Closed
xiaoxia wants to merge 1 commits from test/wave115-watermark-config into develop
Owner

变更内容

  • 抽离 WatermarkConfig 数据类、9宫格位置常量、位置计算、滤镜构建函数到 packages/domain/watermark_config.py
  • 新增 has_effect() / get_position_names() / get_position_display_name() 工具函数
  • watermark_engine.py: 314→117 行 (-63%),保留 WatermarkEngine 薄包装类 + 模块级向后兼容导入

单测

  • 新增 76 个纯逻辑单测(test_watermark_config.py)
  • 原有 48 个测试无回归(test_watermark_engine.py)
  • 合计 124 passed
## 变更内容 - 抽离 WatermarkConfig 数据类、9宫格位置常量、位置计算、滤镜构建函数到 packages/domain/watermark_config.py - 新增 has_effect() / get_position_names() / get_position_display_name() 工具函数 - watermark_engine.py: 314→117 行 (-63%),保留 WatermarkEngine 薄包装类 + 模块级向后兼容导入 ## 单测 - 新增 76 个纯逻辑单测(test_watermark_config.py) - 原有 48 个测试无回归(test_watermark_engine.py) - 合计 **124 passed**
xiaoxia added 1 commit 2026-07-27 07:21:07 +08:00
test(wave115): 抽离watermark_config领域模型 + 76单测
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 16s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m10s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m39s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m43s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m13s
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 / PR Build Web Image (pull_request) Successful in 35s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 34s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m8s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 48s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m40s
AI Code Review / AI Code Review (pull_request) Successful in 6m39s
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 / Unit Tests (pull_request) Successful in 3m25s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m24s
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 22s
9587f02df2
- 抽离WatermarkConfig数据类、9宫格位置常量、位置计算、滤镜构建到packages/domain/watermark_config.py
- 新增has_effect()/get_position_names()/get_position_display_name()工具函数
- watermark_engine.py: 314→117行 (-63%),保留WatermarkEngine薄包装+模块级向后兼容导入
- 76个纯逻辑单测全绿,原有48个测试无回归
- 合计124 passed

🚀 预览环境已部署

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

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

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

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

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

📊 审查概览

  • 整体评价:需修改
  • 严重问题数量:3 个
  • 一般建议数量:1 个

需修改的问题(严重)

  1. [packages/domain/watermark_config.py: calc_scroll_x] FFmpeg 表达式语法错误

    • 问题描述:函数返回的字符串为 f"mod({output_width}-mod({speed}*t\\,{output_width}+{wm_width})"。FFmpeg 的 mod(x, y) 函数需要两个参数,而此处生成的表达式 mod( ... ) 外层只有一个参数,缺少第二个参数(模数),导致生成的 FFmpeg 滤镜命令无效。
    • 修改建议:检查并修正 calc_scroll_x 的返回逻辑。如果意图是计算跑马灯坐标,通常使用 W - mod(t*speed, W+w) 形式,无需外层再套 mod,或者补充缺失的第二个参数。同时需注意该函数返回值与 build_image_watermark_filter 内部实现逻辑不一致的问题。
  2. [packages/domain/watermark_config.py: build_text_watermark_filter] 特殊字符转义不完整

    • 问题描述:代码仅对冒号 : 和单引号 ' 进行了转义,但未处理反斜杠 \。在 FFmpeg drawtext 滤镜中,反斜杠是转义字符。如果用户输入的文本包含 \(如 Windows 路径 C:\Users 或特定符号),未被转义会导致后续字符被误解析(如 \n 变为换行),破坏命令结构或导致渲染错误。
    • 修改建议:在替换列表中增加对 \ 的转义,例如:text.replace("\\", "\\\\")。建议使用 re.escape 或更严谨的转义逻辑处理 FFmpeg 特殊字符。
  3. [packages/domain/watermark_config.py: WatermarkConfig.from_dict] 类型转换缺乏异常保护

    • 问题描述:在从字典读取配置时,直接使用 float(...)int(...) 进行类型转换(如 scale=float(...))。如果配置数据中包含非数字字符串(如 "auto"None),将抛出 ValueErrorTypeError,导致 Worker 进程崩溃。
    • 修改建议:添加 try-except 块捕获转换异常,记录错误日志并回退到默认值,或使用辅助函数进行安全的类型转换。

💡 改进建议(一般)

  1. [packages/domain/watermark_config.py: build_image_watermark_filter] 水印高度估算逻辑偏差
    • 具体内容:代码在计算位置时使用 wm_width 代替未知的 wm_heightcalc_position(..., wm_width, wm_width, ...))。这假设水印是正方形的。对于非正方形图片(如宽横幅或高竖条),垂直方向的对齐(顶部/底部/居中)会产生偏差。虽然难以在预处理阶段获取精确高度,但建议至少在注释中明确此限制,或尝试读取图片头信息获取真实尺寸。

良好实践

  • 架构重构:将核心逻辑从 watermark_engine.py 剥离到 packages/domain/watermark_config.py,实现了关注点分离,便于单元测试和复用。
  • 类型注解:新代码全面使用了 Python 类型注解,提高了代码可读性和 IDE 支持度。
  • 向后兼容:在 watermark_engine.py 中保留了薄包装层和导出,确保了重构对现有调用方的透明性。

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

### 📊 审查概览 - **整体评价**:需修改 - **严重问题数量**:3 个 - **一般建议数量**:1 个 ### ❌ 需修改的问题(严重) 1. **[packages/domain/watermark_config.py: calc_scroll_x] FFmpeg 表达式语法错误** - **问题描述**:函数返回的字符串为 `f"mod({output_width}-mod({speed}*t\\,{output_width}+{wm_width})"`。FFmpeg 的 `mod(x, y)` 函数需要两个参数,而此处生成的表达式 `mod( ... )` 外层只有一个参数,缺少第二个参数(模数),导致生成的 FFmpeg 滤镜命令无效。 - **修改建议**:检查并修正 `calc_scroll_x` 的返回逻辑。如果意图是计算跑马灯坐标,通常使用 `W - mod(t*speed, W+w)` 形式,无需外层再套 `mod`,或者补充缺失的第二个参数。同时需注意该函数返回值与 `build_image_watermark_filter` 内部实现逻辑不一致的问题。 2. **[packages/domain/watermark_config.py: build_text_watermark_filter] 特殊字符转义不完整** - **问题描述**:代码仅对冒号 `:` 和单引号 `'` 进行了转义,但未处理反斜杠 `\`。在 FFmpeg `drawtext` 滤镜中,反斜杠是转义字符。如果用户输入的文本包含 `\`(如 Windows 路径 `C:\Users` 或特定符号),未被转义会导致后续字符被误解析(如 `\n` 变为换行),破坏命令结构或导致渲染错误。 - **修改建议**:在替换列表中增加对 `\` 的转义,例如:`text.replace("\\", "\\\\")`。建议使用 `re.escape` 或更严谨的转义逻辑处理 FFmpeg 特殊字符。 3. **[packages/domain/watermark_config.py: WatermarkConfig.from_dict] 类型转换缺乏异常保护** - **问题描述**:在从字典读取配置时,直接使用 `float(...)` 和 `int(...)` 进行类型转换(如 `scale=float(...)`)。如果配置数据中包含非数字字符串(如 `"auto"` 或 `None`),将抛出 `ValueError` 或 `TypeError`,导致 Worker 进程崩溃。 - **修改建议**:添加 `try-except` 块捕获转换异常,记录错误日志并回退到默认值,或使用辅助函数进行安全的类型转换。 ### 💡 改进建议(一般) 1. **[packages/domain/watermark_config.py: build_image_watermark_filter] 水印高度估算逻辑偏差** - **具体内容**:代码在计算位置时使用 `wm_width` 代替未知的 `wm_height`(`calc_position(..., wm_width, wm_width, ...)`)。这假设水印是正方形的。对于非正方形图片(如宽横幅或高竖条),垂直方向的对齐(顶部/底部/居中)会产生偏差。虽然难以在预处理阶段获取精确高度,但建议至少在注释中明确此限制,或尝试读取图片头信息获取真实尺寸。 ### ✅ 良好实践 - **架构重构**:将核心逻辑从 `watermark_engine.py` 剥离到 `packages/domain/watermark_config.py`,实现了关注点分离,便于单元测试和复用。 - **类型注解**:新代码全面使用了 Python 类型注解,提高了代码可读性和 IDE 支持度。 - **向后兼容**:在 `watermark_engine.py` 中保留了薄包装层和导出,确保了重构对现有调用方的透明性。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-07-26 23:32:16 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia closed this pull request 2026-07-27 15:26:23 +08:00

🗑️ 预览环境已清理

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

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

🗑️ **预览环境已清理** PR #1001 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 16s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m10s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m39s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m43s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 2m13s
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 / PR Build Web Image (pull_request) Successful in 35s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 34s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m8s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 48s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m47s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m40s
AI Code Review / AI Code Review (pull_request) Successful in 6m39s
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 / Unit Tests (pull_request) Successful in 3m25s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m24s
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 22s

Pull request closed

Sign in to join this conversation.