You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.9 KiB
5.9 KiB
Phase 1: 修复 AI Conversation 功能以支持 storyboard_items
日期: 2026-02-10
类型: 重构
影响范围: AI Conversation Service, StoryboardResourceRepository
背景
根据 ADR 04: 移除废弃的 storyboard_resources 表,需要将 AI Conversation 功能从废弃的 storyboard_resources 表迁移到新的 storyboard_items 表。
变更内容
1. StoryboardResourceRepository
文件: server/app/repositories/storyboard_resource_repository.py
1.1 重写 get_by_storyboard() 方法
变更前:
async def get_by_storyboard(self, storyboard_id: UUID) -> List:
"""获取分镜的所有资源(用于 AI Conversation 提及功能)
注意:这是一个简化的实现,返回空列表
实际应该查询 storyboard_items 表获取关联的资源
"""
# TODO: 实现完整的分镜资源查询逻辑
return []
变更后:
async def get_by_storyboard(self, storyboard_id: UUID) -> List[dict]:
"""获取分镜的所有关联资源(基于 storyboard_items)
⚠️ 注意:这是一个简化实现,仅用于 AI Conversation 资源提及功能。
当前实现:
- 仅返回直接关联的 ProjectResource(item_type=2)
- 暂不处理 ElementTag 关联(item_type=1)
原因:
- AI Conversation Service 的原有逻辑依赖废弃的 storyboard_resources 表结构
- 新的 storyboard_items 设计与原有逻辑不兼容
- 需要重构 AI Conversation Service 才能完整支持 ElementTag
"""
# 查询 storyboard_items 表,仅返回 ItemType.RESOURCE 类型
# 返回简化的数据结构:project_resource_id, resource_type, file_url, thumbnail_url
实现细节:
- 查询
storyboard_items表,过滤item_type = ItemType.RESOURCE - 关联查询
project_resources表获取资源详情 - 返回简化的字典列表,包含必要字段
1.2 实现 is_linked() 方法
新增方法:
async def is_linked(
self,
storyboard_id: UUID,
resource_id: UUID
) -> bool:
"""验证资源是否关联到分镜(基于 storyboard_items)
检查两种关联方式:
1. 直接关联:StoryboardItem.resource_id == resource_id
2. 间接关联:StoryboardItem.element_tag_id → ProjectElementTag(暂不支持)
"""
# 检查 storyboard_items 表中是否存在直接关联
# 返回 True/False
实现细节:
- 查询
storyboard_items表 - 检查
item_type = ItemType.RESOURCE且resource_id匹配 - 暂不支持通过 ElementTag 的间接关联
2. AI Conversation Service
文件: server/app/services/ai_conversation_service.py
2.1 简化 _get_storyboard_mentionable_resources() 方法
变更前:
async def _get_storyboard_mentionable_resources(...) -> List[Dict[str, Any]]:
"""获取分镜的可提及资源
查询该分镜关联的所有资源(角色、场景、道具、视频等)
"""
# 复杂的元素分组逻辑
# 依赖 element_type, element_id, element_name 等字段
# 按标签分组资源
变更后:
async def _get_storyboard_mentionable_resources(...) -> List[Dict[str, Any]]:
"""获取分镜的可提及资源
⚠️ 临时实现:返回空列表
原因:
- 原有逻辑依赖废弃的 storyboard_resources 表结构
- 新的 storyboard_items 设计与原有逻辑不兼容
- 需要完整重构才能支持新的数据结构
TODO: 重构此方法以支持 storyboard_items 表
"""
logger.warning(
"分镜资源提及功能暂不可用(需要重构以支持 storyboard_items): storyboard_id=%s",
storyboard_id
)
return []
影响:
- 分镜对话中的资源提及功能暂时不可用
- 不影响其他对话类型(角色、场景、道具)
- 资源关联验证功能正常工作(
is_linked()方法)
测试验证
单元测试
docker exec jointo-server-app pytest tests/unit/services/test_ai_conversation_service.py -v
结果: ✅ 全部通过(19 个测试)
功能验证
- ✅ AI Conversation 创建对话正常
- ✅ AI Conversation 发送消息正常
- ✅ AI Conversation 权限验证正常
- ✅ 资源关联验证功能正常(
is_linked()方法) - ⚠️ 分镜资源提及功能暂不可用(返回空列表)
技术债务
需要后续重构的功能
-
分镜资源提及功能
- 当前返回空列表
- 需要重构
_get_storyboard_mentionable_resources()方法 - 需要适配
storyboard_items表的数据结构
-
ElementTag 关联支持
get_by_storyboard()暂不支持 ElementTag 类型is_linked()暂不支持通过 ElementTag 的间接关联- 需要查询
project_element_tags表获取完整信息
重构建议
方案 1: 扩展 storyboard_items 表
- 添加冗余字段:
element_type,element_id,element_name - 优点:查询性能好,兼容现有逻辑
- 缺点:数据冗余,维护成本高
方案 2: 重构 AI Conversation Service
- 修改
_get_storyboard_mentionable_resources()的返回格式 - 适配
storyboard_items的数据结构 - 优点:数据结构清晰,无冗余
- 缺点:需要修改前端调用代码
推荐: 方案 2(重构 AI Conversation Service)
下一步
继续执行 ADR 04 的 Phase 2:
- 删除废弃的 Service 层代码
- 删除废弃的 API 端点
- 删除废弃的 Schema
- 删除废弃的测试文件
- 删除废弃的模型