# CFC 接口业务级重测报告(Business-level Retest) > 生成时间:2026-10-27 · 测试目标:`cfc.iwintrue.com`(经 `192.168.16.251` + `Host` 头访问) > 测试脚本:`ops_interface_smoke.py`(本轮已升级:契约感知断言 + `direct-register` 多角色 token 前置 + 错误路径修正) > 用例来源:`interface_test_focus_biz.tsv`(19 条聚焦业务用例)+ 多角色验证 4 条 > 契约基线:`INTERFACE_CONTRACT_REVIEW.md` --- ## 一、结论摘要 - **断言已升级为契约感知**:成功 = `Result.code == 200`;`HTTP 200 + code≠200`(匿名放行/业务失败)归 `BIZ_FAIL`;真 `HTTP 401` 归 `AUTH_FAIL`;`404` 归 `NOT_FOUND`。 - **多角色 token 前置可用**:`wechat-login`(父)+ `direct-register(role=teacher)`(师)均成功获取;角色访问控制验证通过(见第三节)。 - **错误路径已修正**:原 `/api/user/switch-*` 404 全部修正为真实路由,废弃接口现正确返回 `410`。 - **发现 1 个需开发团队处理的真问题**:`/api/health-report/report/latest`、`/api/health-report/indicators/current`、`/api/task/today`、`/api/health-report/indicators/rebuild` 在**已部署服务器返回 404**,但源码中确有这些路由(见 `INTERFACE_CONTRACT_REVIEW.md` 证据)。疑似**部署版本与源码分支不一致(版本错位)**。 --- ## 二、分类汇总(共 23 条) | 分类 | 数量 | 说明 | |------|------|------| | `BIZ_OK` | 7 | 契约成功(code=200) | | `BIZ_FAIL` | 12 | HTTP 200 但 code≠200(含 3×`410` 废弃接口 + 9×空体预期失败) | | `NOT_FOUND` | 4 | 已部署服务器 404(见第四节,疑似版本错位) | | `AUTH_FAIL` | 0 | 本轮无真 401(匿名放行场景归 BIZ_FAIL,符合契约) | | `SERVER_ERR` | 0 | 无 5xx | | `CONN_ERR` | 0 | 连通正常 | > 业务成功率(BIZ_OK)7/23 = 30%。该值偏低属**预期**:本批用例多为空体请求,9 条 BIZ_FAIL 是"缺必填参数"的结构化失败,证明接口可达且返回规范 `Result`,并非崩溃。 --- ## 三、多角色验证(本轮核心升级,全部通过) | 验证项 | 请求身份 | 结果 | 结论 | |--------|----------|------|------| | `/api/auth/verify` | teacher token | `BIZ_OK` (code=200) | teacher token 有效 | | `/api/family/guide-bind` | parent token | `BIZ_FAIL` msg="只有成长规划师才能使用此功能" | parent 被正确拒绝(角色校验生效) | | `/api/family/guide-bind` | teacher token | `BIZ_FAIL` msg="邀请码无效" | teacher 角色被接受,进入业务校验(非角色拒绝) | | `/api/health-report/indicators/rebuild` | parent token | `NOT_FOUND` (404) | 见第四节(路由在部署端缺失) | **结论**:多角色 token 获取与 RBAC 行为验证链路打通,测试脚本已具备业务级多角色能力。 --- ## 四、需开发团队处理的契约缺口(优先级高) 以下路由在源码中存在,但**已部署的 `cfc.iwintrue.com` 返回 404**: | 接口 | 源码证据(INTERFACE_CONTRACT_REVIEW.md) | 部署端表现 | |------|------------------------------------------|------------| | `POST /api/health-report/report/latest` | `HealthReportController.java:295` | 404 | | `POST /api/health-report/indicators/current` | `HealthReportController.java:541` | 404 | | `POST /api/health-report/indicators/rebuild` | `HealthReportController.java:516` | 404 | | `POST /api/task/today` | `TaskController.java:81` | 404 | **初步判断**:同服务器上 `activity/list`、`product/list`、`health-status/get` 等均正常 200,说明是**特定 handler 未部署**而非网络/网关问题。最大嫌疑是**部署版本落后源码分支**(如部署跑 `master`、而源码在 `feature/ui-token-u5-color-tokens` 或反之)。 **建议动作**: 1. 确认 `cfc.iwintrue.com` 实际部署的分支/构建号; 2. 重新部署最新构建,或对齐测试目标到正确环境; 3. 对齐后重跑本脚本,404 应转为 BIZ_FAIL(空体预期失败)或 BIZ_OK。 --- ## 五、废弃接口(应迁移,非缺陷) | 接口 | 部署端表现 | 建议 | |------|------------|------| | `/api/family/user/switch-back-to-parent` | `410 Gone` | 前端仍引用,应迁移到 `/api/family/member/switch` | | `/api/family/user/switch-mode` | `410 Gone` | 同上 | | `/api/family/user/switch-to-child` | `410 Gone` | 同上 | 前端 `request()` 调用中仍出现上述废弃路径,属技术债,建议统一切换到 `/api/family/member/switch`(切换成员视图)。 --- ## 六、附:本轮修正清单(脚本侧) 1. `_classify()` 新增 `AUTH_FAIL`(HTTP 401)分类,区分"真未登录"与"匿名放行伪 200"。 2. 修复 4 类错误路径:`/api/user/switch-*` → `/api/auth/switch-role`、`/api/family/user/switch-{back-to-parent,mode,to-child}`。 3. 新增 `direct_register()` + `acquire_tokens()`:父 token 优先 `wechat-login`,师 token 用 `direct-register(role=teacher)`;`--multi-role` 按需获取(避免定时任务每轮新建教师账号)。 4. 新增 `--only-extra`:支持只跑 `--extra` 聚焦用例,便于快速业务级重测。 5. 定时闭环 `run_interface_tests_cron.sh` 报告生成已同步 `AUTH_FAIL` 分类。 --- ## 七、全量结果明细(`interface_test_biz_retest.tsv`) | page | fn | method | path | http | biz | cat | |------|----|--------|------|------|-----|-----| | auth | directRegister | POST | /api/auth/direct-register | 200 | 500 | BIZ_FAIL | | auth | ssoLogin | POST | /api/auth/sso-login | 200 | 500 | BIZ_FAIL | | auth | verify | POST | /api/auth/verify | 200 | 200 | BIZ_OK | | auth | switchRole | POST | /api/auth/switch-role | 200 | 200 | BIZ_OK | | family | inviteCheck | POST | /api/family/invite/check-family | 200 | 200 | BIZ_OK | | family | guideBind | POST | /api/family/guide-bind | 200 | 500 | BIZ_FAIL | | family | memberSwitch | POST | /api/family/member/switch | 200 | 500 | BIZ_FAIL | | family | switchBackToParent | POST | /api/family/user/switch-back-to-parent | 200 | 410 | BIZ_FAIL | | family | switchMode | POST | /api/family/user/switch-mode | 200 | 410 | BIZ_FAIL | | family | switchToChild | POST | /api/family/user/switch-to-child | 200 | 410 | BIZ_FAIL | | healthStatus | get | POST | /api/health-status/get | 200 | 200 | BIZ_OK | | healthStatus | save | POST | /api/health-status/save | 200 | 500 | BIZ_FAIL | | healthReport | latest | POST | /api/health-report/report/latest | 404 | — | NOT_FOUND | | healthReport | indicatorsCurrent | POST | /api/health-report/indicators/current | 404 | — | NOT_FOUND | | activity | list | POST | /api/activity/list | 200 | 200 | BIZ_OK | | activity | detail | POST | /api/activity/detail | 200 | 500 | BIZ_FAIL | | task | today | POST | /api/task/today | 404 | — | NOT_FOUND | | product | list | POST | /api/product/list | 200 | 200 | BIZ_OK | | product | detail | POST | /api/product/detail | 200 | 500 | BIZ_FAIL | | __multi_role__ | teacherVerify | POST | /api/auth/verify | 200 | 200 | BIZ_OK | | __multi_role__ | guideBindAsParent | POST | /api/family/guide-bind | 200 | 500 | BIZ_FAIL | | __multi_role__ | guideBindAsTeacher | POST | /api/family/guide-bind | 200 | 500 | BIZ_FAIL | | __multi_role__ | indicatorsRebuildParent | POST | /api/health-report/indicators/rebuild | 404 | — | NOT_FOUND |