# AI Jobs API 响应字段 camelCase 修复 **日期**: 2026-02-06 **类型**: Bug Fix **影响范围**: AI Jobs API (server/app/api/v1/ai_jobs.py) ## 问题描述 AI Jobs API 的所有端点返回的响应字段使用 `snake_case`,不符合 API 设计规范要求的 `camelCase` 格式。 ## 根本原因 1. API 层直接返回 Service 层的 `snake_case` 字典,未经过 Pydantic Schema 序列化 2. 部分响应 Schema 缺失(`AIJobListItemResponse`、`AIJobStatisticsResponse`) 3. 路由注册顺序问题:`ai.router` 在 `ai_jobs.router` 之前注册,导致 `ai.py` 中的旧路由覆盖新路由 4. 代码中使用 `current_user['user_id']` 而不是 `current_user.user_id`(`get_current_user` 返回 User 对象而非字典) ## 修复内容 ### 1. 新增 Schema (server/app/schemas/ai.py) 创建了两个新的响应 Schema: #### AIJobListItemResponse ```python class AIJobListItemResponse(BaseModel): """AI 任务列表项响应""" job_id: str = Field(..., alias="jobId") job_type: int = Field(..., alias="jobType") status: int progress: int model_name: Optional[str] = Field(None, alias="modelName") credits_used: int = Field(..., alias="creditsUsed") created_at: str = Field(..., alias="createdAt") started_at: Optional[str] = Field(None, alias="startedAt") completed_at: Optional[str] = Field(None, alias="completedAt") error_message: Optional[str] = Field(None, alias="errorMessage") model_config = ConfigDict(populate_by_name=True) ``` #### AIJobStatisticsResponse ```python class AIJobStatisticsResponse(BaseModel): """AI 任务统计响应""" total_jobs: int = Field(..., alias="totalJobs") completed_jobs: int = Field(..., alias="completedJobs") failed_jobs: int = Field(..., alias="failedJobs") pending_jobs: int = Field(..., alias="pendingJobs") processing_jobs: int = Field(..., alias="processingJobs") success_rate: float = Field(..., alias="successRate") total_credits: int = Field(..., alias="totalCredits") avg_execution_time: float = Field(..., alias="avgExecutionTime") by_type: Dict[str, Any] = Field(..., alias="byType") by_model: Dict[str, Any] = Field(..., alias="byModel") model_config = ConfigDict(populate_by_name=True) ``` ### 2. 修改 API 层 (server/app/api/v1/ai_jobs.py) #### 添加 Schema 导入 ```python from app.schemas.ai import ( AIJobStatusResponse, AIJobListItemResponse, AIJobStatisticsResponse, UsageStatsResponse, ) ``` #### 修改的端点 **GET /ai/jobs/{job_id}** - 查询任务状态 ```python # 修改前: return success_response(data=result) # 修改后: job_data = AIJobStatusResponse.model_validate(result).model_dump(by_alias=True, mode='json') return success_response(data=job_data) ``` **GET /ai/jobs** - 批量查询用户任务 ```python # 修改前: return success_response(data=result) # 修改后: serialized_items = [ AIJobListItemResponse.model_validate(item).model_dump(by_alias=True, mode='json') for item in result['items'] ] response_data = { "items": serialized_items, "total": result['total'], "page": result['page'], "pageSize": result['page_size'], "totalPages": result['total_pages'] } return success_response(data=response_data) ``` **GET /ai/jobs/statistics** - 获取任务统计信息 ```python # 修改前: return success_response(data=result) # 修改后: stats_data = AIJobStatisticsResponse.model_validate(result).model_dump(by_alias=True, mode='json') return success_response(data=stats_data) ``` **GET /ai/jobs/usage/stats** - 获取使用统计 ```python # 修改前: return success_response(data=result) # 修改后: usage_data = UsageStatsResponse.model_validate(result).model_dump(by_alias=True, mode='json') return success_response(data=usage_data) ``` ## 验证结果 所有 Schema 的 camelCase 序列化已验证正确: - ✅ AIJobStatusResponse: `jobId`, `jobType`, `modelName`, `creditsUsed`, `createdAt`, `updatedAt`, `startedAt`, `completedAt`, `errorMessage`, `inputData`, `outputData` - ✅ AIJobListItemResponse: 所有字段使用 camelCase - ✅ AIJobStatisticsResponse: `totalJobs`, `completedJobs`, `failedJobs`, `pendingJobs`, `processingJobs`, `successRate`, `totalCredits`, `avgExecutionTime`, `byType`, `byModel` - ✅ UsageStatsResponse: `totalCost`, `totalCreditsUsed`, `totalRequests`, `byModel`, `byType` ## 测试状态 ✅ **所有集成测试通过** (在 Docker 环境中运行): 1. ✅ `test_list_jobs_returns_camelcase` - 验证列表响应字段使用 camelCase 2. ✅ `test_get_statistics_returns_camelcase` - 验证统计响应字段使用 camelCase 3. ✅ `test_get_usage_stats_returns_camelcase` - 验证使用统计响应字段使用 camelCase 4. ✅ 代码无 linter 错误 5. ✅ Schema 序列化验证通过 ## 影响范围 ### 破坏性变更 此修复会影响所有调用 AI Jobs API 的客户端: - **影响端点**: - `GET /api/v1/ai/jobs/{job_id}` - `GET /api/v1/ai/jobs` - `GET /api/v1/ai/jobs/statistics` - `GET /api/v1/ai/jobs/usage/stats` - **客户端适配**: 前端代码需要更新字段名从 `snake_case` 改为 `camelCase` ### 未修改部分 - Service 层:保持 `snake_case`(内部实现) - Repository 层:保持不变 - 数据库:保持不变 ## 后续工作 1. ✅ 修复 AI Jobs API 响应字段格式 2. ✅ 在 Docker 环境运行完整的集成测试 3. ⏳ 更新前端代码以适配新的字段名 4. ⏳ 验证其他 API 端点的字段格式一致性(如 `ai.py` 中的旧路由) 5. ⏳ 考虑废弃 `ai.py` 中的 `/jobs` 路由,统一使用 `ai_jobs.py` ## 参考 - [API 设计规范](/.claude/skills/jointo-tech-stack/references/api-design.md) - [测试规范](/.claude/skills/jointo-tech-stack/references/testing.md) - 相关修复:[Resource Library API camelCase 修复](./2026-02-06-resource-library-camelcase-fix.md)