阶段3 任务3.06:TTS 合成 API #166
Reference in New Issue
Block a user
Delete Branch "feature/task-306-tts-api"
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?
内容
阶段3 任务3.06 — TTS 合成 API(/api/v1/tts)
变更
测试
- POST /api/v1/tts/synthesize: create TTS job (status=pending) - GET /api/v1/tts/jobs: list user's jobs (page/page_size pagination) - GET /api/v1/tts/jobs/{job_id}: get job details - GET /api/v1/tts/jobs/{job_id}/status: query status for polling - DELETE /api/v1/tts/jobs/{job_id}: delete job (soft delete) Includes: - Schema: TTSSynthesizeRequest, TTSJobResponse, ListTTSJobResponse, TTSStatusResponse - Use Cases: CreateTTSJob, ListTTSJobs, GetTTSJob, GetTTSJobStatus, DeleteTTSJob - SQLAlchemy adapter: SQLAlchemyTTSJobRepository - ORM model: TTSJobModel - Alembic migration: 020_add_tts_jobs_table - Unit tests: 14 tests covering all use cases CosyVoice API calls deferred to task 3.07. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>PR #166 审查报告 — 任务 3.06 TTS 合成 API
PR: #166
分支:
feature/task-306-tts-api→developCommit:
e29a698变更: 9 文件,+868 / -0
结论: ✅ 有条件通过(0 P0 / 0 P1 / 1 P2 / 4 P3)
mergeable: ✅ True
一、审查要点逐项验证
✅ 1. 分页参数使用 page/page_size 风格
routes/tts.py第 82-83 行:page: int = Query(default=1, ge=1),page_size: int = Query(default=20, ge=1, le=100)skip = (page - 1) * page_size后传给 Use CaseListTTSJobResponse包含page和page_size字段✅ 2. TTS 状态机符合领域模型
pending → processing → completed / failed,failed → pending(重试),cancelled为终态_VALID_TRANSITIONS严格定义合法转换mark_processing()(记录 started_at)/mark_completed()(记录 output_audio_url 等)/mark_failed()/mark_cancelled()/prepare_retry()create()工厂方法有参数校验:user_id 非空、input_text 非空且 ≤10000 字符、format 限定 mp3/wav/pcm✅ 3. API 认证/鉴权正确
get_current_user获取认证用户job.user_id != user_id→ 抛出TTSJobNotFoundError✅ 4. 错误处理完善
TTSJobNotFoundError→ GET/{id}、GET/{id}/status、DELETEValueError用于参数校验和非法状态转换✅ 5. 软删除实现正确
delete()设置status = "deleted"get()和list_by_user()均过滤status != "deleted"✅ 6. Hexagonal 架构分层合理
✅ 7. Alembic 迁移正确
revision = "020",down_revision = "019"— 链路正确(接续 PR #165 的 019)user_id、status有索引✅ 8. 单元测试覆盖充分
✅ 9. CosyVoice API 调用确实未实现
pending,不自动转processing二、发现的问题
P2-1:Schema 中
speed和output_name参数被静默丢弃schemas/tts.py+routes/tts.pyTTSSynthesizeRequest定义了speed(0.5-2.0)和output_name字段,但路由层synthesize()未将这两个参数传递给CreateTTSJobUseCase.execute();Use Case、领域模型、ORM Model 均无对应字段speed和output_name被完全忽略,不会报错也不会生效。当任务 3.07 实现 CosyVoice API 时需要这些参数TTSJob领域模型和数据库中预留speed和output_name字段,或在 Schema 中标注为"预留字段,当前版本暂不支持"P3-1:
metadata_alias 命名模式metadata_+alias="metadata"映射extra_meta风格更清晰,但当前不影响功能P3-2:软删除不更新
updated_atdelete()仅设置status = "deleted",未更新updated_atP3-3:
format字段遮蔽 Python 内置函数名TTSJobdataclass 和TTSJobModel中使用format作为字段名format不是 Python 关键字,但遮蔽了内置format()函数output_format或audio_formatP3-4:缺少 retry 端点
is_retryable/prepare_retry),但 API 层未暴露 retry 端点三、亮点
page/page_size风格,修正了 PR #165 的 P2 问题get_current_user+ Use Case 层user_id校验TTSStatusResponse轻量版用于轮询,TTSJobResponse完整版用于详情,TTSSynthesizeResponse简洁创建响应list_by_profile:Repository 预留按克隆档案查询 TTS 任务的能力,为后续集成做准备四、总结
speed/output_name参数被静默丢弃结论: ✅ 有条件通过 — 代码质量高,架构清晰,核心功能完整,且主动修正了 PR #165 的分页问题。P2 建议在任务 3.07 实现 CosyVoice API 时一并补充字段,不阻塞当前合并。
可合并: ✅ mergeable=True