本文档定义前后端联调所需的 REST 与 SSE 契约,字段命名以实现优先,不追求过度抽象。
- Base URL:
- 本地:
http://localhost:3001 - 线上:由
NEXT_PUBLIC_API_BASE_URL注入
- 本地:
- 所有 JSON API 返回:
{
"data": {},
"meta": {},
"error": null
}- 错误返回:
{
"data": null,
"meta": {
"requestId": "req_xxx"
},
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request payload."
}
}功能:
- 上传一个或多个 PDF
- 创建上传记录
- 启动解析任务
请求:
multipart/form-data- 字段名:
files
响应:
{
"data": {
"uploads": [
{
"uploadId": "uuid",
"candidateId": "uuid",
"fileName": "resume.pdf",
"status": "uploaded"
}
]
},
"meta": {},
"error": null
}响应:
{
"data": {
"uploadId": "uuid",
"status": "extracting",
"fileName": "resume.pdf",
"candidateId": "uuid",
"errorMessage": null,
"uploadedAt": "2026-05-24T10:00:00.000Z"
},
"meta": {},
"error": null
}类型:
text/event-stream
事件示例:
event: upload.progress
data: {"uploadId":"uuid","progress":25}
event: pdf.parsed
data: {"uploadId":"uuid","pageCount":2}
event: extract.partial
data: {"uploadId":"uuid","basic":{"name":"张三","email":"a@b.com"}}
event: extract.completed
data: {"uploadId":"uuid","candidateId":"uuid"}
查询参数:
pagepageSizekeywordsortBysortOrderstatusskills
示例:
/api/candidates?page=1&pageSize=20&keyword=react&sortBy=score&sortOrder=desc&status=pending,interviewing
响应:
{
"data": {
"items": [
{
"id": "uuid",
"name": "张三",
"email": "zhangsan@example.com",
"city": "Shanghai",
"status": "pending",
"skills": ["React", "TypeScript", "Node.js"],
"latestOverallScore": 86,
"uploadedAt": "2026-05-24T10:00:00.000Z"
}
]
},
"meta": {
"page": 1,
"pageSize": 20,
"total": 132
},
"error": null
}响应:
{
"data": {
"id": "uuid",
"basic": {
"name": "张三",
"phone": "13800000000",
"email": "zhangsan@example.com",
"city": "Shanghai"
},
"status": "interviewing",
"skills": [
{ "name": "React", "type": "framework" }
],
"education": [],
"workExperiences": [],
"projects": [],
"latestMatching": {
"jobId": "uuid",
"overallScore": 86,
"dimensionScores": {
"skillMatch": 90,
"experienceRelevance": 84,
"educationFit": 78
},
"summary": "技能匹配较好,经验相关性较强。"
},
"pdfPreviewUrl": "https://..."
},
"meta": {},
"error": null
}功能:
- 前端人工修正候选人信息
请求:
{
"basic": {
"name": "张三",
"phone": "13800000000",
"email": "zhangsan@example.com",
"city": "Shanghai"
},
"skills": [
{ "name": "React", "type": "framework" }
],
"education": [],
"workExperiences": [],
"projects": []
}请求:
{
"status": "screening_passed"
}响应:
{
"data": {
"id": "uuid",
"status": "screening_passed"
},
"meta": {},
"error": null
}请求:
{
"title": "高级前端工程师",
"description": "负责招聘业务平台开发",
"requiredSkills": ["React", "TypeScript", "Next.js"],
"bonusSkills": ["Node.js", "AI Product"]
}请求:
{
"jobId": "uuid",
"candidateIds": ["uuid1", "uuid2"]
}响应:
{
"data": {
"results": [
{
"matchingId": "uuid",
"candidateId": "uuid1",
"jobId": "uuid",
"overallScore": 86,
"dimensionScores": {
"skillMatch": 90,
"experienceRelevance": 84,
"educationFit": 78
},
"summary": "候选人技能栈与岗位高度相关。",
"strengths": ["React 经验充分"],
"risks": ["教育背景不是明显优势"],
"evidence": ["3 年 B 端系统经验"]
}
]
},
"meta": {},
"error": null
}返回单条评分详情。
-
POST /api/uploads- 只允许 PDF
- 建议单文件不超过 10MB
- 单次不超过 10 个文件
-
PATCH /api/candidates/:id/status- 状态必须在枚举内
-
POST /api/matchingscandidateIds长度为1~3
UPLOAD_INVALID_FILE:文件格式错误UPLOAD_TOO_LARGE:文件太大PDF_PARSE_FAILED:PDF 解析失败AI_EXTRACTION_FAILED:AI 提取失败CANDIDATE_NOT_FOUND:候选人不存在JOB_NOT_FOUND:JD 不存在MATCHING_FAILED:评分失败