# OpenAPI Generation - 更新规范 ## MODIFIED Requirements ### Requirement: 错误响应字段名必须为 msg OpenAPI 文档中的错误响应 SHALL 使用 `msg` 字段而非 `message`,与真实运行时的 Response 结构体保持一致。 #### Scenario: 错误响应使用 msg 字段 - **WHEN** 生成 OpenAPI 文档的错误响应 schema - **THEN** ErrorResponse 包含 `msg` 字段(类型为 string) - **AND** ErrorResponse 不包含 `message` 字段 #### Scenario: 生成的文档与真实响应一致 - **WHEN** API 返回错误响应 - **THEN** 响应 JSON 包含 `msg` 字段 - **AND** OpenAPI 文档中的 schema 定义也使用 `msg` 字段 - **AND** 字段名完全匹配 ### Requirement: 成功响应必须包裹在 envelope 中 所有成功响应 SHALL 包裹在统一的 envelope 结构中:`{code, msg, data, timestamp}`。 #### Scenario: 成功响应包含 envelope 结构 - **WHEN** 生成接口的 200 响应 schema - **THEN** 响应 schema 包含以下字段: - `code` (integer, example: 0) - `msg` (string, example: "success") - `data` (原始 DTO schema) - `timestamp` (string, format: date-time) #### Scenario: data 字段包含实际的 DTO - **WHEN** 接口返回数据(如用户列表、详情) - **THEN** OpenAPI 的 `data` 字段引用实际的 DTO schema - **AND** DTO schema 不被修改(保持原结构) #### Scenario: 无返回数据的接口 data 为 null - **WHEN** 接口无返回数据(如删除操作) - **THEN** OpenAPI 的 `data` 字段类型为 `null` - **AND** 响应仍包含 `code`、`msg`、`timestamp` 字段 ### Requirement: envelope 包裹适用于所有接口类型 envelope 包裹 SHALL 适用于普通接口和文件上传接口。 #### Scenario: 普通接口使用 envelope - **WHEN** 通过 `AddOperation` 添加接口 - **THEN** 生成的 200 响应包含 envelope 结构 #### Scenario: 文件上传接口使用 envelope - **WHEN** 通过 `AddMultipartOperation` 添加文件上传接口 - **THEN** 生成的 200 响应包含 envelope 结构 - **AND** envelope 结构与普通接口一致 ### Requirement: 所有 handlers 必须在文档生成器中注册 文档生成器 SHALL 包含所有已实现的 handlers,确保接口文档完整。 #### Scenario: handlers 清单完整性 - **WHEN** 生成 OpenAPI 文档 - **THEN** 所有 handler 的接口都出现在文档中 - **AND** 不存在已实现但未出现在文档的接口 #### Scenario: 新增 handler 时同步更新 - **WHEN** 新增 handler(如 `PersonalCustomer`、`ShopPackageBatchAllocation`) - **THEN** 必须在 `BuildDocHandlers()` 中添加对应的构造代码 - **AND** 重新生成文档后接口出现在 OpenAPI 文件中 ### Requirement: handlers 构造函数统一管理 handlers 的构造逻辑 SHALL 由公共函数 `BuildDocHandlers()` 统一管理,避免重复。 #### Scenario: cmd/api/docs.go 复用 BuildDocHandlers - **WHEN** 在 `cmd/api/docs.go` 中需要构造 handlers - **THEN** 调用 `openapi.BuildDocHandlers()` 获取 handlers - **AND** 不在本文件中重复构造 #### Scenario: cmd/gendocs/main.go 复用 BuildDocHandlers - **WHEN** 在 `cmd/gendocs/main.go` 中需要构造 handlers - **THEN** 调用 `openapi.BuildDocHandlers()` 获取 handlers - **AND** 不在本文件中重复构造 #### Scenario: BuildDocHandlers 传入 nil 依赖 - **WHEN** `BuildDocHandlers()` 构造 handlers - **THEN** 所有 handler 构造函数的依赖参数传入 `nil` - **AND** 因为文档生成不执行 handler 逻辑,nil 依赖不会导致运行时错误 ### Requirement: 个人客户路由必须使用 Register 机制 个人客户 API (`/api/c/v1`) SHALL 使用 `Register(...)` 机制注册,纳入 OpenAPI 文档体系。 #### Scenario: RegisterPersonalRoutes 使用 Register 机制 - **WHEN** 调用 `RegisterPersonalRoutes` 注册个人客户路由 - **THEN** 使用 `doc.Register(RouteSpec{...})` 注册每个路由 - **AND** 不直接调用 Fiber 的 `app.Get/Post` 方法 #### Scenario: 个人客户路由出现在文档中 - **WHEN** 生成 OpenAPI 文档 - **THEN** 文档包含 `/api/c/v1` 路径的接口 - **AND** 每个接口包含正确的 Summary、Tags、Auth 信息 #### Scenario: 个人客户路由的元数据完整 - **WHEN** 注册个人客户路由 - **THEN** 每个 RouteSpec 包含: - Method(GET/POST/PUT/DELETE) - Path(完整路径) - Handler(fiber.Handler) - Summary(中文摘要) - Tags(包含 "个人客户") - Auth(true/false) - Input(请求 DTO 或 nil) - Output(响应 DTO) ### Requirement: 文档生成的幂等性 文档生成 SHALL 是幂等的,相同的代码生成相同的文档。 #### Scenario: 重复生成文档内容一致 - **WHEN** 多次运行 `go run cmd/gendocs/main.go` - **THEN** 生成的 `openapi.yaml` 内容完全一致 - **AND** 文件 hash 值相同(除 timestamp 等动态字段外) #### Scenario: 代码未变更时文档不变 - **WHEN** 代码(handlers、路由、DTO)未变更 - **THEN** 重新生成的文档与之前的文档一致 - **AND** 不会因为生成逻辑的随机性导致差异