feat: CosyVoice 配置 + VoiceCloneProfile/TTSJob 领域模型 (task 3.01-3.03) #161

Merged
xiaoxia merged 1 commits from feature/cosyvoice-config-models into develop 2026-07-02 07:56:48 +08:00
Owner

阶段 3 CosyVoice 集成 - 任务 3.01-3.03

3.01 CosyVoice 配置

  • SharedSettings 添加 api_key/base_url/model/voice/sample_rate/format
  • 更新 .env.example 和 .env.production.example

3.02 VoiceCloneProfile 领域模型

  • 音色克隆档案实体,状态机: pending → processing → ready/failed → disabled
  • VoiceCloneProfileRepository 端口接口

3.03 TTSJob 领域模型

  • TTS 任务实体,关联 VoiceCloneProfile
  • 状态机: pending → processing → completed/failed → cancelled
  • TTSJobRepository 端口接口

测试

  • 65 个单元测试全部通过
## 阶段 3 CosyVoice 集成 - 任务 3.01-3.03 ### 3.01 CosyVoice 配置 - SharedSettings 添加 api_key/base_url/model/voice/sample_rate/format - 更新 .env.example 和 .env.production.example ### 3.02 VoiceCloneProfile 领域模型 - 音色克隆档案实体,状态机: pending → processing → ready/failed → disabled - VoiceCloneProfileRepository 端口接口 ### 3.03 TTSJob 领域模型 - TTS 任务实体,关联 VoiceCloneProfile - 状态机: pending → processing → completed/failed → cancelled - TTSJobRepository 端口接口 ### 测试 - 65 个单元测试全部通过
xiaoxia added 1 commit 2026-07-02 07:51:35 +08:00
feat(phase3): CosyVoice 配置 + VoiceCloneProfile/TTSJob 领域模型
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 173h2m54s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Failing after 173h2m59s
Deploy / Deploy Staging (push) Failing after 173h22m24s
CI/CD Pipeline / Frontend Lint (push) Failing after 173h22m54s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 173h23m2s
f7c8b441d6
Task 3.01: CosyVoice 配置
- 在 SharedSettings 中添加 CosyVoice 配置字段
- 更新 .env.example 和 .env.production.example

Task 3.02: VoiceCloneProfile 领域模型
- 创建 VoiceCloneProfile 实体(音色克隆档案)
- 状态机: pending → processing → ready/failed → disabled
- 支持重试机制(retry_count/max_retries)
- 创建 VoiceCloneProfileRepository 端口接口

Task 3.03: TTSJob 领域模型
- 创建 TTSJob 实体(TTS 任务)
- 关联 VoiceCloneProfile(voice_clone_profile_id)
- 状态机: pending → processing → completed/failed → cancelled
- 支持重试机制
- 创建 TTSJobRepository 端口接口

单元测试:
- VoiceCloneProfile: 31 个测试用例
- TTSJob: 34 个测试用例
- 全部 65 个测试通过

遵循六边形架构: Domain → Port → Adapter
Author
Owner

PR #161 代码审计报告

分支: feature/cosyvoice-config-models → develop
提交: f7c8b44
变更: 9 文件,+1343 / -0
结论: 有条件通过(无 P0/P1,3 P2 + 5 P3,不阻塞合并)


审查范围

文件 类型 行数
packages/shared/config.py 配置 +8
.env.example 配置模板 +8
.env.production.example 生产配置模板 +8
packages/domain/voice_clone_profile.py 领域模型 +261
packages/domain/tts_job.py 领域模型 +299
packages/ports/voice_clone_profile_repository.py 仓储端口 +51
packages/ports/tts_job_repository.py 仓储端口 +58
tests/unit/test_voice_clone_profile.py 测试 +306
tests/unit/test_tts_job.py 测试 +344

审查结论

1. Hexagonal 架构 优秀

  • Domain 层:纯 Python dataclass,无框架依赖,业务规则内聚
  • Port 层:使用 Protocol 定义仓储接口,标准 Python 鸭子类型
  • Config 层:Pydantic Settings 统一管理,环境变量映射清晰
  • 完全符合项目的六边形架构规范

2. 状态机设计 严谨

  • VoiceCloneProfile: PENDING → PROCESSING → READY/FAILED → DISABLED,支持 FAILED → PENDING 重试
  • TTSJob: PENDING → PROCESSING → COMPLETED/FAILED → CANCELLED,支持 FAILED → PENDING 重试
  • 所有转换通过 _VALID_TRANSITIONS 白名单控制,非法转换抛 ValueError
  • mark_* 方法封装了转换 + 副作用(清除错误、设置时间戳等)

3. 配置安全性 合理

  • API Key 通过环境变量注入,不硬编码
  • .env.example 使用占位符 your-cosyvoice-api-key
  • .env.production.example 使用 CHANGE_ME_* 前缀,提示明确
  • 无敏感信息泄露风险

4. 测试覆盖 充分

  • VoiceCloneProfile: 31 个测试(创建/校验/状态转换/重试/序列化)
  • TTSJob: 34 个测试(创建/校验/状态转换/重试/序列化/格式化)
  • 边界条件覆盖:空值、空白、超长、非法枚举、非法转换、重试上限

问题清单

P2(建议修复,不阻塞合并)

# 严重度 文件 问题 建议
P2-1 P2 voice_clone_profile.py + tts_job.py max_retries 未校验负值 添加 if max_retries < 0: raise ValueError
P2-2 P2 tts_job.py sample_rate 未校验正整数 添加 if sample_rate <= 0: raise ValueError
P2-3 P2 tts_job.py format 参数遮蔽 Python 内置函数名 建议改名为 output_formataudio_format

P3(可忽略)

# 严重度 文件 问题
P3-1 P3 两文件 StrEnum 兼容 polyfill 重复代码,应抽取到 packages/shared/
P3-2 P3 两文件 metadata: dict 缺少类型参数,应为 dict[str, Any]
P3-3 P3 voice_clone_profile.py source_audio_url 未校验 URL 格式
P3-4 P3 tts_job_repository.py 缺少 list_by_project 查询方法,后续大概率需要
P3-5 P3 两文件 TERMINAL_STATUSES 包含 FAILED,但 FAILED 可重试回 PENDING —— "终态" 语义不严格(建议改名为 FINAL_STATUSES 或文档说明)

亮点

  1. 领域模型纯净度高 — 无 ORM 框架依赖,纯 dataclass + 业务逻辑,可独立测试
  2. 状态机设计完备 — 白名单转换 + 语义化 mark 方法 + 重试机制 + 幂等性保证
  3. 防御性编程 — 所有字符串输入 strip、枚举转换 try/except、空值校验
  4. 测试命名规范 — 中文 docstring 清晰描述测试意图
  5. Repository 端口设计合理 — CRUD + 按用户/状态/档案查询,满足初期需求

结论

有条件通过 — 无 P0/P1,代码质量优秀,符合 Hexagonal 架构规范。3 个 P2 建议下一轮修复,不阻塞合并。Mergeable=True,可直接合并。

## PR #161 代码审计报告 **分支**: feature/cosyvoice-config-models → develop **提交**: f7c8b44 **变更**: 9 文件,+1343 / -0 **结论**: ✅ **有条件通过**(无 P0/P1,3 P2 + 5 P3,不阻塞合并) --- ### 审查范围 | 文件 | 类型 | 行数 | |------|------|------| | `packages/shared/config.py` | 配置 | +8 | | `.env.example` | 配置模板 | +8 | | `.env.production.example` | 生产配置模板 | +8 | | `packages/domain/voice_clone_profile.py` | 领域模型 | +261 | | `packages/domain/tts_job.py` | 领域模型 | +299 | | `packages/ports/voice_clone_profile_repository.py` | 仓储端口 | +51 | | `packages/ports/tts_job_repository.py` | 仓储端口 | +58 | | `tests/unit/test_voice_clone_profile.py` | 测试 | +306 | | `tests/unit/test_tts_job.py` | 测试 | +344 | --- ### 审查结论 #### 1. Hexagonal 架构 ✅ 优秀 - **Domain 层**:纯 Python dataclass,无框架依赖,业务规则内聚 - **Port 层**:使用 `Protocol` 定义仓储接口,标准 Python 鸭子类型 - **Config 层**:Pydantic Settings 统一管理,环境变量映射清晰 - 完全符合项目的六边形架构规范 #### 2. 状态机设计 ✅ 严谨 - VoiceCloneProfile: `PENDING → PROCESSING → READY/FAILED → DISABLED`,支持 `FAILED → PENDING` 重试 - TTSJob: `PENDING → PROCESSING → COMPLETED/FAILED → CANCELLED`,支持 `FAILED → PENDING` 重试 - 所有转换通过 `_VALID_TRANSITIONS` 白名单控制,非法转换抛 ValueError - `mark_*` 方法封装了转换 + 副作用(清除错误、设置时间戳等) #### 3. 配置安全性 ✅ 合理 - API Key 通过环境变量注入,不硬编码 - `.env.example` 使用占位符 `your-cosyvoice-api-key` - `.env.production.example` 使用 `CHANGE_ME_*` 前缀,提示明确 - 无敏感信息泄露风险 #### 4. 测试覆盖 ✅ 充分 - VoiceCloneProfile: 31 个测试(创建/校验/状态转换/重试/序列化) - TTSJob: 34 个测试(创建/校验/状态转换/重试/序列化/格式化) - 边界条件覆盖:空值、空白、超长、非法枚举、非法转换、重试上限 --- ### 问题清单 #### P2(建议修复,不阻塞合并) | # | 严重度 | 文件 | 问题 | 建议 | |---|--------|------|------|------| | P2-1 | P2 | voice_clone_profile.py + tts_job.py | `max_retries` 未校验负值 | 添加 `if max_retries < 0: raise ValueError` | | P2-2 | P2 | tts_job.py | `sample_rate` 未校验正整数 | 添加 `if sample_rate <= 0: raise ValueError` | | P2-3 | P2 | tts_job.py | `format` 参数遮蔽 Python 内置函数名 | 建议改名为 `output_format` 或 `audio_format` | #### P3(可忽略) | # | 严重度 | 文件 | 问题 | |---|--------|------|------| | P3-1 | P3 | 两文件 | StrEnum 兼容 polyfill 重复代码,应抽取到 `packages/shared/` | | P3-2 | P3 | 两文件 | `metadata: dict` 缺少类型参数,应为 `dict[str, Any]` | | P3-3 | P3 | voice_clone_profile.py | `source_audio_url` 未校验 URL 格式 | | P3-4 | P3 | tts_job_repository.py | 缺少 `list_by_project` 查询方法,后续大概率需要 | | P3-5 | P3 | 两文件 | `TERMINAL_STATUSES` 包含 FAILED,但 FAILED 可重试回 PENDING —— "终态" 语义不严格(建议改名为 `FINAL_STATUSES` 或文档说明) | --- ### 亮点 1. **领域模型纯净度高** — 无 ORM 框架依赖,纯 dataclass + 业务逻辑,可独立测试 2. **状态机设计完备** — 白名单转换 + 语义化 mark 方法 + 重试机制 + 幂等性保证 3. **防御性编程** — 所有字符串输入 strip、枚举转换 try/except、空值校验 4. **测试命名规范** — 中文 docstring 清晰描述测试意图 5. **Repository 端口设计合理** — CRUD + 按用户/状态/档案查询,满足初期需求 --- ### 结论 **✅ 有条件通过** — 无 P0/P1,代码质量优秀,符合 Hexagonal 架构规范。3 个 P2 建议下一轮修复,不阻塞合并。Mergeable=True,可直接合并。
xiaoxia merged commit e7b25abb48 into develop 2026-07-02 07:56:48 +08:00
Sign in to join this conversation.