# 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 格式化 **示例**: ```python 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 层和数据库设计说明 **修订**: - 添加完整的 `Storyboard` Model 定义 - 使用 `TIMESTAMPTZ` 时间戳(ADR 006) - 应用层生成 UUID v7(`generate_uuid()`) - 配置 Relationship(无物理外键,使用 `primaryjoin`) - 添加数据库迁移 SQL 示例 - 添加表级和列级注释 ### 4. 引用完整性验证 ✅ **问题**: `reorder_storyboards` 没有验证分镜是否存在 **修订**: - 添加 `batch_exists()` 批量验证 - 使用事务 `async with self.db.begin()` 确保原子性 - 验证失败时抛出 `NotFoundError` **示例**: ```python # 验证所有分镜是否存在 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 格式 **示例**: ```python 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 条核心规范 - 更新数据流图说明 --- ## 技术栈符合度检查 ### ✅ 符合项 1. **异步编程**: 所有方法使用 `async/await` 2. **日志系统**: 使用标准库 `logging`,禁止 `loguru` 3. **UUID v7**: 应用层生成,禁止数据库默认值 4. **无物理外键**: 应用层验证引用完整性 5. **时间戳**: 使用 `TIMESTAMPTZ`(ADR 006) 6. **统一响应**: 所有 API 使用 `ApiResponse` 格式 7. **事务处理**: 批量操作使用 `async with self.session.begin()` 8. **仓储模式**: 正确使用 Repository 层 9. **依赖注入**: Service 层正确注入 Repository 10. **Schema 定义**: 使用 Pydantic BaseModel 11. **软删除**: 使用 `deleted_at` 字段 12. **索引**: 所有关联字段创建索引 --- ## 文档结构优化 ### 新增章节 1. **技术栈约束**: 列出核心规范 2. **数据库设计**: Model 定义和迁移脚本 3. **性能优化**: 缓存、分页、批量操作 ### 更新章节 1. **服务实现**: 添加完整日志和异常处理 2. **API 接口**: 添加完整 API 实现代码 3. **Schema 定义**: 添加示例和说明 4. **相关文档**: 添加 ADR、RFC 链接 --- ## 代码示例改进 ### 日志记录 **修订前**: ```python # 没有日志 has_permission = await self.project_repo.check_user_permission(...) ``` **修订后**: ```python 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("没有权限访问此项目") ``` ### 引用完整性验证 **修订前**: ```python # 直接更新,没有验证 for storyboard_id, new_order in reorder_data.storyboard_orders.items(): await self.storyboard_repo.update(...) ``` **修订后**: ```python # 批量验证 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 响应格式 **修订前**: ```python return timeline_data # 直接返回数据 ``` **修订后**: ```python 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 ```bash # 创建服务文件 touch server/app/services/timeline_service.py # 实现完整的 TimelineService 类 # 包含日志、异常处理、引用完整性验证 ``` ### 2. 实现 Repository 方法 ```bash # 在 StoryboardRepository 中添加 # - batch_exists() # - get_by_project() with pagination ``` ### 3. 实现 API 路由 ```bash # 创建 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. 编写测试 ```bash # 单元测试 touch server/tests/unit/test_timeline_service.py # 集成测试 touch server/tests/integration/test_timeline_api.py ``` --- ## 相关文档 - [jointo-tech-stack Skill](../../../.claude/skills/jointo-tech-stack/SKILL.md) - [后端技术栈规范](../../../.claude/skills/jointo-tech-stack/references/backend.md) - [数据库设计规范](../../../.claude/skills/jointo-tech-stack/references/database.md) - [日志使用规范](../../../.claude/skills/jointo-tech-stack/references/logging.md) - [ADR 006: TIMESTAMPTZ 时间戳规范](../../architecture/adrs/006-timestamptz-for-event-timestamps.md) --- **修订人**: Kiro AI **审核状态**: ✅ 已完成 **文档版本**: v3.0