label-backend Swagger 接口黑盒测试用例
1. 文档说明
- 生成时间:2026-04-14
- 适用项目:
label-backend
- 覆盖范围:当前
controller 中已开放的全部 Swagger/OpenAPI 接口
- 生成依据:
src/main/java/com/label/controller/**/*.java
src/main/java/com/label/service/**/*.java
src/main/resources/sql/init.sql
src/test/java/com/label/integration/**/*.java
- 说明:
- 当前会话内未能直接访问
http://127.0.0.1:8080/v3/api-docs,本文档按代码、设计和现有集成测试反推生成。
- 文中“预期结果”以黑盒测试应验证的业务契约为主;若当前实现存在契约空洞,用例应保留,用于发现缺陷。
2. 测试前提
2.1 基础环境
- Base URL:
http://127.0.0.1:8080
- OpenAPI:
GET /v3/api-docs
- Swagger UI:
GET /swagger-ui.html
- 默认返回体:
{ "code": "...", "message": "...", "data": ... }
2.2 认证前提
- 若要执行认证、鉴权、越权、Token 失效类用例,建议运行时配置
auth.enabled=true。
- 若当前运行环境仍为
auth.enabled=false 的 mock 模式,则以下用例中所有 401/403 校验需要在真实认证模式下执行。
2.3 种子数据建议
基于 src/main/resources/sql/init.sql,至少准备以下账号:
| 公司 |
用户名 |
密码 |
角色 |
DEMO |
admin |
admin123 |
ADMIN |
DEMO |
reviewer01 |
review123 |
REVIEWER |
DEMO |
annotator01 |
annot123 |
ANNOTATOR |
DEMO |
uploader01 |
upload123 |
UPLOADER |
额外建议准备:
- 第二家公司
TESTB
TESTB 下至少 1 个 ADMIN 账号
DEMO、TESTB 各自的资料、任务、配置、导出批次、视频任务样本
- JSON 接口:
Content-Type: application/json
- 文件上传:
multipart/form-data
- 受保护接口:
Authorization: Bearer <token>
- 视频回调启用密钥时:
X-Callback-Secret: <VIDEO_CALLBACK_SECRET>
3. 通用黑盒用例
除 POST /api/auth/login 与 POST /api/video/callback 外,所有受保护接口均应复用以下通用用例。
| 用例ID |
适用范围 |
场景 |
操作 |
预期结果 |
G-AUTH-001 |
全部受保护接口 |
缺少 Token |
不传 Authorization |
HTTP 401,code=UNAUTHORIZED |
G-AUTH-002 |
全部受保护接口 |
Token 格式错误 |
传 Authorization: BearerX xxx 或 Basic xxx |
HTTP 401,code=UNAUTHORIZED |
G-AUTH-003 |
全部受保护接口 |
Token 无效或过期 |
传不存在/已失效 Token |
HTTP 401,code=UNAUTHORIZED |
G-ROLE-001 |
有角色要求的接口 |
角色不足 |
用低权限账号访问高权限接口 |
HTTP 403,code=FORBIDDEN |
G-TENANT-001 |
租户数据相关接口 |
跨租户访问数据 |
用 TESTB Token 访问 DEMO 数据 |
返回 404、空列表或业务拒绝;不能读到 DEMO 数据 |
G-PAGE-001 |
分页接口 |
大页码限制 |
传超大 pageSize |
返回成功,pageSize 被限制到系统上限,不出现异常 |
G-ERR-001 |
全部接口 |
非法请求不能打穿到 5xx |
传缺参/错参/非法状态 |
返回可解释的 4xx 或失败业务码,不应无意义 500 |
4. 认证管理
4.1 POST /api/auth/login
| 用例ID |
场景 |
请求 |
预期结果 |
AUTH-LOGIN-001 |
正常登录 |
{"companyCode":"DEMO","username":"admin","password":"admin123"} |
HTTP 200,code=SUCCESS,返回 token/userId/username/role/expiresIn |
AUTH-LOGIN-002 |
密码错误 |
password=wrong |
HTTP 401,code=USER_NOT_FOUND |
AUTH-LOGIN-003 |
公司代码不存在 |
companyCode=NO_SUCH |
HTTP 401,code=USER_NOT_FOUND |
AUTH-LOGIN-004 |
账号被禁用 |
先将用户禁用,再登录 |
HTTP 403,code=USER_DISABLED |
AUTH-LOGIN-005 |
缺少必填字段 |
缺 companyCode、username 或 password |
返回失败,不能生成有效 Token,不应出现无提示 500 |
4.2 POST /api/auth/logout
| 用例ID |
场景 |
操作 |
预期结果 |
AUTH-LOGOUT-001 |
正常退出 |
用有效 Token 调用退出 |
HTTP 200,code=SUCCESS |
AUTH-LOGOUT-002 |
退出后 Token 立即失效 |
退出后继续访问 /api/auth/me |
HTTP 401,code=UNAUTHORIZED |
AUTH-LOGOUT-003 |
无 Token 退出 |
复用 G-AUTH-001 |
HTTP 401 |
4.3 GET /api/auth/me
| 用例ID |
场景 |
操作 |
预期结果 |
AUTH-ME-001 |
查询当前用户信息 |
用 admin Token 调用 |
HTTP 200,返回 id/username/realName/role/companyId/companyName |
AUTH-ME-002 |
已退出 Token 查询自己 |
先登录再退出,再调 /me |
HTTP 401,code=UNAUTHORIZED |
AUTH-ME-003 |
被禁用账号的旧 Token 查询自己 |
先登录,管理员禁用该用户,再调 /me |
HTTP 401,code=UNAUTHORIZED |
5. 公司管理
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001。
5.1 GET /api/companies
| 用例ID |
场景 |
请求 |
预期结果 |
COMPANY-LIST-001 |
管理员分页查询公司 |
?page=1&pageSize=20 |
HTTP 200,返回分页结构 |
COMPANY-LIST-002 |
按状态筛选 |
?status=ACTIVE |
仅返回对应状态公司 |
COMPANY-LIST-003 |
非管理员访问 |
用 REVIEWER 或 UPLOADER 调用 |
HTTP 403,code=FORBIDDEN |
5.2 POST /api/companies
| 用例ID |
场景 |
请求 |
预期结果 |
COMPANY-CREATE-001 |
创建公司成功 |
{"companyName":"测试公司B","companyCode":"TESTB"} |
HTTP 201,创建成功,状态默认 ACTIVE |
COMPANY-CREATE-002 |
公司代码重复 |
使用已存在 companyCode |
HTTP 409,code=DUPLICATE_COMPANY_CODE |
COMPANY-CREATE-003 |
公司名称重复 |
使用已存在 companyName |
HTTP 409,code=DUPLICATE_COMPANY_NAME |
COMPANY-CREATE-004 |
公司名为空 |
companyName 空或空白 |
HTTP 400,code=INVALID_COMPANY_FIELD |
COMPANY-CREATE-005 |
公司代码为空 |
companyCode 空或空白 |
HTTP 400,code=INVALID_COMPANY_FIELD |
5.3 PUT /api/companies/{id}
| 用例ID |
场景 |
请求 |
预期结果 |
COMPANY-UPDATE-001 |
更新公司成功 |
修改 companyName/companyCode |
HTTP 200,字段更新成功 |
COMPANY-UPDATE-002 |
更新不存在公司 |
id 不存在 |
HTTP 404,code=NOT_FOUND |
COMPANY-UPDATE-003 |
更新为重复代码 |
companyCode 改成已存在值 |
HTTP 409,code=DUPLICATE_COMPANY_CODE |
COMPANY-UPDATE-004 |
更新为重复名称 |
companyName 改成已存在值 |
HTTP 409,code=DUPLICATE_COMPANY_NAME |
5.4 PUT /api/companies/{id}/status
| 用例ID |
场景 |
请求 |
预期结果 |
COMPANY-STATUS-001 |
禁用公司成功 |
{"status":"DISABLED"} |
HTTP 200,公司状态变为 DISABLED |
COMPANY-STATUS-002 |
恢复公司成功 |
{"status":"ACTIVE"} |
HTTP 200,公司状态变为 ACTIVE |
COMPANY-STATUS-003 |
非法状态值 |
{"status":"UNKNOWN"} |
HTTP 400,code=INVALID_COMPANY_STATUS |
COMPANY-STATUS-004 |
公司不存在 |
不存在 id |
HTTP 404,code=NOT_FOUND |
5.5 DELETE /api/companies/{id}
| 用例ID |
场景 |
操作 |
预期结果 |
COMPANY-DELETE-001 |
删除空公司成功 |
删除无用户的公司 |
HTTP 200,删除成功 |
COMPANY-DELETE-002 |
公司下仍有用户 |
删除已有用户公司 |
HTTP 409,code=COMPANY_HAS_USERS |
COMPANY-DELETE-003 |
删除不存在公司 |
不存在 id |
HTTP 404,code=NOT_FOUND |
6. 用户管理
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
6.1 GET /api/users
| 用例ID |
场景 |
请求 |
预期结果 |
USER-LIST-001 |
管理员查看本公司用户 |
?page=1&pageSize=20 |
HTTP 200,仅返回当前公司用户 |
USER-LIST-002 |
跨租户隔离 |
用 TESTB 管理员查看列表 |
不出现 DEMO 用户 |
USER-LIST-003 |
非管理员访问 |
用 REVIEWER 调用 |
HTTP 403 |
6.2 POST /api/users
| 用例ID |
场景 |
请求 |
预期结果 |
USER-CREATE-001 |
创建用户成功 |
{"username":"qa01","password":"qa123456","realName":"测试员","role":"ANNOTATOR"} |
HTTP 200,创建成功,状态默认为 ACTIVE |
USER-CREATE-002 |
用户名重复 |
同公司创建同名用户 |
HTTP 409,code=DUPLICATE_USERNAME |
USER-CREATE-003 |
角色非法 |
role=VIEWER 或其他未支持角色 |
HTTP 400,code=INVALID_ROLE |
USER-CREATE-004 |
跨租户污染校验 |
TESTB 管理员创建用户后,DEMO 不可见 |
创建成功且仅属于当前公司 |
6.3 PUT /api/users/{id}
| 用例ID |
场景 |
请求 |
预期结果 |
USER-UPDATE-001 |
更新真实姓名成功 |
{"realName":"新名字"} |
HTTP 200,真实姓名更新 |
USER-UPDATE-002 |
更新密码成功 |
{"password":"newpass123"},再重新登录 |
新密码可登录,旧密码失效 |
USER-UPDATE-003 |
更新不存在用户 |
不存在 id |
HTTP 404,code=NOT_FOUND |
USER-UPDATE-004 |
更新他租户用户 |
用 TESTB 管理员修改 DEMO 用户 |
HTTP 404 或不可见 |
6.4 PUT /api/users/{id}/status
| 用例ID |
场景 |
请求 |
预期结果 |
USER-STATUS-001 |
禁用用户成功 |
{"status":"DISABLED"} |
HTTP 200,用户状态更新成功 |
USER-STATUS-002 |
禁用后旧 Token 失效 |
禁用后用该用户旧 Token 调 /api/auth/me |
HTTP 401,code=UNAUTHORIZED |
USER-STATUS-003 |
恢复用户成功 |
{"status":"ACTIVE"} |
HTTP 200 |
USER-STATUS-004 |
非法状态值 |
{"status":"LOCKED"} |
HTTP 400,code=INVALID_STATUS |
6.5 PUT /api/users/{id}/role
| 用例ID |
场景 |
请求 |
预期结果 |
USER-ROLE-001 |
修改角色成功 |
{"role":"REVIEWER"} |
HTTP 200,用户角色更新成功 |
USER-ROLE-002 |
角色变更立即生效 |
同一 Token 变更前访问 reviewer 接口 403,变更后重试 |
变更后无需重新登录即可访问成功 |
USER-ROLE-003 |
非法角色值 |
{"role":"VIEWER"} |
HTTP 400,code=INVALID_ROLE |
USER-ROLE-004 |
修改不存在用户 |
不存在 id |
HTTP 404,code=NOT_FOUND |
7. 资料管理
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
7.1 POST /api/source/upload
| 用例ID |
场景 |
请求 |
预期结果 |
SOURCE-UPLOAD-001 |
上传文本资料成功 |
multipart/form-data,传 file + dataType=TEXT |
HTTP 201,返回资料 id/fileName/dataType/status |
SOURCE-UPLOAD-002 |
上传图片资料成功 |
dataType=IMAGE |
HTTP 201 |
SOURCE-UPLOAD-003 |
上传视频资料成功 |
dataType=VIDEO |
HTTP 201 |
SOURCE-UPLOAD-004 |
空文件上传 |
文件为空 |
HTTP 400,code=FILE_EMPTY |
SOURCE-UPLOAD-005 |
不支持的资料类型 |
dataType=PDF |
HTTP 400,code=INVALID_TYPE |
SOURCE-UPLOAD-006 |
Swagger 文案兼容性检查 |
dataType=text 小写 |
应与文档约定一致;若失败需修正文档或实现 |
SOURCE-UPLOAD-007 |
低权限无权上传 |
用无上传权限账号访问 |
HTTP 403 |
7.2 GET /api/source/list
| 用例ID |
场景 |
请求 |
预期结果 |
SOURCE-LIST-001 |
上传员查看自己资料 |
用 uploader01 调用 |
仅返回自己上传的数据 |
SOURCE-LIST-002 |
管理员查看公司全部资料 |
用 admin 调用 |
返回公司内全部资料 |
SOURCE-LIST-003 |
按类型筛选 |
?dataType=TEXT |
仅返回对应类型 |
SOURCE-LIST-004 |
按状态筛选 |
?status=PENDING |
仅返回对应状态 |
SOURCE-LIST-005 |
跨租户隔离 |
TESTB 调用 |
看不到 DEMO 数据 |
7.3 GET /api/source/{id}
| 用例ID |
场景 |
操作 |
预期结果 |
SOURCE-DETAIL-001 |
查看资料详情成功 |
查询本公司资料 |
HTTP 200,返回详情及下载地址 |
SOURCE-DETAIL-002 |
查询不存在资料 |
id 不存在 |
HTTP 404,code=NOT_FOUND |
SOURCE-DETAIL-003 |
跨租户查看详情 |
用 TESTB Token 查 DEMO 资料 |
HTTP 404 或不可见 |
7.4 DELETE /api/source/{id}
| 用例ID |
场景 |
操作 |
预期结果 |
SOURCE-DELETE-001 |
删除 PENDING 资料成功 |
删除未进入流水线资料 |
HTTP 200 |
SOURCE-DELETE-002 |
删除不存在资料 |
id 不存在 |
HTTP 404,code=NOT_FOUND |
SOURCE-DELETE-003 |
删除已进入流水线资料 |
状态为 PREPROCESSING/EXTRACTING/QA_REVIEW/APPROVED |
HTTP 409,code=SOURCE_IN_PIPELINE |
SOURCE-DELETE-004 |
非管理员删除 |
用 UPLOADER 删除资料 |
HTTP 403 |
8. 任务管理
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
8.1 GET /api/tasks/pool
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-POOL-001 |
标注员查看任务池 |
用 ANNOTATOR 调用 |
仅返回 EXTRACTION + UNCLAIMED 任务 |
TASK-POOL-002 |
Reviewer/Admin 调用任务池 |
用 REVIEWER 或 ADMIN 调用 |
返回 SUBMITTED 待审任务 |
TASK-POOL-003 |
跨租户隔离 |
TESTB 调用 |
仅能看到本公司任务 |
8.2 GET /api/tasks/mine
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-MINE-001 |
查询我的任务成功 |
?page=1&pageSize=20 |
返回当前用户的 IN_PROGRESS/SUBMITTED/REJECTED 任务 |
TASK-MINE-002 |
按状态过滤 |
?status=REJECTED |
仅返回对应状态 |
TASK-MINE-003 |
未领取任务不应出现在 mine |
准备 UNCLAIMED 任务 |
列表中不出现该任务 |
8.3 GET /api/tasks/pending-review
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-REVIEW-001 |
Reviewer 查询待审批任务 |
?taskType=EXTRACTION |
仅返回 SUBMITTED 且符合类型的任务 |
TASK-REVIEW-002 |
非 Reviewer 访问 |
用 ANNOTATOR 调用 |
HTTP 403 |
TASK-REVIEW-003 |
跨租户隔离 |
TESTB 调用 |
看不到 DEMO 待审任务 |
8.4 GET /api/tasks
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-LIST-001 |
管理员查询全部任务 |
?status=SUBMITTED&taskType=QA_GENERATION |
返回过滤后的本公司任务 |
TASK-LIST-002 |
非管理员访问 |
用 REVIEWER 调用 |
HTTP 403 |
8.5 POST /api/tasks
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-CREATE-001 |
创建提取任务成功 |
{"sourceId":<id>,"taskType":"EXTRACTION"} |
HTTP 200,返回新任务,状态 UNCLAIMED |
TASK-CREATE-002 |
创建 QA 任务成功 |
{"sourceId":<id>,"taskType":"QA_GENERATION"} |
HTTP 200 |
TASK-CREATE-003 |
缺少 sourceId |
仅传 taskType |
应返回明确失败,不应出现裸 500 |
TASK-CREATE-004 |
缺少 taskType |
仅传 sourceId |
应返回明确失败,不应出现裸 500 |
8.6 GET /api/tasks/{id}
| 用例ID |
场景 |
操作 |
预期结果 |
TASK-DETAIL-001 |
查询任务详情成功 |
查询本公司任务 |
HTTP 200,返回任务详情 |
TASK-DETAIL-002 |
查询不存在任务 |
不存在 id |
HTTP 404,code=NOT_FOUND |
TASK-DETAIL-003 |
跨租户查看任务 |
用 TESTB 查询 DEMO 任务 |
HTTP 404 或不可见 |
8.7 POST /api/tasks/{id}/claim
| 用例ID |
场景 |
操作 |
预期结果 |
TASK-CLAIM-001 |
正常领取未领取任务 |
ANNOTATOR 领取 UNCLAIMED 任务 |
HTTP 200,任务状态变为 IN_PROGRESS |
TASK-CLAIM-002 |
并发抢任务 |
10 并发领取同一任务 |
恰好 1 个成功,其余 HTTP 409,code=TASK_CLAIMED |
TASK-CLAIM-003 |
重复领取已被占用任务 |
第二个用户再领取 |
HTTP 409,code=TASK_CLAIMED |
8.8 POST /api/tasks/{id}/unclaim
| 用例ID |
场景 |
操作 |
预期结果 |
TASK-UNCLAIM-001 |
放弃进行中任务成功 |
当前领取人放弃 IN_PROGRESS 任务 |
HTTP 200,状态回到 UNCLAIMED |
TASK-UNCLAIM-002 |
非法状态放弃 |
对 SUBMITTED/REJECTED/APPROVED 任务调用 |
HTTP 409,code=INVALID_STATE_TRANSITION |
TASK-UNCLAIM-003 |
非领取人放弃他人任务 |
用别的标注员调用 |
应被拒绝,不能让他人释放任务 |
8.9 POST /api/tasks/{id}/reclaim
| 用例ID |
场景 |
操作 |
预期结果 |
TASK-RECLAIM-001 |
原领取人重领被驳回任务 |
原领取人对 REJECTED 任务调用 |
HTTP 200,状态变为 IN_PROGRESS |
TASK-RECLAIM-002 |
非原领取人重领 |
其他用户调用 |
HTTP 403,code=FORBIDDEN |
TASK-RECLAIM-003 |
非驳回状态重领 |
对 IN_PROGRESS 任务调用 |
HTTP 409,code=INVALID_STATE_TRANSITION |
8.10 PUT /api/tasks/{id}/reassign
| 用例ID |
场景 |
请求 |
预期结果 |
TASK-REASSIGN-001 |
管理员强制指派成功 |
{"userId":<targetUserId>} |
HTTP 200,任务归属变更到目标用户 |
TASK-REASSIGN-002 |
指派不存在任务 |
不存在 id |
HTTP 404,code=NOT_FOUND |
TASK-REASSIGN-003 |
缺少 userId |
空请求体或缺字段 |
应返回明确失败,不应裸 500 |
TASK-REASSIGN-004 |
指派后状态一致性 |
指派后查询任务 |
任务应处于可执行状态,归属人与时间被更新 |
9. 提取标注
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
| 用例ID |
场景 |
操作 |
预期结果 |
EXT-GET-001 |
获取提取结果成功 |
查询本公司任务 |
HTTP 200,返回 taskId/sourceType/sourceFilePath/isFinal/resultJson |
EXT-GET-002 |
查询不存在任务 |
不存在 taskId |
HTTP 404,code=NOT_FOUND |
EXT-GET-003 |
跨租户查询结果 |
用 TESTB 查询 DEMO 任务 |
HTTP 404 或不可见 |
| 用例ID |
场景 |
请求体 |
预期结果 |
EXT-PUT-001 |
更新结果成功 |
传合法 JSON 字符串 |
HTTP 200 |
EXT-PUT-002 |
非法 JSON |
传坏 JSON |
HTTP 400,code=INVALID_JSON |
EXT-PUT-003 |
任务不存在 |
不存在 taskId |
HTTP 404,code=NOT_FOUND |
| 用例ID |
场景 |
操作 |
预期结果 |
EXT-SUBMIT-001 |
提交成功 |
IN_PROGRESS 任务提交 |
HTTP 200,任务变为 SUBMITTED |
EXT-SUBMIT-002 |
非法状态提交 |
UNCLAIMED/REJECTED/APPROVED 时提交 |
HTTP 409,code=INVALID_STATE_TRANSITION |
| 用例ID |
场景 |
操作 |
预期结果 |
EXT-APPROVE-001 |
审批通过成功 |
Reviewer 审批 SUBMITTED 任务 |
HTTP 200,原任务 APPROVED,isFinal=true |
EXT-APPROVE-002 |
审批通过触发后续链路 |
审批完成后查数据库/接口 |
自动创建 QA_GENERATION 任务,source_data.status=QA_REVIEW,创建 training_dataset |
EXT-APPROVE-003 |
自审拦截 |
提交人与审批人相同 |
HTTP 403,code=SELF_REVIEW_FORBIDDEN |
EXT-APPROVE-004 |
非法状态审批 |
未提交任务直接审批 |
HTTP 409,code=INVALID_STATE_TRANSITION |
| 用例ID |
场景 |
请求 |
预期结果 |
EXT-REJECT-001 |
驳回成功 |
{"reason":"实体识别有误"} |
HTTP 200,任务变为 REJECTED |
EXT-REJECT-002 |
驳回原因为空 |
空 body 或空 reason |
HTTP 400,code=REASON_REQUIRED |
EXT-REJECT-003 |
自审驳回 |
提交人与驳回人相同 |
HTTP 403,code=SELF_REVIEW_FORBIDDEN |
EXT-REJECT-004 |
驳回后可重领重提 |
驳回后原领取人调 /reclaim 再 /submit |
可重领,任务恢复到 SUBMITTED |
10. 问答生成
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
10.1 GET /api/qa/{taskId}
| 用例ID |
场景 |
操作 |
预期结果 |
QA-GET-001 |
获取候选问答对成功 |
查询本公司 QA 任务 |
HTTP 200,返回 taskId/sourceType/items |
QA-GET-002 |
查询不存在任务 |
不存在 taskId |
HTTP 404,code=NOT_FOUND |
QA-GET-003 |
跨租户查询 |
用 TESTB 查询 DEMO 任务 |
HTTP 404 或不可见 |
10.2 PUT /api/qa/{taskId}
| 用例ID |
场景 |
请求体 |
预期结果 |
QA-PUT-001 |
更新候选问答对成功 |
{"items":[...]} |
HTTP 200 |
QA-PUT-002 |
非法 JSON |
传坏 JSON |
HTTP 400,code=INVALID_JSON |
QA-PUT-003 |
缺失 items 字段 |
传空对象 {} |
不应报 5xx;若允许则生成空 conversations |
10.3 POST /api/qa/{taskId}/submit
| 用例ID |
场景 |
操作 |
预期结果 |
QA-SUBMIT-001 |
提交成功 |
IN_PROGRESS 任务提交 |
HTTP 200,任务变为 SUBMITTED |
QA-SUBMIT-002 |
非法状态提交 |
对 UNCLAIMED/REJECTED/APPROVED 任务提交 |
HTTP 409,code=INVALID_STATE_TRANSITION |
10.4 POST /api/qa/{taskId}/approve
| 用例ID |
场景 |
操作 |
预期结果 |
QA-APPROVE-001 |
QA 审批通过成功 |
Reviewer 审批 SUBMITTED QA 任务 |
HTTP 200 |
QA-APPROVE-002 |
审批通过完成整条流水线 |
审批完成后查状态 |
training_dataset.status=APPROVED,任务 APPROVED,source_data.status=APPROVED |
QA-APPROVE-003 |
自审拦截 |
提交人与审批人相同 |
HTTP 403,code=SELF_REVIEW_FORBIDDEN |
10.5 POST /api/qa/{taskId}/reject
| 用例ID |
场景 |
请求 |
预期结果 |
QA-REJECT-001 |
驳回成功 |
{"reason":"问题描述不准确"} |
HTTP 200,任务变为 REJECTED |
QA-REJECT-002 |
驳回原因为空 |
空 body 或空 reason |
HTTP 400,code=REASON_REQUIRED |
QA-REJECT-003 |
驳回后候选数据删除 |
驳回后检查 training_dataset |
候选问答对被删除,source_data 维持 QA_REVIEW |
QA-REJECT-004 |
驳回后可重领重提 |
原领取人调 /reclaim 再 /submit |
可重领,重新提交成功 |
11. 导出与微调
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
11.1 GET /api/training/samples
| 用例ID |
场景 |
请求 |
预期结果 |
EXPORT-SAMPLE-001 |
查询已审批样本成功 |
?page=1&pageSize=20 |
HTTP 200,返回 APPROVED 样本 |
EXPORT-SAMPLE-002 |
仅看未导出样本 |
?exported=false |
只返回 export_batch_id 为空的数据 |
EXPORT-SAMPLE-003 |
按样本类型过滤 |
?sampleType=TEXT |
仅返回对应类型 |
EXPORT-SAMPLE-004 |
非管理员访问 |
用 ANNOTATOR 调用 |
HTTP 403 |
11.2 POST /api/export/batch
| 用例ID |
场景 |
请求 |
预期结果 |
EXPORT-BATCH-001 |
创建导出批次成功 |
{"sampleIds":[<approvedId1>,<approvedId2>]} |
HTTP 201,返回批次信息 |
EXPORT-BATCH-002 |
样本列表为空 |
{"sampleIds":[]} |
HTTP 400,code=EMPTY_SAMPLES |
EXPORT-BATCH-003 |
包含未审批样本 |
混入 PENDING_REVIEW/REJECTED 样本 |
HTTP 400,code=INVALID_SAMPLES |
EXPORT-BATCH-004 |
包含他租户样本 |
混入其他公司样本 ID |
HTTP 400,code=INVALID_SAMPLES |
EXPORT-BATCH-005 |
批次创建后回写样本导出信息 |
创建成功后查询样本 |
exportBatchId/exportedAt 已写入 |
11.3 POST /api/export/{batchId}/finetune
| 用例ID |
场景 |
操作 |
预期结果 |
FINETUNE-TRIGGER-001 |
首次触发微调成功 |
对 NOT_STARTED 批次调用 |
HTTP 200,返回 glmJobId/finetuneStatus=RUNNING |
FINETUNE-TRIGGER-002 |
重复触发微调 |
对已启动批次再次调用 |
HTTP 409,code=FINETUNE_ALREADY_STARTED |
FINETUNE-TRIGGER-003 |
触发不存在批次 |
不存在 batchId |
HTTP 404,code=NOT_FOUND |
11.4 GET /api/export/{batchId}/status
| 用例ID |
场景 |
操作 |
预期结果 |
FINETUNE-STATUS-001 |
未启动批次查询状态 |
glmJobId 为空批次 |
HTTP 200,返回 NOT_STARTED/progress=0 |
FINETUNE-STATUS-002 |
已启动批次查询状态 |
对已提交微调任务批次调用 |
HTTP 200,返回 batchId/glmJobId/finetuneStatus/progress/errorMessage |
FINETUNE-STATUS-003 |
跨租户状态隔离 |
用 TESTB 查 DEMO 批次 |
HTTP 404 或不可见 |
11.5 GET /api/export/list
| 用例ID |
场景 |
请求 |
预期结果 |
EXPORT-LIST-001 |
分页查询导出批次成功 |
?page=1&pageSize=20 |
HTTP 200,仅返回当前公司批次 |
EXPORT-LIST-002 |
跨租户隔离 |
TESTB 调用 |
看不到 DEMO 批次 |
12. 系统配置
说明:本组接口复用 G-AUTH-001~003、G-ROLE-001、G-TENANT-001。
12.1 GET /api/config
| 用例ID |
场景 |
操作 |
预期结果 |
CONFIG-LIST-001 |
查询合并配置成功 |
管理员查询 |
HTTP 200,返回当前公司可见配置列表 |
CONFIG-LIST-002 |
公司配置覆盖全局默认 |
先写公司专属 model_default,再查询 |
返回 scope=COMPANY 且值为公司专属值 |
CONFIG-LIST-003 |
未配置公司专属时回退全局 |
清除公司专属后查询 |
返回 scope=GLOBAL |
CONFIG-LIST-004 |
跨租户隔离 |
DEMO 配置不影响 TESTB |
另一公司仍看到自己的配置或全局默认 |
12.2 PUT /api/config/{key}
| 用例ID |
场景 |
请求 |
预期结果 |
CONFIG-UPSERT-001 |
新增公司专属配置成功 |
{"value":"glm-4-plus","description":"默认模型"} |
HTTP 200,创建成功 |
CONFIG-UPSERT-002 |
更新同键配置成功 |
同一个 key 连续两次 PUT |
HTTP 200,第二次为更新而不是重复插入 |
CONFIG-UPSERT-003 |
未知配置键 |
PUT /api/config/unknown_key |
HTTP 400,code=UNKNOWN_CONFIG_KEY |
CONFIG-UPSERT-004 |
空配置值 |
{"value":""} |
HTTP 400,code=INVALID_CONFIG_VALUE |
13. 视频处理
说明:
POST /api/video/callback 为公开接口,不复用 G-AUTH-001~003
- 其余视频接口复用
G-AUTH-001~003、G-ROLE-001、G-TENANT-001
13.1 POST /api/video/process
| 用例ID |
场景 |
请求 |
预期结果 |
VIDEO-CREATE-001 |
创建视频处理任务成功 |
{"sourceId":<videoSourceId>,"jobType":"FRAME_EXTRACT","params":"{\"frameInterval\":30}"} |
创建成功,返回 job,资料状态进入 PREPROCESSING |
VIDEO-CREATE-002 |
使用另一种任务类型成功 |
jobType=VIDEO_TO_TEXT |
创建成功 |
VIDEO-CREATE-003 |
缺少必要字段 |
缺 sourceId 或 jobType |
返回失败,code=INVALID_PARAMS,且不能创建 job |
VIDEO-CREATE-004 |
非法任务类型 |
jobType=UNKNOWN |
HTTP 400,code=INVALID_JOB_TYPE |
VIDEO-CREATE-005 |
非视频资料创建视频任务 |
对非 VIDEO 资料调用 |
应返回明确失败,不应产生错误状态迁移 |
VIDEO-CREATE-006 |
跨租户创建视频任务 |
用 TESTB 处理 DEMO 资料 |
HTTP 404 或不可见 |
13.2 GET /api/video/jobs/{jobId}
| 用例ID |
场景 |
操作 |
预期结果 |
VIDEO-GET-001 |
查询视频任务成功 |
查询本公司 jobId |
HTTP 200,返回任务状态、重试次数、输出路径等 |
VIDEO-GET-002 |
查询不存在任务 |
不存在 jobId |
HTTP 404,code=NOT_FOUND |
VIDEO-GET-003 |
跨租户查询 |
用 TESTB 查 DEMO 任务 |
HTTP 404 或不可见 |
13.3 POST /api/video/jobs/{jobId}/reset
| 用例ID |
场景 |
操作 |
预期结果 |
VIDEO-RESET-001 |
重置失败任务成功 |
对 FAILED 任务调用 |
HTTP 200,job 状态变为 PENDING,retryCount=0 |
VIDEO-RESET-002 |
非失败任务不允许重置 |
对 PENDING/RETRYING/SUCCESS 调用 |
HTTP 400,code=INVALID_TRANSITION |
VIDEO-RESET-003 |
跨租户重置 |
用 TESTB 调 DEMO 任务 |
HTTP 404 或不可见 |
13.4 POST /api/video/callback
| 用例ID |
场景 |
请求 |
预期结果 |
VIDEO-CALLBACK-001 |
SUCCESS 回调成功 |
{"jobId":123,"status":"SUCCESS","outputPath":"processed/frames.zip"} |
HTTP 200,job 变 SUCCESS,source_data.status=PENDING |
VIDEO-CALLBACK-002 |
SUCCESS 回调幂等 |
对同一 jobId 连续两次发送相同 SUCCESS 回调 |
两次都成功,第二次不重复改状态、不重复产出副作用 |
VIDEO-CALLBACK-003 |
FAILED 回调触发重试 |
对未达重试上限 job 发 FAILED |
job 变 RETRYING,retryCount+1 |
VIDEO-CALLBACK-004 |
超过最大重试次数 |
retryCount=maxRetries-1 时再发 FAILED |
job 变 FAILED,source_data.status=PENDING |
VIDEO-CALLBACK-005 |
回调 job 不存在 |
jobId 不存在 |
接口不应打穿服务;应安全返回,无脏数据写入 |
VIDEO-CALLBACK-006 |
启用共享密钥时密钥错误 |
不传或传错 X-Callback-Secret |
返回失败,code=UNAUTHORIZED |
VIDEO-CALLBACK-007 |
回调缺少 jobId/status |
缺关键字段 |
返回明确失败,不应裸 500 |
14. 推荐执行顺序
建议按以下顺序执行,能更快定位问题来源:
- 认证管理
- 公司管理
- 用户管理
- 资料管理
- 任务管理
- 提取标注
- 问答生成
- 导出与微调
- 系统配置
- 视频处理
15. 高风险回归点
每次版本回归至少覆盖以下高风险用例:
| 优先级 |
用例ID |
说明 |
| P0 |
AUTH-LOGIN-001 |
登录主链路 |
| P0 |
AUTH-LOGOUT-002 |
退出后 Token 立即失效 |
| P0 |
USER-STATUS-002 |
禁用账号后旧 Token 失效 |
| P0 |
SOURCE-DELETE-003 |
资料进入流水线后不可删除 |
| P0 |
TASK-CLAIM-002 |
并发抢任务只允许一个成功 |
| P0 |
EXT-APPROVE-002 |
提取审批通过自动推进 QA 链路 |
| P0 |
QA-APPROVE-002 |
QA 审批通过完成整条流水线 |
| P0 |
EXPORT-BATCH-003 |
非 APPROVED 样本不可导出 |
| P0 |
CONFIG-LIST-004 |
配置跨租户隔离 |
| P0 |
VIDEO-CALLBACK-002 |
视频回调幂等 |
16. 后续落地建议
本文档适合作为三类产物的源:
- Swagger 手工测试清单
- Postman/Apifox/Newman 自动化用例集
src/test/java/com/label/blackbox 下的 API 黑盒自动化测试
若需要继续落地,建议优先把以下用例自动化:
- 认证与 Token 生命周期
- 任务领取并发
- 提取/问答审批状态流转
- 导出样本校验
- 视频回调幂等与重试