Files
label_backend/docs/superpowers/specs/2026-04-15-label-backend-swagger-annotations-design.md

302 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# label_backend Swagger 参数注解与 DTO 化设计
> 日期2026-04-15
> 范围:`label_backend` 对外 REST API 的 Swagger/OpenAPI 文档增强
## 1. 背景
当前 `label_backend` 已经在 Controller 层使用了 `@Tag``@Operation`,少量 DTO 也已有 `@Schema` 注解,因此 Swagger 页面可以展示基础接口列表和部分对象结构。
但现状仍存在几个明显问题:
- 很多路径参数、查询参数、表单参数缺少名称、类型、取值和含义说明
- 多个接口仍使用 `Map<String, Object>``Map<String, String>` 作为请求体Swagger 无法准确展示字段名、字段类型和字段说明
- 一些固定结构响应仍以 `Map<String, Object>` 返回Swagger 只能显示匿名对象
- 部分接口直接暴露实体类,而实体字段尚未补齐 Swagger 字段描述
- 通用返回包装 `Result<T>``PageResult<T>` 没有字段级别文档说明
用户目标很明确:在 Swagger 中看到所有接口参数的名称、类型和含义。
## 2. 目标
本次改造完成后,`label_backend` 的 Swagger 页面应满足以下目标:
- 所有公开接口都能展示清晰的路径参数、查询参数、请求头参数、表单参数说明
- 所有固定结构的请求体都使用 DTO 建模,并为每个字段提供名称、类型、必填性和含义说明
- 所有固定结构的主要响应对象都能展示字段说明
- 所有分页与统一返回包装的字段含义清晰可见
- 不改变现有接口路径、HTTP 方法和字段名称,尽量保持对现有调用方兼容
## 3. 非目标
本次不做以下事情:
- 不重构整体业务流程
- 不调整接口 URL、HTTP 方法和权限策略
- 不强制把所有实体类都替换成专门的 Response DTO
- 不把完全动态的业务 JSON 全量重建成复杂深层对象,只对固定边界做显式包装
- 不顺手做无关的代码整理或目录重构
## 4. 设计原则
### 4.1 DTO-first
凡是 Swagger 需要清楚展示字段名、字段类型和字段说明的固定结构请求体,都应优先使用 DTO而不是 `Map<String, Object>`
### 4.2 文档增强优先,行为保持不变
本次的核心是 API 契约可读性增强,因此:
- Controller 仍调用原有 Service
- 参数字段名保持不变
- 业务语义、状态流转、权限校验保持不变
### 4.3 固定结构显式化,动态结构边界化
如果接口返回的是稳定字段集合,应使用明确 DTO 或明确对象字段注解。
如果业务内部结果本身仍是动态 JSON则至少提供一个固定外层 DTO把最外层字段含义说明清楚避免 Swagger 展示匿名 `Map`
### 4.4 最小可控改动
优先修改 Controller 入口、DTO 定义和 Swagger 展示对象,尽量不侵入 Service 深层逻辑。
## 5. 目标改造范围
### 5.1 Controller
本次覆盖以下 10 个 Controller
- `AuthController`
- `CompanyController`
- `ExportController`
- `ExtractionController`
- `QaController`
- `SourceController`
- `SysConfigController`
- `TaskController`
- `UserController`
- `VideoController`
### 5.2 通用返回模型
- `Result<T>`
- `PageResult<T>`
### 5.3 现有 DTO
- `LoginRequest`
- `LoginResponse`
- `SourceResponse`
- `TaskResponse`
- `UserInfoResponse`
### 5.4 当前直接暴露给 Swagger 的实体
- `SysUser`
- `SysCompany`
- `SysConfig`
- `TrainingDataset`
- `ExportBatch`
- `VideoProcessJob`
## 6. DTO 改造策略
### 6.1 必须从 Map 重构为 DTO 的请求体
以下接口应从匿名请求体改为明确 DTO
- `TaskController#createTask`
- 新增 `CreateTaskRequest`
- `TaskController#reassign`
- 新增 `TaskReassignRequest`
- `VideoController#createJob`
- 新增 `VideoProcessCreateRequest`
- `VideoController#handleCallback`
- 新增 `VideoProcessCallbackRequest`
- `CompanyController#update`
- 新增明确请求 DTO
- `CompanyController#updateStatus`
- 新增明确请求 DTO
- `ExportController#createBatch`
- 新增明确请求 DTO
- `UserController` 中如仍存在匿名请求体,也统一改成 DTO
### 6.2 固定结构响应优先改为 DTO
以下返回如果当前为 `Map<String, Object>` 但字段稳定,应收敛为 DTO
- 导出与微调相关状态响应
- 视频回调相关固定结构响应
- 系统配置项列表响应
### 6.3 动态结果场景
`ExtractionController``QaController` 可能仍涉及结构化 JSON 结果。处理原则如下:
- 如果最外层字段稳定,则增加外层 DTO 说明
- 如果内部 `items` 仍允许动态内容,则在 DTO 字段级别说明该字段承载的业务 JSON 结构
## 7. Swagger 注解标准
### 7.1 Controller 方法
每个接口方法统一遵循:
- `@Tag`
- `@Operation(summary = "...", description = "...")`
- 对路径参数、查询参数、请求头参数、表单参数补 `@Parameter`
- 对请求体补 `@io.swagger.v3.oas.annotations.parameters.RequestBody`
参数描述至少包含:
- 参数业务含义
- 是否必填
- 枚举值范围或典型值
- 分页默认值或限制条件
### 7.2 DTO 字段
所有公开请求/响应 DTO 字段统一使用:
- `@Schema(description = "...", example = "...")`
必要时增加:
- `@NotNull`
- `@NotBlank`
- `@Valid`
### 7.3 通用包装类
`Result<T>` 应说明:
- `code`:业务状态码
- `data`:接口返回主体
- `message`:失败或补充说明
`PageResult<T>` 应说明:
- `items`:当前页数据列表
- `total`:总记录数
- `page`:当前页码,从 1 开始
- `pageSize`:每页条数
### 7.4 直接暴露实体
对于当前直接暴露给 Swagger 的实体类,给字段补齐 `@Schema` 说明,但不在本次强制转换为 Response DTO。
## 8. 代码组织方案
建议在 `dto/` 下继续保持扁平化风格,新增与接口语义一致的请求和响应类,命名以业务动作为中心,例如:
- `CreateTaskRequest`
- `TaskReassignRequest`
- `VideoProcessCreateRequest`
- `VideoProcessCallbackRequest`
- `CompanyUpdateRequest`
- `CompanyStatusUpdateRequest`
- `ExportBatchCreateRequest`
如果某个响应只在单个 Controller 使用,但字段固定,也放在 `dto/` 下,而不是内联 `Map`
## 9. 兼容性要求
为了避免影响现有调用方,本次必须满足:
- 接口 URL 不变
- HTTP 方法不变
- JSON 字段名称不变
- Multipart 参数名不变
- 路径参数名和查询参数名不变
DTO 只是显式建模现有契约,不是重新设计契约。
## 9.1 README 约束同步
本次设计不仅要求代码层落地,还要求将 Swagger/DTO 约束写入项目 `README.md` 的开发规范中,作为后续接口开发的长期规则。
README 中至少应明确以下要求:
- 所有对外接口参数必须在 Swagger 中清楚展示名称、类型和含义
- 固定结构请求体禁止继续使用匿名 `Map`,必须定义 DTO
- 固定结构响应应优先显式建模,避免 Swagger 展示匿名对象
- 通用返回体和分页包装也必须维护字段说明
## 10. 测试策略
由于本次会把匿名请求体改为 DTO需要用测试确认请求绑定行为没有被改坏。
测试策略如下:
- 优先补或更新 Controller 测试
- 覆盖 DTO 替换后的 JSON 反序列化
- 验证关键接口的请求字段名保持不变
- 验证原有成功路径和主要失败路径仍成立
至少应覆盖:
- 创建任务
- 重指派任务
- 创建视频处理任务
- 接收视频回调
- 创建导出批次
- 公司更新和状态更新
## 11. 风险与处理
### 11.1 风险:字段名不一致导致请求绑定失败
处理方式:
- DTO 字段严格对齐当前请求 JSON 的既有字段名
- 使用 Controller 测试验证兼容性
### 11.2 风险:动态 JSON 过度 DTO 化,导致业务边界变复杂
处理方式:
- 只对固定边界建模
- 动态业务内容保留为受控字段,不做过度深挖
### 11.3 风险:实体类字段太多,注解工作量大
处理方式:
- 只处理当前实际暴露到 Swagger 的实体
- 优先处理高频接口涉及对象
## 12. 实施顺序
推荐按以下顺序实施:
1.`Result<T>``PageResult<T>` 补齐字段说明
2. 给已有公开 DTO 补齐 `@Schema`
3. 将匿名请求体改造成 DTO并更新对应 Controller
4. 将固定结构的 `Map` 响应改造成 DTO
5. 为直接暴露的实体补齐 `@Schema`
6. 统一补齐 Controller 参数 `@Parameter` 注解
7. 更新或新增相关测试并执行验证
## 13. 验收标准
验收通过应满足以下条件:
- Swagger 页面中所有公开接口参数都能看到名称、类型和含义
- 所有固定结构请求体不再以匿名 `Map` 展示
- 主要响应对象字段说明齐全
- 通用返回体字段说明齐全
- `README.md` 已写入 Swagger/DTO 文档约束
- Controller 相关测试通过
- 未引入接口路径或字段名兼容性破坏
## 14. 决策总结
本次采用“DTO-first API 文档化”方案:
- 请求体优先 DTO 化
- 固定结构响应优先显式建模
- Controller 参数注释统一化
- 通用返回体和当前暴露实体补齐 Swagger 字段说明
- 在不改变业务语义的前提下,最大化提升 Swagger 可读性和接口契约清晰度