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.
8.1 KiB
8.1 KiB
Timeline Service 技术栈规范符合性修订
日期: 2026-01-29
类型: 文档修订
影响范围: docs/requirements/backend/04-services/project/timeline-service.md
修订概述
对 timeline-service.md 文档进行全面修订,确保完全符合 jointo-tech-stack 技术栈规范。
修订内容
1. 添加日志系统 ✅
问题: 原文档代码示例完全没有使用日志
修订:
- 在
TimelineService类中添加模块级 logger - 所有关键操作添加日志记录(INFO 级别)
- 所有异常添加错误日志(ERROR 级别 +
exc_info=True) - 使用中文日志消息
- 使用 %-formatting 格式化
示例:
import logging
logger = logging.getLogger(__name__)
logger.info(
"获取时间轴数据 | 用户: %s | 项目: %s | 轨道类型: %s",
user_id,
project_id,
track_types or "全部"
)
logger.error(
"获取时间轴数据失败 | 项目: %s | 错误: %s",
project_id,
str(e),
exc_info=True
)
2. 完善异常处理 ✅
问题: 异常处理不完整,没有日志记录
修订:
- 所有 Service 方法添加 try-except 块
- 异常日志使用
exc_info=True记录堆栈 - 区分业务异常和系统异常
- 业务异常直接 raise,系统异常记录后 raise
3. 添加数据库设计章节 ✅
问题: 缺少 Model 层和数据库设计说明
修订:
- 添加完整的
StoryboardModel 定义 - 使用
TIMESTAMPTZ时间戳(ADR 006) - 应用层生成 UUID v7(
generate_uuid()) - 配置 Relationship(无物理外键,使用
primaryjoin) - 添加数据库迁移 SQL 示例
- 添加表级和列级注释
4. 引用完整性验证 ✅
问题: reorder_storyboards 没有验证分镜是否存在
修订:
- 添加
batch_exists()批量验证 - 使用事务
async with self.db.begin()确保原子性 - 验证失败时抛出
NotFoundError
示例:
# 验证所有分镜是否存在
storyboard_ids = [UUID(sid) for sid in reorder_data.storyboard_orders.keys()]
storyboards_exist = await self.storyboard_repo.batch_exists(storyboard_ids)
missing_ids = [
str(sid) for sid, exists in storyboards_exist.items() if not exists
]
if missing_ids:
raise NotFoundError(f"分镜不存在: {missing_ids}")
# 使用事务批量更新
async with self.db.begin():
for storyboard_id, new_order in reorder_data.storyboard_orders.items():
await self.storyboard_repo.update(...)
5. 统一 API 响应格式 ✅
问题: API 接口直接返回数据对象
修订:
- 所有 API 使用
ApiResponse统一格式(RFC-135) - 添加完整的 API 实现代码
- 添加 API 日志记录
- 响应示例使用 UUID v7 格式
示例:
return ApiResponse.success_response(
data=timeline_data,
message="时间轴数据获取成功"
)
6. 时间戳规范 ✅
问题: 没有明确时间戳字段类型
修订:
- Model 层使用
datetime.now(timezone.utc) - 数据库使用
TIMESTAMPTZ(ADR 006 强制规范) - 添加时区说明注释
7. UUID v7 生成说明 ✅
问题: 没有说明 UUID 如何生成
修订:
- 明确应用层生成(
generate_uuid()) - 禁止数据库默认值(
server_default) - 添加代码示例
8. Relationship 配置说明 ✅
问题: 使用了关联但没有说明如何配置
修订:
- 添加完整的 Relationship 配置示例
- 使用
primaryjoin和foreign_keys(因为无物理外键) - 添加 TYPE_CHECKING 导入
9. 性能优化增强 ✅
问题: 缓存示例可能暗示使用 loguru
修订:
- 缓存方法添加日志记录(使用标准库
logging) - 添加批量操作优化示例
- 添加异常处理
10. 技术栈约束章节 ✅
新增:
- 添加"技术栈约束"章节
- 列出 7 条核心规范
- 更新数据流图说明
技术栈符合度检查
✅ 符合项
- 异步编程: 所有方法使用
async/await - 日志系统: 使用标准库
logging,禁止loguru - UUID v7: 应用层生成,禁止数据库默认值
- 无物理外键: 应用层验证引用完整性
- 时间戳: 使用
TIMESTAMPTZ(ADR 006) - 统一响应: 所有 API 使用
ApiResponse格式 - 事务处理: 批量操作使用
async with self.session.begin() - 仓储模式: 正确使用 Repository 层
- 依赖注入: Service 层正确注入 Repository
- Schema 定义: 使用 Pydantic BaseModel
- 软删除: 使用
deleted_at字段 - 索引: 所有关联字段创建索引
文档结构优化
新增章节
- 技术栈约束: 列出核心规范
- 数据库设计: Model 定义和迁移脚本
- 性能优化: 缓存、分页、批量操作
更新章节
- 服务实现: 添加完整日志和异常处理
- API 接口: 添加完整 API 实现代码
- Schema 定义: 添加示例和说明
- 相关文档: 添加 ADR、RFC 链接
代码示例改进
日志记录
修订前:
# 没有日志
has_permission = await self.project_repo.check_user_permission(...)
修订后:
logger.info(
"获取时间轴数据 | 用户: %s | 项目: %s",
user_id,
project_id
)
has_permission = await self.project_repo.check_user_permission(...)
if not has_permission:
logger.warning("权限不足 | 用户: %s | 项目: %s", user_id, project_id)
raise PermissionError("没有权限访问此项目")
引用完整性验证
修订前:
# 直接更新,没有验证
for storyboard_id, new_order in reorder_data.storyboard_orders.items():
await self.storyboard_repo.update(...)
修订后:
# 批量验证
storyboard_ids = [UUID(sid) for sid in reorder_data.storyboard_orders.keys()]
storyboards_exist = await self.storyboard_repo.batch_exists(storyboard_ids)
missing_ids = [str(sid) for sid, exists in storyboards_exist.items() if not exists]
if missing_ids:
raise NotFoundError(f"分镜不存在: {missing_ids}")
# 使用事务
async with self.db.begin():
for storyboard_id, new_order in reorder_data.storyboard_orders.items():
await self.storyboard_repo.update(...)
API 响应格式
修订前:
return timeline_data # 直接返回数据
修订后:
return ApiResponse.success_response(
data=timeline_data,
message="时间轴数据获取成功"
)
影响范围
文档
- ✅
docs/requirements/backend/04-services/project/timeline-service.md
代码实现
- ⚠️ 需要根据修订后的文档实现
TimelineService - ⚠️ 需要实现
StoryboardRepository.batch_exists() - ⚠️ 需要实现 API 路由(
app/api/v1/timeline.py)
后续工作
1. 实现 TimelineService
# 创建服务文件
touch server/app/services/timeline_service.py
# 实现完整的 TimelineService 类
# 包含日志、异常处理、引用完整性验证
2. 实现 Repository 方法
# 在 StoryboardRepository 中添加
# - batch_exists()
# - get_by_project() with pagination
3. 实现 API 路由
# 创建 API 文件
touch server/app/api/v1/timeline.py
# 实现 4 个 API 端点
# - GET /projects/{project_id}/timeline
# - POST /projects/{project_id}/timeline/reorder
# - GET /projects/{project_id}/timeline/tracks/{track_type}
# - GET /projects/{project_id}/timeline/items/time-range
4. 编写测试
# 单元测试
touch server/tests/unit/test_timeline_service.py
# 集成测试
touch server/tests/integration/test_timeline_api.py
相关文档
修订人: Kiro AI
审核状态: ✅ 已完成
文档版本: v3.0