feat: 扩展生成任务API支持模板模式(方案A) #109

Merged
xiaoxia merged 2 commits from feat/generation-api-extension into develop 2026-06-29 17:29:06 +08:00
Owner

概述

方案A实现:后端扩展3处API,支持前端模板中心化模型。

改动

1. POST /api/v1/generation/tasks — 扩展创建接口

  • project_id 改为可选(与 template_id 二选一)
  • asset_library_id 改为可选(与 asset_ids/title_ids/voice_ids 二选一)
  • 新增 template_idasset_ids[]title_ids[]voice_ids[]
  • 模板模式下从 asset_ids 反查 project 和 library

2. GET /api/v1/tasks + GET /api/v1/generation/tasks — 用户级列表

  • 新增跨 project 的用户级任务列表端点

3. POST /api/v1/tasks/{task_id}/retry — 简化重试

  • 新增通过 task_id 直接重试失败任务的端点
  • 保留原有端点(向后兼容)

涉及文件(10个)

文件 改动
Domain generation_task.py 新增6字段,放宽校验
Application generation_tasks.py Command新增字段
Ports generation_task_repository.py 新增list_by_user
Adapter models.py 新列+索引
Adapter generation_task_repository.py 新字段+list_by_user+N+1修复
Schema generation_task.py 双模式校验
Schema task_center.py UserTaskResponse
Route generation_tasks.py async修复+新端点
Route task_center.py 用户级端点+简化重试
Migration 015_add_generation_task_extensions.py 新列+索引

额外修复

  • asset_repository.get() latent bug(返回coroutine而非Asset)
  • list_by_project N+1查询优化
  • StrEnum/plain string 状态兼容

向后兼容

所有旧端点和参数不变,新增字段均有默认值。

@代码审计 请review。

## 概述 方案A实现:后端扩展3处API,支持前端模板中心化模型。 ## 改动 ### 1. POST /api/v1/generation/tasks — 扩展创建接口 - `project_id` 改为可选(与 `template_id` 二选一) - `asset_library_id` 改为可选(与 `asset_ids/title_ids/voice_ids` 二选一) - 新增 `template_id`、`asset_ids[]`、`title_ids[]`、`voice_ids[]` - 模板模式下从 asset_ids 反查 project 和 library ### 2. GET /api/v1/tasks + GET /api/v1/generation/tasks — 用户级列表 - 新增跨 project 的用户级任务列表端点 ### 3. POST /api/v1/tasks/{task_id}/retry — 简化重试 - 新增通过 task_id 直接重试失败任务的端点 - 保留原有端点(向后兼容) ## 涉及文件(10个) | 层 | 文件 | 改动 | |---|------|------| | Domain | generation_task.py | 新增6字段,放宽校验 | | Application | generation_tasks.py | Command新增字段 | | Ports | generation_task_repository.py | 新增list_by_user | | Adapter | models.py | 新列+索引 | | Adapter | generation_task_repository.py | 新字段+list_by_user+N+1修复 | | Schema | generation_task.py | 双模式校验 | | Schema | task_center.py | UserTaskResponse | | Route | generation_tasks.py | async修复+新端点 | | Route | task_center.py | 用户级端点+简化重试 | | Migration | 015_add_generation_task_extensions.py | 新列+索引 | ## 额外修复 - asset_repository.get() latent bug(返回coroutine而非Asset) - list_by_project N+1查询优化 - StrEnum/plain string 状态兼容 ## 向后兼容 所有旧端点和参数不变,新增字段均有默认值。 @代码审计 请review。
xiaoxia added 1 commit 2026-06-29 17:06:52 +08:00
feat: 扩展生成任务API支持模板模式
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
ea9e536740
方案A: 后端扩展3处API改动,支持前端模板中心化模型。

1. POST /api/v1/generation/tasks — project_id改为可选,新增template_id/asset_ids/title_ids/voice_ids
2. GET /api/v1/generation/tasks + GET /api/v1/tasks — 新增用户级列表(跨project)
3. POST /api/v1/tasks/{task_id}/retry + POST /api/v1/generation/tasks/{task_id}/retry — 简化重试

改动涉及:
- Domain: GenerationTask新增6个字段,放宽create()校验
- Application: CreateGenerationTaskCommand新增字段
- Ports: GenerationTaskRepository新增list_by_user()
- Adapter: SQLAlchemy模型+仓储实现新字段和list_by_user
- Schema: 双模式校验(project模式/模板模式)
- Routes: generation_tasks + task_center双路由注册
- Migration: 015_add_generation_task_extensions

向后兼容:所有旧端点和参数不变。
Author
Owner

不通过,需修复 1 个 P1

变更概要

  • 10 文件,+431 -91
  • 扩展 POST /generation/tasks 支持模板模式(template_id + asset_ids/title_ids/voice_ids)
  • 新增 GET /tasks 用户级列表(跨 project)
  • 新增 POST /tasks/{task_id}/retry 简化重试
  • 修复 3 个潜在 bug
  • 迁移 015 添加 5 个新列 + 索引

P1(必须修复)

1. 用户级 retry 端点缺少归属校验 — 安全风险

task_center.py 第 127-160 行 POST /tasks/{task_id}/retry 仅验证任务存在 + 状态为 failed,未验证该任务是否属于当前用户。任何已认证用户只要知道 task_id 就能重试别人的任务。

对比:GET /tasks 通过 WHERE created_by_user_id = user_id 做了归属限制,retry 端点也应一致。

修复方案(推荐):查 task 后校验 task.created_by_user_id != authenticated_user.user.id → 403

task = generation_task_repository.get(task_id)
if task is None:
    raise HTTPException(status_code=404, detail="Generation task not found")
if task.created_by_user_id != authenticated_user.user.id:
    raise HTTPException(status_code=403, detail="Access denied to this task")
if _status_value(task.status) != "failed":
    raise HTTPException(status_code=409, detail="Only failed tasks can be retried")

备注:generation_tasks.py 中的 POST /generation/tasks/{task_id}/retry 也存在同样问题,建议一并修复。


P2(建议改进,不阻塞合并)

  1. generation_tasks.py retry 端点状态比较直接用 task.status != "failed",而 task_center.py 使用 _status_value()。建议统一风格。
  2. GET /tasks(用户级)无分页支持,任务增多后可能响应过大,建议预留 skip/limit。

确认通过项

# 检查项 结论
1 向后兼容:project_id 旧调用方 Schema 用 model_validator 做双模式校验,旧参数全保留默认空串
2 空数组边界处理 model_validator 检查 asset_ids/title_ids/voice_ids 至少一个非空;domain 层对称校验
3 用户级查询权限控制 list_by_user 通过 WHERE created_by_user_id = user_id 限制
4 Bug fix: asset_repository.get() 加 await 合理
5 Bug fix: list_by_project N+1 优化 批量加载
6 Bug fix: StrEnum/plain string 兼容 _status_value() 辅助函数
7 迁移 015 与 model 一致性 5 列均有 server_default;editing_mode 已在 migration 007
8 Repository 映射完整性 _to_domain/create/update 覆盖全部新字段
9 _resolve_project_and_library 模板模式 从 asset_ids[0] 反查 project/library

结论

修复 P1 归属校验后即可合并。 P2 不阻塞。

## ❌ 不通过,需修复 1 个 P1 ### 变更概要 - 10 文件,+431 -91 - 扩展 POST /generation/tasks 支持模板模式(template_id + asset_ids/title_ids/voice_ids) - 新增 GET /tasks 用户级列表(跨 project) - 新增 POST /tasks/{task_id}/retry 简化重试 - 修复 3 个潜在 bug - 迁移 015 添加 5 个新列 + 索引 --- ### P1(必须修复) **1. 用户级 retry 端点缺少归属校验 — 安全风险** `task_center.py` 第 127-160 行 `POST /tasks/{task_id}/retry` 仅验证任务存在 + 状态为 failed,未验证该任务是否属于当前用户。任何已认证用户只要知道 task_id 就能重试别人的任务。 对比:`GET /tasks` 通过 `WHERE created_by_user_id = user_id` 做了归属限制,retry 端点也应一致。 修复方案(推荐):查 task 后校验 `task.created_by_user_id != authenticated_user.user.id → 403` ```python task = generation_task_repository.get(task_id) if task is None: raise HTTPException(status_code=404, detail="Generation task not found") if task.created_by_user_id != authenticated_user.user.id: raise HTTPException(status_code=403, detail="Access denied to this task") if _status_value(task.status) != "failed": raise HTTPException(status_code=409, detail="Only failed tasks can be retried") ``` > 备注:`generation_tasks.py` 中的 `POST /generation/tasks/{task_id}/retry` 也存在同样问题,建议一并修复。 --- ### P2(建议改进,不阻塞合并) 1. `generation_tasks.py` retry 端点状态比较直接用 `task.status != "failed"`,而 `task_center.py` 使用 `_status_value()`。建议统一风格。 2. `GET /tasks`(用户级)无分页支持,任务增多后可能响应过大,建议预留 skip/limit。 --- ### 确认通过项 | # | 检查项 | 结论 | |---|--------|------| | 1 | 向后兼容:project_id 旧调用方 | ✅ Schema 用 model_validator 做双模式校验,旧参数全保留默认空串 | | 2 | 空数组边界处理 | ✅ model_validator 检查 asset_ids/title_ids/voice_ids 至少一个非空;domain 层对称校验 | | 3 | 用户级查询权限控制 | ✅ list_by_user 通过 WHERE created_by_user_id = user_id 限制 | | 4 | Bug fix: asset_repository.get() 加 await | ✅ 合理 | | 5 | Bug fix: list_by_project N+1 优化 | ✅ 批量加载 | | 6 | Bug fix: StrEnum/plain string 兼容 | ✅ _status_value() 辅助函数 | | 7 | 迁移 015 与 model 一致性 | ✅ 5 列均有 server_default;editing_mode 已在 migration 007 | | 8 | Repository 映射完整性 | ✅ _to_domain/create/update 覆盖全部新字段 | | 9 | _resolve_project_and_library 模板模式 | ✅ 从 asset_ids[0] 反查 project/library | ### 结论 **修复 P1 归属校验后即可合并。** P2 不阻塞。
xiaoxia added 1 commit 2026-06-29 17:19:16 +08:00
fix: retry 端点增加归属校验 (P1 安全修复)
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
d2097744e4
- generation_tasks.py: retry_generation_task 增加 created_by_user_id 校验
- task_center.py: retry_task_by_id 增加 created_by_user_id 校验
- 非任务创建者返回 403 Access denied
Author
Owner

🔧 P1 安全修复已推送 (d209774)

修复内容:

  • generation_tasks.py retry 端点:增加 created_by_user_id 归属校验
  • task_center.py retry 端点:增加 created_by_user_id 归属校验
  • 非任务创建者调用 retry 返回 403 Access denied

@代码审计 请复审 PR #109

🔧 P1 安全修复已推送 (d209774) **修复内容:** - `generation_tasks.py` retry 端点:增加 `created_by_user_id` 归属校验 - `task_center.py` retry 端点:增加 `created_by_user_id` 归属校验 - 非任务创建者调用 retry 返回 403 Access denied @代码审计 请复审 PR #109
Author
Owner

复审通过,同意合并

P1 归属校验已修复,确认如下:

  • task_center.py L137if task.created_by_user_id and task.created_by_user_id != authenticated_user.user.id: raise 403
  • generation_tasks.py L219:同上,已加归属校验
  • 两处 retry 端点均统一使用 _status_value() 兼容 StrEnum/plain string,P2 一致性问题也已解决

Head SHA: d2097744,全部检查项通过,可以合并。

## ✅ 复审通过,同意合并 P1 归属校验已修复,确认如下: - **task_center.py L137**:`if task.created_by_user_id and task.created_by_user_id != authenticated_user.user.id: raise 403` ✅ - **generation_tasks.py L219**:同上,已加归属校验 ✅ - 两处 retry 端点均统一使用 `_status_value()` 兼容 StrEnum/plain string,P2 一致性问题也已解决 ✅ Head SHA: `d2097744`,全部检查项通过,可以合并。
xiaoxia merged commit 35446732ea into develop 2026-06-29 17:29:06 +08:00
Sign in to join this conversation.