openapi: 3.0.3 info: title: 数据持久化与异步任务处理集成 API description: | GORM + PostgreSQL + Asynq 集成的数据持久化和异步任务处理功能 API 规范 **Feature**: 002-gorm-postgres-asynq **Date**: 2025-11-12 ## 核心功能 - 数据库连接管理和健康检查 - 异步任务提交和管理 - 数据 CRUD 操作(示例:用户管理) ## 技术栈 - Fiber (HTTP 框架) - GORM (ORM) - PostgreSQL (数据库) - Asynq (任务队列) - Redis (任务队列存储) version: 1.0.0 contact: name: API Support email: support@example.com servers: - url: http://localhost:8080/api/v1 description: 开发环境 - url: http://staging.example.com/api/v1 description: 预发布环境 - url: https://api.example.com/api/v1 description: 生产环境 tags: - name: Health description: 健康检查和系统状态 - name: Users description: 用户管理(数据库操作示例) - name: Tasks description: 异步任务管理 paths: /health: get: tags: - Health summary: 健康检查 description: | 检查系统健康状态,包括数据库连接和 Redis 连接 **测试用例**: - FR-011: 系统必须提供健康检查接口 - SC-010: 健康检查应在 1 秒内返回 operationId: healthCheck responses: '200': description: 系统健康 content: application/json: schema: type: object properties: status: type: string enum: [ok] description: 系统整体状态 postgres: type: string enum: [up, down] description: PostgreSQL 连接状态 redis: type: string enum: [up, down] description: Redis 连接状态 example: status: ok postgres: up redis: up '503': description: 服务降级或不可用 content: application/json: schema: type: object properties: status: type: string enum: [degraded, unavailable] postgres: type: string enum: [up, down] redis: type: string enum: [up, down] error: type: string description: 错误详情 example: status: degraded postgres: down redis: up error: "数据库连接失败" /users: post: tags: - Users summary: 创建用户 description: | 创建新用户(演示数据库 CRUD 操作) **测试用例**: - FR-002: 支持标准 CRUD 操作 - FR-003: 支持数据库事务 - User Story 1 - Acceptance 1: 数据持久化 operationId: createUser security: - TokenAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' responses: '200': description: 用户创建成功 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/UserResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '409': $ref: '#/components/responses/Conflict' '500': $ref: '#/components/responses/InternalServerError' get: tags: - Users summary: 用户列表 description: | 分页查询用户列表 **测试用例**: - FR-002: 支持分页列表查询 - FR-005: 支持条件查询、分页、排序 - User Story 1 - Acceptance 5: 分页和排序 operationId: listUsers security: - TokenAuth: [] parameters: - name: page in: query schema: type: integer default: 1 minimum: 1 description: 页码 - name: page_size in: query schema: type: integer default: 20 minimum: 1 maximum: 100 description: 每页条数(最大 100) - name: status in: query schema: type: string enum: [active, inactive, suspended] description: 用户状态过滤 responses: '200': description: 查询成功 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/ListUsersResponse' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' /users/{id}: get: tags: - Users summary: 获取用户详情 description: | 根据用户 ID 获取详细信息 **测试用例**: - FR-002: 支持按 ID 查询 - User Story 1 - Acceptance 1: 数据检索 operationId: getUserById security: - TokenAuth: [] parameters: - name: id in: path required: true schema: type: integer minimum: 1 description: 用户 ID responses: '200': description: 查询成功 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/UserResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' put: tags: - Users summary: 更新用户 description: | 更新用户信息 **测试用例**: - FR-002: 支持更新操作 - User Story 1 - Acceptance 2: 数据更新 operationId: updateUser security: - TokenAuth: [] parameters: - name: id in: path required: true schema: type: integer minimum: 1 description: 用户 ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateUserRequest' responses: '200': description: 更新成功 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/UserResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '409': $ref: '#/components/responses/Conflict' '500': $ref: '#/components/responses/InternalServerError' delete: tags: - Users summary: 删除用户 description: | 软删除用户(设置 deleted_at 字段) **测试用例**: - FR-002: 支持软删除操作 - User Story 1 - Acceptance 3: 数据删除 operationId: deleteUser security: - TokenAuth: [] parameters: - name: id in: path required: true schema: type: integer minimum: 1 description: 用户 ID responses: '200': description: 删除成功 content: application/json: schema: $ref: '#/components/schemas/SuccessResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /tasks/email: post: tags: - Tasks summary: 提交邮件发送任务 description: | 将邮件发送任务提交到异步队列 **测试用例**: - FR-006: 提交任务到异步队列 - FR-008: 任务重试机制 - User Story 2 - Acceptance 1: 任务提交 operationId: submitEmailTask security: - TokenAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EmailTaskRequest' responses: '200': description: 任务已提交 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/TaskResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' /tasks/sync: post: tags: - Tasks summary: 提交数据同步任务 description: | 将数据同步任务提交到异步队列(支持优先级) **测试用例**: - FR-006: 提交任务到异步队列 - FR-009: 任务优先级支持 - User Story 2 - Acceptance 1: 任务提交 operationId: submitSyncTask security: - TokenAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SyncTaskRequest' responses: '200': description: 任务已提交 content: application/json: schema: allOf: - $ref: '#/components/schemas/SuccessResponse' - type: object properties: data: $ref: '#/components/schemas/TaskResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '500': $ref: '#/components/responses/InternalServerError' components: securitySchemes: TokenAuth: type: apiKey in: header name: token description: 认证令牌 schemas: # 通用响应 SuccessResponse: type: object required: - code - msg - timestamp properties: code: type: integer enum: [0] description: 响应码(0 表示成功) msg: type: string example: success description: 响应消息 data: type: object description: 响应数据(具体结构由各端点定义) timestamp: type: string format: date-time example: "2025-11-12T16:00:00+08:00" description: 响应时间戳(ISO 8601 格式) ErrorResponse: type: object required: - code - msg - timestamp properties: code: type: integer description: 错误码(非 0) example: 1001 msg: type: string description: 错误消息(中文) example: "参数验证失败" data: type: object nullable: true description: 错误详情(可选) timestamp: type: string format: date-time example: "2025-11-12T16:00:00+08:00" # 用户相关 CreateUserRequest: type: object required: - username - email - password properties: username: type: string minLength: 3 maxLength: 50 pattern: '^[a-zA-Z0-9_]+$' description: 用户名(3-50 个字母数字下划线) example: testuser email: type: string format: email maxLength: 100 description: 邮箱地址 example: test@example.com password: type: string format: password minLength: 8 description: 密码(至少 8 个字符) example: password123 UpdateUserRequest: type: object properties: email: type: string format: email maxLength: 100 description: 邮箱地址 example: newemail@example.com status: type: string enum: [active, inactive, suspended] description: 用户状态 UserResponse: type: object required: - id - username - email - status - created_at - updated_at properties: id: type: integer description: 用户 ID example: 1 username: type: string description: 用户名 example: testuser email: type: string description: 邮箱地址 example: test@example.com status: type: string enum: [active, inactive, suspended] description: 用户状态 example: active created_at: type: string format: date-time description: 创建时间 example: "2025-11-12T16:00:00+08:00" updated_at: type: string format: date-time description: 更新时间 example: "2025-11-12T16:00:00+08:00" last_login_at: type: string format: date-time nullable: true description: 最后登录时间 example: "2025-11-12T16:30:00+08:00" ListUsersResponse: type: object required: - users - page - page_size - total - total_pages properties: users: type: array items: $ref: '#/components/schemas/UserResponse' description: 用户列表 page: type: integer description: 当前页码 example: 1 page_size: type: integer description: 每页条数 example: 20 total: type: integer format: int64 description: 总记录数 example: 100 total_pages: type: integer description: 总页数 example: 5 # 任务相关 EmailTaskRequest: type: object required: - to - subject - body properties: to: type: string format: email description: 收件人邮箱 example: user@example.com subject: type: string maxLength: 200 description: 邮件主题 example: Welcome to our service body: type: string description: 邮件正文 example: Thank you for signing up! cc: type: array items: type: string format: email description: 抄送列表 example: ["manager@example.com"] priority: type: string enum: [critical, default, low] default: default description: 任务优先级 SyncTaskRequest: type: object required: - sync_type - start_date - end_date properties: sync_type: type: string enum: [sim_status, flow_usage, real_name] description: 同步类型 example: sim_status start_date: type: string format: date pattern: '^\d{4}-\d{2}-\d{2}$' description: 开始日期(YYYY-MM-DD) example: "2025-11-01" end_date: type: string format: date pattern: '^\d{4}-\d{2}-\d{2}$' description: 结束日期(YYYY-MM-DD) example: "2025-11-12" batch_size: type: integer minimum: 1 maximum: 1000 default: 100 description: 批量大小 priority: type: string enum: [critical, default, low] default: default description: 任务优先级 TaskResponse: type: object required: - task_id - queue properties: task_id: type: string format: uuid description: 任务唯一 ID example: "550e8400-e29b-41d4-a716-446655440000" queue: type: string enum: [critical, default, low] description: 任务所在队列 example: default estimated_time: type: string description: 预计执行时间 example: "within 5 minutes" responses: BadRequest: description: 请求参数错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: 1001 msg: "参数验证失败" data: null timestamp: "2025-11-12T16:00:00+08:00" Unauthorized: description: 未授权或令牌无效 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: 1002 msg: "缺失认证令牌" data: null timestamp: "2025-11-12T16:00:00+08:00" NotFound: description: 资源不存在 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: 1003 msg: "用户不存在" data: null timestamp: "2025-11-12T16:00:00+08:00" Conflict: description: 资源冲突(如用户名已存在) content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: 1004 msg: "用户名已存在" data: null timestamp: "2025-11-12T16:00:00+08:00" InternalServerError: description: 服务器内部错误 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: code: 5000 msg: "服务器内部错误" data: null timestamp: "2025-11-12T16:00:00+08:00"