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

Screenplay Service 技术栈合规性修复

日期:2026-01-29
类型:文档更新 + 规范修复
影响范围docs/requirements/backend/04-services/project/screenplay-service.md


变更概述

对 Screenplay Service 文档进行全面的技术栈合规性修复,使其符合 jointo-tech-stack 规范要求。


修复内容

1. 日志系统集成

问题:Service 类中完全没有使用日志系统

修复

  • 添加模块级 logger:logger = get_logger(__name__)
  • 所有关键操作添加日志记录:
    • INFO 级别:成功操作(创建、更新、删除)
    • WARNING 级别:业务异常(资源不存在、权限不足)
    • ERROR 级别:系统异常(使用 exc_info=True 记录堆栈)
    • DEBUG 级别:调试信息(版本创建、文件上传)

示例

logger.info(
    "创建文本剧本: 用户=%s, 名称=%s, 项目=%s",
    user_id, screenplay_data.name, screenplay_data.project_id
)

try:
    # 业务逻辑
    logger.info("文本剧本创建成功: ID=%s, 字数=%d", screenplay_id, word_count)
except Exception as e:
    logger.error(
        "创建文本剧本失败: 用户=%s, 错误=%s",
        user_id, str(e),
        exc_info=True  # 记录完整堆栈
    )
    raise

2. UUID 生成方式修复

问题:模型中使用 server_default=text("gen_random_uuid()") 生成 UUID

修复

  • 导入 generate_uuid_v7 函数
  • 所有主键字段使用 default=generate_uuid_v7
  • 应用层生成 UUID v7,符合规范

修改前

screenplay_id: UUID = Field(
    sa_column=Column(
        PG_UUID(as_uuid=True),
        primary_key=True,
        server_default=text("gen_random_uuid()")  # ❌ 数据库层生成
    )
)

修改后

from app.core.database import generate_uuid_v7

screenplay_id: UUID = Field(
    sa_column=Column(
        PG_UUID(as_uuid=True),
        primary_key=True,
        default=generate_uuid_v7  # ✅ 应用层生成
    )
)

3. 依赖注入修复

问题:Service 构造函数接收 db: Session(同步)

修复

  • 修改为 db: AsyncSession
  • 导入 from sqlalchemy.ext.asyncio import AsyncSession

修改前

from sqlalchemy.orm import Session

class ScreenplayService:
    def __init__(self, db: Session):  # ❌ 同步 Session
        self.db = db

修改后

from sqlalchemy.ext.asyncio import AsyncSession

class ScreenplayService:
    def __init__(self, db: AsyncSession):  # ✅ 异步 Session
        self.db = db

4. 时区处理统一

问题:使用 datetime.now(timezone.utc) 而非 datetime.now(UTC)

修复

  • 导入 from datetime import datetime, UTC
  • 所有时间戳字段使用 datetime.now(UTC)

修改前

from datetime import datetime

created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))  # ❌

修改后

from datetime import datetime, UTC

created_at = Column(DateTime, default=lambda: datetime.now(UTC))  # ✅

5. 类型注解完善

问题:部分方法参数使用 int 而非 UUID

修复

  • 所有 ID 参数统一使用 UUID 类型
  • 导入 from uuid import UUID

修改前

async def get_screenplays(
    self,
    project_id: int,  # ❌
    user_id: int,     # ❌
    ...
)

修改后

async def get_screenplays(
    self,
    project_id: UUID,  # ✅
    user_id: UUID,     # ✅
    ...
)

6. API 响应格式说明

新增:统一响应格式章节

{
  "success": true,
  "message": "操作成功",
  "data": {
    // 实际数据
  }
}

7. 测试规范章节

新增

  • 测试文件结构说明
  • 单元测试示例(Service、Repository)
  • 集成测试示例(API)
  • 测试运行命令(Docker 容器内执行)

8. 模型字段补充

新增has_tags 字段到以下模型

  • ScreenplayCharacter
  • ScreenplayScene
  • ScreenplayProp

用于标识元素是否有标签(年龄段、时代等)。


影响范围

文档变更

  • docs/requirements/backend/04-services/project/screenplay-service.md
    • 版本号:v2.1 → v2.2
    • 更新日期:2026-01-22 → 2026-01-29

代码变更(需要后续实施)

  • ⚠️ server/app/services/screenplay_service.py - 需要添加日志
  • ⚠️ server/app/models/screenplay.py - 需要修改 UUID 生成和时区
  • ⚠️ server/app/repositories/screenplay_repository.py - 需要添加日志
  • ⚠️ server/tests/unit/test_screenplay_service.py - 需要创建
  • ⚠️ server/tests/integration/test_screenplay_api.py - 需要创建

合规性检查清单

  • 日志系统(所有关键操作)
  • UUID 生成方式(应用层 generate_uuid_v7)
  • 依赖注入(AsyncSession)
  • 时区处理(datetime.now(UTC))
  • 错误日志(exc_info=True)
  • API 响应格式说明
  • 测试规范文档
  • 类型注解(UUID)
  • has_tags 字段

后续工作

  1. 实施代码修复

    • 创建 server/app/services/screenplay_service.py
    • 创建 server/app/models/screenplay.py
    • 创建 server/app/repositories/screenplay_repository.py
  2. 编写测试

    • 单元测试:test_screenplay_service.py
    • 单元测试:test_screenplay_repository.py
    • 集成测试:test_screenplay_api.py
  3. 数据库迁移

    • 添加 has_tags 字段到相关表

参考文档


变更人:AI Assistant
审核状态:待审核