fix(clips): 全面修复 Clips API 响应结构 — 替换 PR #1403 #1404
Reference in New Issue
Block a user
Delete Branch "fix/clips-api-response-structure"
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?
背景
前端工程师反馈 clips API 返回结果混乱:缺少关键字段(asset_id, status, start_time 等)、split/merge 响应格式不统一、无法获取素材视频URL。本 PR 替换之前的 #1403(仅加 asset_url),做完整修复。
改动总览
P0: EditorClipResponse 新增字段
P1: split/merge 响应统一
split 返回:
merge 返回:
P1: asset_url 实现
StorageService.get_download_url()生成 OSS 签名URLAssetRepository.find_by_id()查询素材 storage_key修改文件
schemas.pyclips.py替换关系
本 PR 完全替换 PR #1403(feat/clips-asset-url 分支),包含其所有功能并扩展修复。
验证
P0: EditorClipResponse 补全所有数据库字段 - 新增 start_time, transition_duration, asset_id, status, template_clip_config_id, created_at, updated_at - 新增 asset_url (OSS签名URL, 1小时有效) P1: split/merge 端点统一使用 EditorClipResponse - split 返回 {left_clip, right_clip} 均为 EditorClipResponse - merge 返回 {merged_clip, deleted_clip_ids} - 移除 dict[str, Any] 响应类型 P1: asset_url 签名URL解析 - 批量查询 Asset 表获取 storage_key - 使用 StorageService.get_download_url() 签名 - 列表/详情/split/merge 端点均支持 P2: ClipsFromAssetsResponse 补上 plan_id 字段🚀 预览环境已部署
- Remove unused 'from typing import Any' (Ruff F401) - Add 28 unit/integration tests covering: - _clip_to_response: enum conversion, datetime formatting, asset_url param - _build_asset_url_map: empty list, storage failure, asset not found, no storage_key, success path, exception handling, mixed scenarios - Route integration: list/detail/split/merge with asset URL resolution - Incremental coverage: 100% (95/95 added lines covered)CI全绿,自动审批通过。
CI全绿,自动审批通过。
【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
merge_draft_clips函数的返回值结构发生了重大变化。原代码直接返回合并后的片段属性(如id,plan_id等),而新代码将其包裹在merged_clip对象中,并新增了deleted_clip_ids字段。这会导致前端或调用方无法通过response.id获取数据,而是需要改为response.merged_clip.id。在未同步更新调用方的情况下,这将导致功能异常。💡 改进建议(不阻塞合并)
[apps/api/app/api/routes/templates_editor/clips.py: 22] 违反依赖倒置原则(DIP)
SQLAlchemyAssetRepository(from packages.adapters...),导致 API 层(应用层)直接依赖了具体的 Repository 实现(基础设施层)。这违反了整洁架构的分层原则,增加了耦合度。建议定义一个AssetRepositoryProtocol 或抽象基类,函数参数依赖该抽象接口,而非具体实现类。[apps/api/app/api/routes/templates_editor/clips.py: 280, 317] 移除 response_model 导致契约丢失
split_draft_clip和merge_draft_clips路由装饰器中移除了response_model参数。虽然代码能正常运行,但这会导致 FastAPI 失去对响应数据的自动验证、序列化保证以及 OpenAPI 文档的自动生成能力。建议定义明确的 Pydantic 响应模型(如SplitClipResponse)并应用,以确保 API 契约的严谨性。✅ 良好实践
_build_asset_url_map函数实现了批量查询素材(find_by_ids)并去重,有效避免了 N+1 查询问题,这是很好的性能实践。_clip_to_response函数使用了getattr配合默认值,能够很好地处理模型字段缺失或为 None 的情况,增强了代码的容错性。try-except块,并在异常时返回None或降级处理,避免了因第三方服务故障导致主流程中断。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-08-17 10:13:08 | 模型:
🗑️ 预览环境已清理
PR #1404 已关闭或合并,对应的预览环境已被清理。