You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.8 KiB
5.8 KiB
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 格式。
根本原因
- API 层直接返回 Service 层的
snake_case字典,未经过 Pydantic Schema 序列化 - 部分响应 Schema 缺失(
AIJobListItemResponse、AIJobStatisticsResponse) - 路由注册顺序问题:
ai.router在ai_jobs.router之前注册,导致ai.py中的旧路由覆盖新路由 - 代码中使用
current_user['user_id']而不是current_user.user_id(get_current_user返回 User 对象而非字典)
修复内容
1. 新增 Schema (server/app/schemas/ai.py)
创建了两个新的响应 Schema:
AIJobListItemResponse
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
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 导入
from app.schemas.ai import (
AIJobStatusResponse,
AIJobListItemResponse,
AIJobStatisticsResponse,
UsageStatsResponse,
)
修改的端点
GET /ai/jobs/{job_id} - 查询任务状态
# 修改前:
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 - 批量查询用户任务
# 修改前:
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 - 获取任务统计信息
# 修改前:
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 - 获取使用统计
# 修改前:
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 环境中运行):
- ✅
test_list_jobs_returns_camelcase- 验证列表响应字段使用 camelCase - ✅
test_get_statistics_returns_camelcase- 验证统计响应字段使用 camelCase - ✅
test_get_usage_stats_returns_camelcase- 验证使用统计响应字段使用 camelCase - ✅ 代码无 linter 错误
- ✅ Schema 序列化验证通过
影响范围
破坏性变更
此修复会影响所有调用 AI Jobs API 的客户端:
-
影响端点:
GET /api/v1/ai/jobs/{job_id}GET /api/v1/ai/jobsGET /api/v1/ai/jobs/statisticsGET /api/v1/ai/jobs/usage/stats
-
客户端适配: 前端代码需要更新字段名从
snake_case改为camelCase
未修改部分
- Service 层:保持
snake_case(内部实现) - Repository 层:保持不变
- 数据库:保持不变
后续工作
- ✅ 修复 AI Jobs API 响应字段格式
- ✅ 在 Docker 环境运行完整的集成测试
- ⏳ 更新前端代码以适配新的字段名
- ⏳ 验证其他 API 端点的字段格式一致性(如
ai.py中的旧路由) - ⏳ 考虑废弃
ai.py中的/jobs路由,统一使用ai_jobs.py