feat(phase2): 模板发布版本化 + 回滚能力 #646
Reference in New Issue
Block a user
Delete Branch "feat/phase2-publish-versioning"
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?
背景
Phase 2 发布流程打通:模板编辑器草稿 → 正式模板的完整链路,增加版本号、状态流转、回滚能力。
改动
新增端点(2个)
GET /templates/{id}/editor/versions— 版本历史列表POST /templates/{id}/editor/rollback— 回滚到指定版本测试
🚀 预览环境已部署
代码审查结果 - PR #646
⚠️ 问题(2个需要修改)
apps/api/app/services/edit_template_service.py 第876行:事务原子性失效导致数据不一致风险。
rollback_to_version方法中,虽然使用了try...except并在异常时调用self._db.rollback(),但事务内部调用的self._template_repo.update()和self._clip_config_repo.delete/create()方法内部均显式调用了self.session.commit()。这意味着在rollback操作的多个步骤中,如果中间某一步(如恢复 clip_configs)失败,之前的步骤(如更新 version、删除旧 configs)已经提交到数据库,无法回滚。这将导致模板处于“版本号已增加但配置丢失”的损坏状态。update,delete,create)在参与复杂事务时不应自动commit,或者使用 SQLAlchemy 的begin_nested()/savepoint,或者将所有数据库操作放在一个事务上下文管理器中,仅在 Service 层最后统一commit。apps/api/app/services/edit_template_service.py 第856行:异常处理逻辑错误。
rollback_to_version的循环中,except (ValueError, ImportError)块内重新执行了from packages.domain.template_clip_config import TransitionEffect。如果发生ImportError(模块导入失败),在 except 块中再次导入通常也会失败,这并不能解决问题,且掩盖了真正的错误原因。此外,将ImportError与数值转换的ValueError混在一起处理是不恰当的。CUT),可能导致回滚后的数据与历史版本不一致;且如果真的发生导入错误,会导致难以排查的循环或崩溃。ValueError来处理不兼容的枚举值,并考虑记录警告日志以便追踪数据兼容性问题。💡 建议(3个可选)
apps/api/app/services/edit_template_service.py 第870行:N+1 查询性能问题。
clip_configs时,使用了for cfg in old_configs: self._clip_config_repo.delete(cfg.id),这会在循环中执行多次 DELETE 语句。建议在 Repository 层实现支持WHERE template_id = ?的批量删除方法,以减少数据库交互次数。apps/api/app/services/edit_template_service.py 第718行 & 第828行:代码重复。
publish_draft_to_template和rollback_to_version中存在大量相同的代码逻辑,用于将TemplateClipConfig对象列表转换为字典列表(快照)。建议将这段逻辑提取为TemplateClipConfig类的一个实例方法(如to_snapshot_dict())或一个独立的辅助函数,以提高代码可维护性。apps/api/app/api/routes/templates_editor.py 第363行:冗余查询。
rollback_template接口中,调用tpl_svc.rollback_to_version完成回滚后,又立即调用tpl_svc.list_clip_configs仅为了获取clip_count。建议优化 Service 层返回值,让rollback_to_version直接返回包含 clip_count 的结果对象,避免额外的数据库查询。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-07-20 17:59:55 | 模型:
CI全绿,自动审批通过。
CI全绿,自动审批通过。