Просмотр исходного кода

Merge branch 'feature/ui-token-u5-color-tokens' into cfclub — 测试工作回归 cfclub

合并内容:
- tests/ 测试资产(用户场景/结构化用例/缺陷单/可跑 e2e 规格/playwright 独立配置)
- 接口测试闭环脚本(run_interface_tests_cron.sh/.bat, ops_interface_smoke.py, scan_frontend_endpoints.py)
- 接口冒烟测试报告产物与 cfc-frontend 接口矩阵
E2E Test Bot 2 недель назад
Родитель
Сommit
7e5d6a89c6
36 измененных файлов с 7426 добавлено и 1 удалено
  1. 277 0
      INTERFACE_CONTRACT_REVIEW.md
  2. 115 0
      INTERFACE_TEST_BUSINESS_REPORT.md
  3. 29 0
      INTERFACE_TEST_REPORT.md
  4. 2588 0
      cfc-frontend/INTERFACE_TEST_MATRIX.md
  5. 24 0
      interface_test_biz_retest.tsv
  6. 2 0
      interface_test_extra_cases.tsv
  7. 20 0
      interface_test_focus_biz.tsv
  8. 1008 0
      interface_test_report.tsv
  9. 1309 0
      ops_interface_smoke.py
  10. 18 0
      run_interface_tests_cron.bat
  11. 222 0
      run_interface_tests_cron.sh
  12. 72 0
      scan_frontend_endpoints.py
  13. 85 0
      tests/README.md
  14. 203 0
      tests/defects/DEFECTS-assessment-appointment.md
  15. 144 0
      tests/e2e/assessment-appointment-functional.spec.js
  16. 124 0
      tests/e2e/assessment-appointment.spec.js
  17. 1 1
      tests/package-lock.json
  18. 30 0
      tests/playwright.config.func.js
  19. 46 0
      tests/test-cases/README.md
  20. 26 0
      tests/test-cases/admin.md
  21. 20 0
      tests/test-cases/child.md
  22. 40 0
      tests/test-cases/cross-role-e2e.md
  23. 102 0
      tests/test-cases/deep-dive-assessment-appointment.md
  24. 91 0
      tests/test-cases/deep-dive-plan-activation.md
  25. 17 0
      tests/test-cases/guest.md
  26. 34 0
      tests/test-cases/parent.md
  27. 26 0
      tests/test-cases/teacher.md
  28. 15 0
      tests/test-cases/vendor.md
  29. 4 0
      tests/test-results/.last-run.json
  30. 85 0
      tests/user-scenarios/01-guest.md
  31. 201 0
      tests/user-scenarios/02-parent.md
  32. 129 0
      tests/user-scenarios/03-child.md
  33. 128 0
      tests/user-scenarios/04-teacher.md
  34. 113 0
      tests/user-scenarios/05-admin.md
  35. 51 0
      tests/user-scenarios/06-vendor.md
  36. 27 0
      tests/user-scenarios/README.md

+ 277 - 0
INTERFACE_CONTRACT_REVIEW.md

@@ -0,0 +1,277 @@
+# CFC 小程序后端「接口契约」评审报告
+
+> 评审角色:集成·接口级评审专家(柯砚)
+> 代码仓库:`D:/cfc` · 后端:`D:/cfc/cfc-backend`(Spring Boot 2.7,端口 **9082**,统一 `@PostMapping`,JWT Bearer 鉴权)
+> 评审方式:全程只读,仅新增本文件,未修改/删除/提交任何源码
+> 目标:为把空体冒烟测试升级为业务级测试(带真实参数、多角色 token)提供契约基线,逐步达到 100% 通过
+
+---
+
+## 0. 前置结论(先读这段)
+
+1. **统一响应结构**:`Result<T>{code,message,data}`,位于 `common/Result.java`。`code=200` 成功;其余为非 0 失败码。
+2. **鉴权**:`JwtInterceptor` 拦截 `/api/**`,白名单见 §2。**token 通过 `Authorization: Bearer <token>` 头传递**(也可走 `?token=` 参数)。token 字段名是 `token`(在 `LoginResultDTO` 里,不是 `accessToken`)。
+3. **既有冒烟 0% 的根因**:`INTERFACE_TEST_REPORT.md` 显示全部 `NON_JSON`,目标域填的是 `cfc.iwintrue.com`(外网不可达,返回 HTML 而非 JSON)。**测试应改为指向 `http://localhost:9082`**。同时基线里大量路径写错(如 `/api/user/switch-*`、实际是 `/api/family/user/switch-role`),导致 404/错路由。
+4. **没有 `mock-login` 接口**。`auto-login` 已废弃(返回 410)。多角色 token 的获取姿势见 §3、§4。
+
+---
+
+## 1. 统一响应结构 `Result<T>` 与 code 取值约定
+
+**定义位置**:`src/main/java/com/etotem/cfc/common/Result.java:8`
+
+字段:
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `code` | `Integer` | 业务码,200=成功 |
+| `message` | `String` | 提示文案 |
+| `data` | `T` | 业务数据,可 null |
+
+**code 取值约定(证据均在 `Result.java`)**:
+
+| 取值 | 含义 | 出处 / 触发位置 |
+|------|------|----------------|
+| `200` | 成功 | `Result.java:16,23,31`(`success()` 系列统一写 200) |
+| `500` | 通用失败(参数错误、业务异常、未登录等混用) | `Result.java:39`(`error(String)` 写死 500) |
+| `5001` | 无家庭(请先创建或加入家庭) | `Result.java:45-50`(`noFamily()`) |
+| `401` | 未登录 / token 失效 | 见 §2 `JwtInterceptor.writeUnauthorized`;业务层 `AuthController.verifyToken` `AuthController.java:226,238,246`、`sso-ticket` `:353` 用 `Result.error(401,...)` |
+| `403` | 无权限(越权访问家庭数据 / 组织权限) | `FamilyAccessInterceptor.java:139`(`{"code":403,...}`);`common/AdminOrgAccess.java:40,43,46,52,61` |
+| `410` | 接口已废弃(Gone) | `AuthController.java:139`(auto-login)、`FamilyController.java:42,52`、`FamilyUserController.java:97,124,131`(switch-mode/switch-to-child/switch-back-to-parent) |
+| `4001` | 业务自定义失败(如“请先购买健康启航计划体验包”) | `HealthReportController.java:216` |
+| 其他任意非 0 | 各业务自定义错误码 | 全代码库散落大量 `Result.error(NNNN, msg)`,测试需**按接口逐个核对实际码**,不能假设只有上面几种 |
+
+**对编写用例的建议**:
+- 断言不要只判 `200`。把「业务成功」定义为 `code==200 && data!=null`(或 data 符合契约);「失败」定义为 `code!=200` 且断言 `message` 非空。
+- 必须记录每个接口返回的**实际错误码**(尤其是自定义码如 4001),避免把“预期失败”误判为“通过”或“崩溃”。
+- 注意:**未带 token 访问非白名单接口,不一定返回 401**。`JwtInterceptor` 对“无 token 且非强制登录路径”会注入匿名用户(`userId=-1, role=anonymous`)并放行,下游 Controller 通常返回 `code=500` 的 `Result.error("请先登录")`/`"未登录"`,HTTP 状态仍是 200。**只有 token 格式非法/过期、或命中 `LOGIN_REQUIRED_PATHS` 才会真正返回 HTTP 401**。用例要区分这两种“未登录”表现。
+
+---
+
+## 2. 鉴权拦截器 `JwtInterceptor` 与公开路径白名单
+
+**实现位置**:`src/main/java/com/etotem/cfc/config/JwtInterceptor.java:21`
+**注册位置**:`src/main/java/com/etotem/cfc/config/WebConfig.java:95-137`(拦截 `/api/**`,并在 `excludePathPatterns` 中再排除一批)
+
+### 2.1 白名单 `PUBLIC_PATHS`(`JwtInterceptor.java:32-77`,精确匹配 + `prefix/` 前缀匹配)
+
+以下路径**完全跳过 token 校验**(匿名即可访问):
+
+- 认证类:`/api/auth/send-code`、`/api/auth/phone-login`、`/api/auth/wechat-phone-login`、`/api/auth/silent-login`、`/api/auth/sso-login`、`/api/auth/auto-login`(已废弃)、`/api/auth/register-with-idcard`、`/api/auth/wechat-login`、`/api/auth/verify`、`/api/auth/check-phone`、`/api/auth/direct-register`、`/api/auth/register-with-invite`、`/api/auth/wechat-web/qr`、`/api/auth/wechat-web/poll`、`/api/auth/internal/`
+- 商品/商城:`/api/product/list`、`/api/product/detail`、`/api/special-price/info`、`/api/product/type-list`、`/api/product/related-products`、`/api/mini-game/list`
+- 文章:`/api/articles/list`、`/api/articles/detail`、`/api/articles/categories`、`/api/articles/featured`、`/api/articles/record-read`、`/api/articles/related-products`、`/api/articles/related`、`/api/articles/related-by-product`、`/api/content/related-items`
+- 成长/活动:`/api/growth/**`、`/api/activity/list`、`/api/activity/detail`、`/api/activity/order/notify`、`/api/content-sections/visible`
+- 心智:`/api/mind/alert/active`、`/api/mind/alert/checkin-alerts`、`/api/mind/traditional/mirror`、`/api/mind/traditional/compatibility`
+- 其他:`/api/admin-auth/send-code`、`/api/admin-auth/login`、`/api/admin-auth/login-by-password`、`/api/admin-auth/account-roles`、`/api/mcp/**`
+
+> 匹配规则见 `JwtInterceptor.java:93-99`:`path.equals(publicPath)` 或 `path.startsWith(boundaryPath + "/")`(`/**` 仅取前缀)。
+
+### 2.2 强制登录路径 `LOGIN_REQUIRED_PATHS`(`JwtInterceptor.java:80-83`)
+
+无 token 直接 **HTTP 401**:`/api/share/qrcode`、`/api/auth/verify-password`。
+
+### 2.3 token 解析与请求属性注入(`JwtInterceptor.java:102-191`)
+
+- 取 token:`Authorization` 头,去 `Bearer ` 前缀(`:130`);空则取 `?token=` 参数(`:106`)。
+- 解析成功后注入请求属性(下游 `@RequestAttribute` 取值):
+  - `userId`(`Long`,`:148`)
+  - `role`(`String`,`:149`)
+  - `roles`(`List<String>`,`:150`)
+  - `familyId`(`Long`,`:167`,user.family_id 为空时从 `family_members` 反查)
+  - `currentMemberId` / `familyMemberId`(`Long`,`:184-185`,当 familyId 非空时查家庭成员)
+- 无 token 且非强制登录:注入**匿名用户** `userId=-1, role="anonymous"`,放行(`:211-217`)。
+
+### 2.4 第二个拦截器:家庭越权 `FamilyAccessInterceptor`(`config/FamilyAccessInterceptor.java:33`)
+
+- 作用:校验请求里出现的 `familyId`(query/path/body 递归)是否属于当前用户自己或 `teacherFamilyIds`。
+- `admin/**` 跳过(`:51`)。
+- 默认 **logging 模式**(只打 warn,不拦截);**enforcement 模式**(`-Dfamily.access.mode=enforcement`)越权返回 **HTTP 403 + code 403**(`:135-140`)。
+- ⚠️ 测试环境若开了 enforcement,跨家庭访问会被 403;业务级用例需确保每个角色的 token 只访问自己家庭的数据。
+
+### 2.5 其它拦截器(顺序见 `WebConfig.java:94-179`)
+
+`operationLogInterceptor`、`rateLimitInterceptor` 也拦截 `/api/**`,并对白名单批量 exclude。限流可能让高频测试偶发失败,必要时在测试侧限速或识别限流返回。
+
+**对编写用例的建议**:
+- 把白名单接口标记为「免登录可测」,优先拿它们做“空体/最小参数”探活。
+- 非白名单接口必须先拿 token;**拿 token 的最小成本路径是 `/api/auth/direct-register`**(见 §3),无需验证码。
+- 注意公开接口(白名单)内部大多用 `@RequestAttribute(value="userId", required=false)`(如 `ActivityController.java:29`),匿名时 `userId` 为 null,不应断言“未登录 401”,而应断言业务正常返回(活动列表/详情本就是公开读)。
+
+---
+
+## 3. 登录相关接口(请求参数 + 返回 token 字段)
+
+**控制器**:`src/main/java/com/etotem/cfc/controller/auth/AuthController.java`
+
+> 所有登录/注册接口均返回 `Result<LoginResultDTO>`。token 字段名 = **`token`**(`LoginResultDTO`,见 `src/main/java/com/etotem/cfc/dto/LoginResultDTO.java`),响应体取值 `data.token`。前端/测试用 `Authorization: Bearer <data.token>` 携带。`LoginResultDTO` 还含 `userId, role, roles, familyId, nickname, phone, currentChildId, isNewUser, needsRoleSelect, needsFamily, teacherStatus, hasTeacherRole, vendorType, activityProviderStatus` 等,可用来驱动后续断言。
+
+| 接口 | 行号 | 请求体(必填项) | 说明 / 返回 |
+|------|------|------------------|------------|
+| `POST /api/auth/wechat-login` | `AuthController.java:175` | `{code}`(`WechatLoginDTO.code`) | 微信 code 登录;测试环境若无真实微信 code 不易用 |
+| `POST /api/auth/phone-login` | `:67` | `{phone, code}` | 需先 `send-code` 拿验证码并落库,流程重 |
+| `POST /api/auth/direct-register` | `:278` | `{phone, nickname?, avatar?, role?, birthday?, gender?, inviteCode?}`(`DirectRegisterDTO`) | **测试首选**:跳过验证码直接注册/登录;`phone` 必填且需 `^1[3-9]\d{9}$`;已注册则返回“该手机号已注册” | 
+| `POST /api/auth/register-with-idcard` | `:146` | `{phone, code, idCard, realName}` | 需验证码,身份证格式校验 |
+| `POST /api/auth/sso-login` | `:376` | `{ticket}`(公开) | 跨小程序 SSO:先 `/api/auth/sso-ticket` 签发,再消费换登录态 |
+| `POST /api/auth/sso-ticket` | `:349` | `{target:"train"}`(需登录) | 返回 `{ticket,target}` |
+| `POST /api/auth/auto-login` | `:136` | — | **已废弃 → `Result.error(410,...)`**,不要再用 |
+| `POST /api/auth/verify` | `:222` | 仅 `Authorization` 头 | 校验 token,返回 `{userId,role}`;token 非法/用户不存在 → `code=401` |
+| `POST /api/auth/wechat-phone-login` | `:90` | `{code, phoneCode}` | 需微信能力 |
+| `POST /api/auth/silent-login` | `:107` | `{code}` | 已废弃的 openid 自动登录替代方案(仍需微信 code) |
+
+**关于 mock-login**:**全代码库无 `mock-login` 接口**(已 grep 确认)。多角色 token 的推荐获取方式:
+1. `direct-register` 时直接带 `role`(值 `parent`/`teacher`)拿对应角色 token;
+2. 登录后用 `switch-role` 切换(见 §4)。
+
+**对编写用例的建议**:
+- 业务级用例的“登录前置”统一封装为:`POST /api/auth/direct-register` → 提取 `data.token` → 后续请求带 `Authorization: Bearer <token>`。注意 `direct-register` 会校验手机号格式,使用测试专用号段即可,但**同一手机号二次调用会报“已注册”**,用例需做号段/清理或复用已注册 token。
+- `needsFamily=true`(familyId 为空/0)时,要先建/加入家庭再调家庭/健康/任务类接口,否则易触发 `code=5001` 或 downstream 的 `familyId不能为空`。
+- 校验未登录判定:带**非法/过期 token** 才稳定得到 HTTP 401;不带 token 访问非白名单接口是匿名放行 + 业务 `code=500`,不要混为一谈。
+
+---
+
+## 4. 角色模型与切换角色接口现状
+
+### 4.1 角色如何区分
+
+**实体**:`src/main/java/com/etotem/cfc/entity/User.java`
+- `role`(`User.java:30`):当前活跃角色,取值 `parent` / `child` / `teacher` / `admin`。
+- `roles`(`User.java:34`):拥有的全部角色列表,JSON。
+- `familyRole`(`User.java:99`):家长身份(爸爸/妈妈/爷爷…),区别于 `role`。
+- `vendorType`(`User.java`):服务商类型 `planner` / `activity_provider` / `product_supplier`(配合 `vendorStatus`)。
+
+**角色语义(基于 `UserService` 与控制器)**:
+- **parent(家长)**:常规登录用户,可建/加入家庭,给孩子派任务、看健康报告。
+- **child(孩子)**:**通常不作为独立登录账号**——孩子以 `family_members` 表的成员记录存在,由家长以 `currentMemberId` 切换“成员视图”来代操作。`User.role="child"` 在代码里也存在(`UserService.java` 有 `setRole("child")` 分支),但小程序端孩子一般通过家长切换成员视图访问,而非自己登录拿 token。
+- **teacher(成长规划师)**:可登录,受 `teacherStatus`(pending/approved/rejected)审核;`teacherFamilyIds` 决定可访问哪些家庭。部分接口要求 `teacher` 角色(如 `FamilyController.guideBindFamily` `:68` 校验 `"teacher".equals(guide.getRole())`)。
+- **admin**:**禁止登录小程序**(`UserService.ssoLogin` `:701` 抛“该账号不允许登录小程序”;`switchRoleForLogin` `:635` 抛“管理员角色不允许切换”)。admin 走独立的 `/api/admin-auth/*` 体系。
+
+### 4.2 切换角色接口现状(重点:此前冒烟 `/api/user/switch-*` 返回 404 的原因)
+
+经核对,**不存在 `/api/user/switch-*` 路由**,真实路由如下(`grep` 证据):
+
+| 真实路由 | 行号 | 说明 |
+|----------|------|------|
+| `POST /api/auth/switch-role` | `AuthController.java:330` | 切换**活跃登录角色** `parent/teacher`,重新签发 token(返回 `LoginResultDTO`)。需登录。底层 `UserService.switchRoleForLogin` `:637`:非 teacher 不能切到 teacher |
+| `POST /api/family/user/switch-role` | `FamilyUserController.java:101-105` | 切 `parent/child/teacher`,body `{role}`,返回 `Result<String>` |
+| `POST /api/family/member/switch` | `FamilyMembersController.java:84` | **切换成员视图**(家长切到某个孩子 `memberId`),body `{memberId}`,返回 `SwitchMemberVO`。这是替代一堆废弃接口的新路由 |
+| `POST /api/family/user/switch-mode` | `FamilyUserController.java:94` | **已废弃 → `code=410`** |
+| `POST /api/family/user/switch-to-child` | `FamilyUserController.java:121` | **已废弃 → `code=410`** |
+| `POST /api/family/user/switch-back-to-parent` | `FamilyUserController.java:129` | **已废弃 → `code=410`** |
+
+**结论**:此前冒烟 `/api/user/switch-*` 的 404,是因为路径写错(少了 `/family/` 前缀,或混淆了废弃路由)。正确做法是:切换登录角色用 `/api/auth/switch-role`,切换成员视图用 `/api/family/member/switch`。不要再用任何 `switch-mode/switch-to-child/switch-back-to-parent`(都返回 410)。
+
+**对编写用例的建议**:
+- 多角色 token 准备:用 `direct-register` 带 `role=parent` 注册家长;另注册一个 `role=teacher` 且 `teacherStatus=approved` 的账号作规划师(注意 `switchRoleForLogin` 要求该用户 `roles` 里真含 teacher,否则切不过去)。
+- 验证 teacher 越权场景:用家长 token 调 `POST /api/family/guide-bind`(要求 teacher 角色)应得“只有成长规划师才能使用此功能”。
+- 孩子视角用例:家长登录 → `POST /api/family/member/switch {memberId}` 拿到成员视图 → 用返回的 `currentMemberId` 调健康/任务接口。
+
+---
+
+## 5. 代表性业务接口契约(优先此前冒烟大量 500 的 health / family / activity)
+
+> 通用约定:全部 `@PostMapping`;请求体多为 `Map<String,Object>` 或实体;缺参通常 `Result.error("xxx不能为空")` → `code=500`。以下“常见错误码”含业务自定义码。
+
+### 5.1 活动 Activity —— `controller/ActivityController.java`(`@RequestMapping("/api/activity")`)
+此前冒烟 500 多因未登录 / 缺 `id` / 缺 `memberId`。注意 `/api/activity/*` 中仅 `list`、`detail`、`order/notify` 在白名单,其余需登录。
+
+| 接口 | 行号 | 必填参数 | 正常返回 / 常见错误 |
+|------|------|----------|--------------------|
+| `POST /api/activity/list` | `:28` | 无(公开)`dimensionCode? page? size?` | `Map`(列表+分页);匿名可访问 |
+| `POST /api/activity/detail` | `:36` | `id`(必填) | `ActivityDTO`;缺 `id`→`"id不能为空"` |
+| `POST /api/activity/register` | `:123` | `id`(活动ID);单报需 `memberId`(缺→`"孩子ID不能为空"`) | `Map`;批量用 `registrants[]` |
+| `POST /api/activity/create` | `:44` | 活动实体;普通用户需登录(未登录且非管理员→`"普通用户需登录后创建活动"`) | `ActivityDTO` |
+| `POST /api/activity/publish` | `:71` | `id`;需 `activity_manager/admin` 角色 | 字符串;无权限→`"只有管理员或活动管理员可以发布活动"` |
+| `POST /api/activity/checkin` | `:167` | `id`, `memberId` | `Map`;含 `error` 键时 `Result.error(...)` |
+| `POST /api/activity/submit-review` | `:106` | `id`;须创建人或管理员 | `"已提交审核"` |
+
+活动管理角色判定:`hasActivityManageRole` `:23-26`:`role=="admin"||"activity_admin"` 或 `roles` 含 `activity_manager`。
+
+### 5.2 家庭 Family —— `controller/family/FamilyController.java`(`/api/family`)+ 成员
+此前 500 多因 `familyId` 缺失/无家庭。
+
+| 接口 | 行号 | 必填参数 | 正常返回 / 常见错误 |
+|------|------|----------|--------------------|
+| `POST /api/family/guide-bind` | `:59` | `inviteCode`;需 `teacher` 角色 | `"申请已提交,请等待家长审批"`;非 teacher→`"只有成长规划师才能使用此功能"`;无效码→`"邀请码无效"` |
+| `POST /api/family/member/switch` | `:84` | `memberId` | `SwitchMemberVO`;缺 `memberId`→`"缺少成员ID"` |
+| `POST /api/family/user/switch-role` | `FamilyUserController.java:101` | `{role}` | `String`;无该角色→`Result.error("切换失败...")` |
+| `POST /api/family/invite-code` / `generate` | `:40 / :50` | — | **已废弃 → `code=410`**,应改用 `/api/family/invite/generate`(邀请令牌) |
+
+### 5.3 健康现状 HealthStatus —— `controller/HealthStatusController.java`(`/api/health-status`)
+需登录(`userId` 必填,非白名单)。
+
+| 接口 | 行号 | 必填参数 | 正常返回 / 常见错误 |
+|------|------|----------|--------------------|
+| `POST /api/health-status/get` | `:28` | 无(`userId` 由拦截器注入);`memberId?` | `HealthStatus`(账号级或成员级) |
+| `POST /api/health-status/save` | `:48` | 至少填一项(全空→`"请至少填写一项"`);`heightCm/weightKg/bloodPressure/bloodGlucose` 有范围校验 | `HealthStatus`;身高 30-250、体重 3-300、血压 `\d{2,3}/\d{2,3}`、血糖 1-30,越界→对应中文错误 |
+| `POST /api/health-status/signature` | `:79` | `signature`(base64 PNG data URL) | `Void`;空→`"请完成手签名"` |
+
+### 5.4 健康报告 HealthReport —— `controller/HealthReportController.java`(`/api/health-report`)
+**此前 500 的高发区**。根因:报告创建依赖“已购买健康启航计划体验包”且需 `memberId`/`reportType`。
+
+| 接口 | 行号 | 必填参数 | 正常返回 / 常见错误 |
+|------|------|----------|--------------------|
+| `POST /api/health-report/report/create` | `:206` | `userId`(注入)、`memberId`、`reportType`(`physical_exam`/`gut_flora`)、且**需先购计划** | `HealthReport`;未购→`code=4001 "请先购买健康启航计划体验包"`;缺 `memberId`→`"memberId不能为空"`;缺 `reportType`→`"reportType不能为空: ..."` |
+| `POST /api/health-report/report/latest` | `:295` | `memberId` | `HealthReport`;缺→`"memberId不能为空"` |
+| `POST /api/health-report/report/list` | `:316` | `userId` | `List<HealthReport>` |
+| `POST /api/health-report/indicators/current` | `:541` | `memberId` | `List`;缺→`"memberId不能为空"` |
+| `POST /api/health-report/indicators/rebuild` | `:516` | `memberId`;**需 `role==admin`** | 否则→`"权限不足"` |
+
+> 推论:此前 health 模块 500,很可能是测试未建家庭/未购计划/未传 `memberId`。业务级用例需先完成“建家庭→(必要时购计划)→拿 `memberId`”的前置链。
+
+### 5.5 任务 Task —— `controller/task/TaskController.java`(`/api/task`)
+需登录;`/today` 等需要 `familyId`。
+
+| 接口 | 行号 | 必填参数 | 正常返回 / 常见错误 |
+|------|------|----------|--------------------|
+| `POST /api/task/today` | `:81` | `familyId`(缺→`"familyId不能为空"`) | `List<Task>` |
+| `POST /api/task/create` | `:73` | `userId`(注入) | `Long`(任务ID) |
+| `POST /api/task/{id}/complete` | `:109` | 路径 `id`;`currentMemberId` | `Map`;无权/不存在→`"任务不存在、无权完成或状态已变更"` |
+| `POST /api/task/pending-review` | `:189` | `userId` | `List<Task>` |
+| `POST /api/task/batch-complete` | `:255` | `taskIds`(缺→`"taskIds不能为空"`) | `Boolean` |
+
+### 5.6 商城/商品 Product(白名单只读)
+- `POST /api/product/list`(`WebConfig` 白名单、`JwtInterceptor` 白名单):公开,无必填。
+- `POST /api/product/detail`:公开,需 `id`。
+- `POST /api/special-price/info`:公开。
+
+---
+
+## 6. 业务级用例编写总建议(落地清单)
+
+1. **测试目标改 localhost**:`http://localhost:9082`(端口 `application.yml:2`),不要打外网域名,否则全 `NON_JSON`。
+2. **统一登录封装**:用 `POST /api/auth/direct-register`(带 `phone`+`role`)拿 `data.token`;每个角色(parent/teacher)+ 每个成员视图各准备一个 token 池,避免“已注册”冲突(可维护一批测试手机号)。
+3. **前置链路**:parent 注册 →(建/加家庭拿到 `familyId`)→(如测健康报告需购计划)→ 通过 `/api/family/member/switch` 拿 `memberId`。把这条链路做成用例 fixture。
+4. **断言策略**:成功 = `code==200`;失败 = `code!=200` 且记录真实 `message`/自定义码(如 4001/5001/410/403)。不要假设失败码只有 500。
+5. **未登录断言双形态**:非法 token → 真 HTTP 401(`/api/auth/verify` 等);不带头访问非白名单 → 匿名放行 + 业务 `code=500`,HTTP 仍 200。
+6. **角色/权限用例**:
+   - 家长调 `teacher`-only 接口(如 `/api/family/guide-bind`)→ 期望“只有成长规划师才能使用此功能”。
+   - 非 admin 调 `indicators/rebuild` → 期望“权限不足”。
+   - 跨家庭访问(若开 enforcement)→ 期望 403。
+7. **废弃接口不要测通过**:`auto-login`、`switch-mode`、`switch-to-child`、`switch-back-to-parent`、`/api/family/invite-code` 等均返回 410,用例应预期 410 而非 200/404。
+8. **修正错误路径**:把旧基线里的 `/api/user/switch-*` 改成 `/api/family/user/switch-role` 或 `/api/auth/switch-role`;`/api/activities/hot` 等需核对真实路由(活动列表是 `/api/activity/list`)。
+9. **限流**:`rateLimitInterceptor` 可能让高频批量测试偶发失败,建议在测试客户端加节流或识别限流返回后退避重试。
+10. **参数校验覆盖**:对 `health-status/save` 等做边界用例(身高 <30、体重 >300、血压格式错误、血糖越界)验证中文错误码;对 `activity/detail`、`report/latest` 等做缺 `id`/`memberId` 的负向用例。
+
+---
+
+## 附:核心证据文件索引
+
+| 主题 | 文件:行号 |
+|------|-----------|
+| 响应结构 / code 约定 | `common/Result.java:8,16,39,45,52` |
+| 401 未登录写出 | `config/JwtInterceptor.java:205-209` |
+| 403 越权写出 | `config/FamilyAccessInterceptor.java:135-140`;`common/AdminOrgAccess.java` |
+| 拦截注册 / 白名单 exclude | `config/WebConfig.java:94-179` |
+| 公开白名单 PUBLIC_PATHS | `config/JwtInterceptor.java:32-77` |
+| token 取用与属性注入 | `config/JwtInterceptor.java:102-191` |
+| JWT 签发(claims=userId/role/roles) | `config/JwtConfig.java:46-68` |
+| 登录/注册/切换接口 | `controller/auth/AuthController.java:67,136,175,222,278,330,349,376` |
+| 登录返回 DTO(token 字段) | `dto/LoginResultDTO.java` |
+| 角色字段 | `entity/User.java:30,34,99` |
+| 切换角色(真实路由) | `AuthController.java:330`;`FamilyUserController.java:101`;`FamilyMembersController.java:84`;废弃 `FamilyUserController.java:94,121,129` |
+| 活动接口 | `controller/ActivityController.java:28,36,44,71,123,167` |
+| 家庭/成员切换 | `controller/family/FamilyController.java:59`;`FamilyMembersController.java:84` |
+| 健康现状 | `controller/HealthStatusController.java:28,48,79` |
+| 健康报告(4001) | `controller/HealthReportController.java:206,216,295,541` |
+| 任务 | `controller/task/TaskController.java:73,81,109,189,255` |
+| 端口 | `src/main/resources/application.yml:2` |

+ 115 - 0
INTERFACE_TEST_BUSINESS_REPORT.md

@@ -0,0 +1,115 @@
+# 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 |

+ 29 - 0
INTERFACE_TEST_REPORT.md

@@ -0,0 +1,29 @@
+# CFC 接口冒烟测试报告 (20261029_155512)
+
+- 目标: cfc.iwintrue.com  用例总数: **543**
+- 业务成功率(BIZ_OK): **245/543 = 45%**
+
+## 分类汇总
+- BIZ_OK: 245
+- BIZ_FAIL: 287
+- NOT_FOUND: 9
+- CONN_ERR: 2
+
+## ⚠️ 回归劣化(2 个,之前通过现失败)
+- `POST /api/user/portrait/generate`  (现 CONN_ERR)
+- `POST /api/user/portrait/regenerate`  (现 CONN_ERR)
+
+## 需开发团队关注的契约缺口 (NOT_FOUND=9)
+- `POST /api/guide/families`  (biz=None, NOT_FOUND)
+- `POST /api/guide/packages/my`  (biz=None, NOT_FOUND)
+- `POST /api/rewards`  (biz=None, NOT_FOUND)
+- `POST /api/user/join-family`  (biz=None, NOT_FOUND)
+- `POST /api/wishes/1/price`  (biz=None, NOT_FOUND)
+- `POST /api/guide/bind/confirm`  (biz=None, NOT_FOUND)
+- `POST /api/packages`  (biz=None, NOT_FOUND)
+- `POST /api/health/report/bodyfat-save`  (biz=None, NOT_FOUND)
+- `POST /api/health-plan/available-teachers`  (biz=None, NOT_FOUND)
+
+## 健壮性风险 (SERVER_ERR=0)
+
+> 说明:冒烟为空体请求,部分 500/400 属预期(缺必填参数)。NOT_FOUND 与回归劣化才需优先处理。

+ 2588 - 0
cfc-frontend/INTERFACE_TEST_MATRIX.md

@@ -0,0 +1,2588 @@
+# CFC 小程序「页面功能 → 操作接口」测试矩阵
+
+> 由 `cfc-frontend/utils/api.js` 全量解析 + 全量页面 `.vue/.js` 调用扫描自动生成。
+> 每个小程序页面(路由)映射到其实际调用的后端操作接口,可直接派生接口测试用例。
+
+- **页面路由数**:267
+- **接口用例总数**:1016
+- **公开接口(无需登录)**:178
+- **需登录态接口**:838
+- **含路径参数(需真实 ID)**:56
+
+> 注意:含路径参数的接口在无真实数据时大概率返回 400/404/401,脚本仅做「可达性 + 返回结构」断言,业务正确性需结合真实数据补充。
+
+## 按模块概览
+
+| 模块 | 接口数 | 公开 | 需登录 | 含参数 |
+|------|-------:|-----:|-------:|-------:|
+| ability | 1 | 0 | 1 | 0 |
+| activity | 27 | 27 | 0 | 0 |
+| admin | 14 | 3 | 11 | 1 |
+| ai | 10 | 1 | 9 | 0 |
+| articles | 22 | 22 | 0 | 0 |
+| assessment | 7 | 0 | 7 | 0 |
+| auth | 26 | 26 | 0 | 0 |
+| badges | 11 | 0 | 11 | 0 |
+| basic-quota | 2 | 0 | 2 | 0 |
+| butler | 8 | 8 | 0 | 0 |
+| cart | 3 | 0 | 3 | 0 |
+| cf | 3 | 0 | 3 | 0 |
+| circle | 15 | 1 | 14 | 0 |
+| cognitive | 15 | 0 | 15 | 0 |
+| commission | 19 | 0 | 19 | 0 |
+| common | 1 | 0 | 1 | 0 |
+| consent | 1 | 0 | 1 | 0 |
+| consignee | 4 | 0 | 4 | 0 |
+| contact | 13 | 0 | 13 | 0 |
+| content | 1 | 0 | 1 | 0 |
+| content-sections | 4 | 0 | 4 | 0 |
+| coupon | 10 | 0 | 10 | 0 |
+| daily-task | 2 | 0 | 2 | 0 |
+| dan-assessment | 17 | 5 | 12 | 1 |
+| dan-report | 2 | 0 | 2 | 1 |
+| diet | 20 | 1 | 19 | 0 |
+| dimension | 12 | 0 | 12 | 0 |
+| doa | 7 | 0 | 7 | 0 |
+| earnings | 4 | 0 | 4 | 0 |
+| emireport | 3 | 0 | 3 | 0 |
+| energy | 41 | 0 | 41 | 0 |
+| family | 98 | 12 | 86 | 1 |
+| family-platform | 4 | 0 | 4 | 0 |
+| feedback | 2 | 2 | 0 | 0 |
+| food | 8 | 0 | 8 | 0 |
+| game | 7 | 0 | 7 | 0 |
+| growth | 12 | 0 | 12 | 2 |
+| growth-task | 2 | 0 | 2 | 0 |
+| guide | 50 | 6 | 44 | 6 |
+| guide-config | 3 | 0 | 3 | 0 |
+| health | 97 | 2 | 95 | 2 |
+| health-plan | 1 | 0 | 1 | 0 |
+| health-status | 7 | 0 | 7 | 0 |
+| home | 21 | 0 | 21 | 0 |
+| home-banner | 1 | 0 | 1 | 0 |
+| indicator | 8 | 0 | 8 | 0 |
+| insurance | 1 | 0 | 1 | 0 |
+| internal | 1 | 0 | 1 | 0 |
+| invite | 23 | 0 | 23 | 0 |
+| invite-card | 2 | 2 | 0 | 0 |
+| leaderboard | 2 | 0 | 2 | 0 |
+| meal | 5 | 0 | 5 | 0 |
+| membership | 35 | 0 | 35 | 0 |
+| micro-action | 4 | 0 | 4 | 0 |
+| mind | 8 | 0 | 8 | 0 |
+| mini-game | 7 | 0 | 7 | 1 |
+| notification | 6 | 0 | 6 | 0 |
+| nutrition | 3 | 0 | 3 | 0 |
+| nutritionist | 1 | 1 | 0 | 0 |
+| octopus | 11 | 0 | 11 | 0 |
+| onboarding | 3 | 0 | 3 | 0 |
+| orchestration | 16 | 0 | 16 | 0 |
+| package | 2 | 0 | 2 | 0 |
+| packages | 6 | 1 | 5 | 5 |
+| parent | 4 | 0 | 4 | 1 |
+| pearl | 9 | 0 | 9 | 0 |
+| points | 8 | 0 | 8 | 0 |
+| poster-template | 2 | 0 | 2 | 0 |
+| product | 32 | 32 | 0 | 0 |
+| profile | 2 | 0 | 2 | 0 |
+| purchase | 2 | 0 | 2 | 0 |
+| recommend | 3 | 0 | 3 | 1 |
+| report-summary | 2 | 0 | 2 | 1 |
+| rewards | 7 | 0 | 7 | 2 |
+| service-role | 2 | 0 | 2 | 0 |
+| share | 5 | 0 | 5 | 0 |
+| shop | 2 | 2 | 0 | 0 |
+| special-price | 2 | 0 | 2 | 0 |
+| stats | 7 | 0 | 7 | 0 |
+| streets | 4 | 4 | 0 | 4 |
+| survey | 8 | 0 | 8 | 0 |
+| task | 2 | 0 | 2 | 0 |
+| tasks | 41 | 0 | 41 | 13 |
+| tianpan | 5 | 5 | 0 | 1 |
+| unlock | 3 | 0 | 3 | 0 |
+| user | 30 | 0 | 30 | 0 |
+| vendor | 9 | 7 | 2 | 0 |
+| wealth | 16 | 8 | 8 | 0 |
+| wisdom | 1 | 0 | 1 | 0 |
+| wishes | 23 | 0 | 23 | 13 |
+| withdrawal | 3 | 0 | 3 | 0 |
+
+## 按页面路由明细
+
+### App  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/auto-login` | 公开 |  | `autoLogin` |
+| POST | `/api/auth/sso-login` | 公开 |  | `ssoLogin` |
+| POST | `/api/auth/verify` | 公开 |  | `verifyToken` |
+| POST | `/api/family/invite/check-family` | 公开 |  | `checkUserFamily` |
+
+### __tests__/api/api.indicator.test  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/indicator/change-ranking` | 登录 |  | `getIndicatorChangeRanking` |
+| POST | `/api/indicator/correlation/list` | 登录 |  | `getIndicatorCorrelationList` |
+| POST | `/api/indicator/quick-lookup` | 登录 |  | `getIndicatorQuickLookup` |
+| POST | `/api/indicator/trend` | 登录 |  | `getIndicatorTrend` |
+
+### __tests__/api/api.test  (113 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/ai/chat/conversations` | 登录 |  | `aiGetConversations` |
+| POST | `/api/ai/chat/send` | 登录 |  | `aiSendMessage` |
+| POST | `/api/articles/categories` | 公开 |  | `getArticleCategories` |
+| POST | `/api/articles/daily-tip` | 公开 |  | `getDailyTip` |
+| POST | `/api/articles/detail` | 公开 |  | `getArticleDetail` |
+| POST | `/api/articles/list` | 公开 |  | `getArticleList` |
+| POST | `/api/articles/related` | 公开 |  | `getRelatedArticles` |
+| POST | `/api/auth/auto-login` | 公开 |  | `autoLogin` |
+| POST | `/api/auth/check-phone` | 公开 |  | `checkPhone` |
+| POST | `/api/auth/direct-register` | 公开 |  | `directRegister` |
+| POST | `/api/auth/phone-login` | 公开 |  | `phoneLogin` |
+| POST | `/api/auth/send-code` | 公开 |  | `sendCode` |
+| POST | `/api/auth/set-password` | 公开 |  | `setPassword` |
+| POST | `/api/auth/silent-login` | 公开 |  | `silentLogin` |
+| POST | `/api/auth/verify` | 公开 |  | `verifyToken` |
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/auth/wechat-login` | 公开 |  | `wechatLogin` |
+| POST | `/api/auth/wechat-phone-login` | 公开 |  | `wechatPhoneLogin` |
+| POST | `/api/badges/child/list` | 登录 |  | `getChildBadges` |
+| POST | `/api/badges/favorite` | 登录 |  | `toggleBadgeFavorite` |
+| POST | `/api/badges/list` | 登录 |  | `getActiveBadges` |
+| POST | `/api/commission/summary` | 登录 |  | `getCommissionSummary` |
+| POST | `/api/contact/create` | 登录 |  | `createContact` |
+| POST | `/api/contact/delete` | 登录 |  | `deleteContact` |
+| POST | `/api/contact/import-phone` | 登录 |  | `importPhoneContact` |
+| POST | `/api/contact/list` | 登录 |  | `getContactList` |
+| POST | `/api/dan-assessment/child-results` | 登录 |  | `getChildAssessmentResults` |
+| POST | `/api/dan-assessment/my-results` | 登录 |  | `getMyAssessmentResults` |
+| POST | `/api/dan-assessment/order/pay` | 登录 |  | `payAssessmentOrder` |
+| POST | `/api/dan-assessment/result/record` | 公开 |  | `recordAssessmentResult` |
+| POST | `/api/energy/logs` | 登录 |  | `getEnergyLogs` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/user/children` | 登录 |  | `createChild` |
+| POST | `/api/family/user/children/update` | 登录 |  | `updateChild` |
+| POST | `/api/family/user/create-family` | 登录 |  | `createFamily` |
+| POST | `/api/family/user/kick` | 登录 |  | `kickFamilyMember` |
+| POST | `/api/family/user/members/update-visibility` | 登录 |  | `updateMemberVisibility` |
+| POST | `/api/game/history` | 登录 |  | `getGameHistory` |
+| POST | `/api/game/leaderboard` | 登录 |  | `getGameLeaderboard` |
+| POST | `/api/growth/record/create` | 登录 |  | `createGrowthRecord` |
+| POST | `/api/growth/record/create-with-order` | 登录 |  | `createGrowthRecord` |
+| POST | `/api/growth/record/list` | 登录 |  | `getGrowthRecordList` |
+| POST | `/api/guide/bind/invite` | 登录 |  | `generateBindInvite` |
+| POST | `/api/guide/families` | 登录 |  | `getBoundFamilies` |
+| POST | `/api/guide/messages/list` | 登录 |  | `getGuideMessages` |
+| POST | `/api/guide/orders/list` | 登录 |  | `getGuideOrders` |
+| POST | `/api/guide/packages/my` | 登录 |  | `getGuidePackages` |
+| POST | `/api/guide/register` | 公开 |  | `registerGuide` |
+| POST | `/api/guide/team/members` | 登录 |  | `getTeamMembers` |
+| POST | `/api/health/checkin/list` | 登录 |  | `healthCheckinList` |
+| POST | `/api/health/indicator/list` | 登录 |  | `getHealthIndicatorList` |
+| POST | `/api/health/report/create` | 登录 |  | `createHealthReport` |
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+| POST | `/api/health/report/latest` | 登录 |  | `getLatestHealthReport` |
+| POST | `/api/health/report/list` | 登录 |  | `getReportList` |
+| POST | `/api/health/survey/create` | 登录 |  | `createReportSurvey` |
+| POST | `/api/health/survey/submit` | 登录 |  | `submitReportSurvey` |
+| POST | `/api/invite-card/generate` | 公开 |  | `generateInviteCard` |
+| POST | `/api/invite-card/verify` | 公开 |  | `verifyInviteCard` |
+| POST | `/api/invite/bind` | 登录 |  | `bindReferral` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/membership/levels` | 登录 |  | `getMembershipLevels` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/membership/orders` | 登录 |  | `createOrder` |
+| POST | `/api/mini-game//:var` | 登录 | ✓ | `getMiniGameByCode` |
+| POST | `/api/mini-game/complete` | 登录 |  | `completeMiniGame` |
+| POST | `/api/mini-game/list` | 登录 |  | `getMiniGameList` |
+| POST | `/api/packages//:var/publish` | 登录 | ✓ | `publishPackage` |
+| POST | `/api/points/balance` | 登录 |  | `getPointsBalance` |
+| POST | `/api/points/logs` | 登录 |  | `getPointsLogs` |
+| POST | `/api/product/create` | 公开 |  | `productCreate` |
+| POST | `/api/product/detail` | 公开 |  | `productDetail` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+| POST | `/api/product/order/create` | 公开 |  | `productOrderCreate` |
+| POST | `/api/rewards` | 登录 |  | `createReward` |
+| POST | `/api/rewards//:var/exchange` | 登录 | ✓ | `exchangeReward` |
+| POST | `/api/rewards/wishlist` | 登录 |  | `getWishlist` |
+| POST | `/api/stats/child-completion` | 登录 |  | `getChildCompletionStats` |
+| POST | `/api/stats/child/overview` | 登录 |  | `getChildOverview` |
+| POST | `/api/streets//:var/match`)
+}
+
+// 按区域统计
+export const getStreetStats = (level = 4) => {
+  return request('/api/streets/stats', 'POST', { level })
+}
+
+// 获取家庭详情(含地址信息)
+export const getFamilyDetail = (id) => {
+  return request(`/api/admin/families//:var`)
+}
+
+// 更新家庭地址
+export const updateFamilyAddress = (data) => {
+  return request(`/api/admin/families/update` | 公开 | ✓ | `matchByStreet` |
+| POST | `/api/streets/provinces')
+}
+
+// 根据父级ID获取子级地址
+export const getStreetChildren = (parentId) => {
+  return request(`/api/streets/children//:var`)
+}
+
+// 根据ID获取地址详情
+export const getStreetById = (id) => {
+  return request(`/api/streets//:var`)
+}
+
+// 获取地址完整路径
+export const getStreetPath = (id) => {
+  return request(`/api/streets//:var/path`)
+}
+
+// 搜索地址
+export const searchStreet = (keyword) => {
+  return request('/api/streets/search` | 公开 | ✓ | `getProvinces` |
+| POST | `/api/survey/status` | 登录 |  | `getSurveyStatus` |
+| POST | `/api/tasks//:var` | 登录 | ✓ | `deleteTask` |
+| POST | `/api/tasks//:var/complete` | 登录 | ✓ | `completeTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `approveTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `rejectTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `reviewTask` |
+| POST | `/api/tasks/batch-complete` | 登录 |  | `batchCompleteTasks` |
+| POST | `/api/tasks/create` | 登录 |  | `createTask` |
+| POST | `/api/tasks/history` | 登录 |  | `getTaskHistory` |
+| POST | `/api/tasks/pending-review` | 登录 |  | `getPendingReviewTasks` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasksByCategory` |
+| POST | `/api/tasks/today-parent` | 登录 |  | `getTodayParentTasks` |
+| POST | `/api/user/info` | 登录 |  | `getUserInfo` |
+| POST | `/api/user/join-family` | 登录 |  | `joinFamily` |
+| POST | `/api/user/switch-back-to-parent` | 登录 |  | `switchBackToParent` |
+| POST | `/api/user/switch-mode` | 登录 |  | `switchMode` |
+| POST | `/api/user/switch-to-child` | 登录 |  | `switchToChild` |
+| POST | `/api/user/update` | 登录 |  | `updateUserInfo` |
+| POST | `/api/vendor/apply` | 登录 |  | `vendorApply` |
+| POST | `/api/vendor/info` | 公开 |  | `vendorInfo` |
+| POST | `/api/vendor/status` | 公开 |  | `vendorStatus` |
+| POST | `/api/wealth/checkin/list` | 登录 |  | `getCheckinList` |
+| POST | `/api/wealth/insurance/list` | 公开 |  | `getInsuranceList` |
+| POST | `/api/wishes//:var/approve-exchange` | 登录 | ✓ | `approveWishExchange` |
+| POST | `/api/wishes//:var/price` | 登录 | ✓ | `setWishPrice` |
+| POST | `/api/wishes/create` | 登录 |  | `createWish` |
+| POST | `/api/wishes/list` | 登录 |  | `getWishes` |
+| POST | `/api/wishes/pending` | 登录 |  | `getPendingWishes` |
+| POST | `/api/withdrawal/apply` | 登录 |  | `applyWithdrawal` |
+
+### __tests__/store/store.test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/user/switch-role` | 登录 |  | `switchRole` |
+
+### components/DimensionActivities  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### components/DimensionProducts  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/recommend/dimension-products` | 登录 |  | `getDimensionProducts` |
+| POST | `/api/recommend/repurchase-reminder/'/:var + '/click` | 登录 | ✓ | `clickRepurchaseReminder` |
+
+### components/DimensionTasks  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+
+### components/MemberSelector  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/relationship/pairwise` | 登录 |  | `getPairwiseRelationships` |
+| POST | `/api/family/user/create-family` | 登录 |  | `createFamily` |
+
+### components/OnboardingGuide  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide-config/current` | 登录 |  | `getGuideConfig` |
+
+### components/OnboardingProgressBar  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/onboarding/progress` | 登录 |  | `getOnboardingProgress` |
+
+### components/RelatedContent  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/content/related-items` | 登录 |  | `getContentRelated` |
+
+### components/address-picker  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/streets/provinces')
+}
+
+// 根据父级ID获取子级地址
+export const getStreetChildren = (parentId) => {
+  return request(`/api/streets/children//:var`)
+}
+
+// 根据ID获取地址详情
+export const getStreetById = (id) => {
+  return request(`/api/streets//:var`)
+}
+
+// 获取地址完整路径
+export const getStreetPath = (id) => {
+  return request(`/api/streets//:var/path`)
+}
+
+// 搜索地址
+export const searchStreet = (keyword) => {
+  return request('/api/streets/search` | 公开 | ✓ | `getProvinces` |
+
+### components/daily-task-card  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/daily-task/overview` | 登录 |  | `getDailyTaskOverview` |
+
+### components/login-sheet  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/wechat-phone-login` | 公开 |  | `wechatPhoneLogin` |
+
+### components/share-mixin  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+
+### pages/achievement/index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/badges/child/list` | 登录 |  | `getChildBadges` |
+
+### pages/action-detail/components/PearlDiagram  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/pearl/interaction/add` | 登录 |  | `addPearlInteraction` |
+| POST | `/api/pearl/item/update-priority` | 登录 |  | `updatePearlPriority` |
+
+### pages/action-detail/contact-detail  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/contact/delete` | 登录 |  | `deleteContact` |
+| POST | `/api/contact/detail` | 登录 |  | `getContactDetail` |
+| POST | `/api/contact/interaction` | 登录 |  | `recordContactInteraction` |
+| POST | `/api/contact/update` | 登录 |  | `updateContact` |
+
+### pages/action-detail/index  (13 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/ability/map` | 登录 |  | `getAbilityMap` |
+| POST | `/api/content-sections/visible` | 登录 |  | `getVisibleSections` |
+| POST | `/api/dimension/radar-data` | 登录 |  | `getRadarData` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/octopus/analysis/summary` | 登录 |  | `getOctopusAnalysisSummary` |
+| POST | `/api/octopus/effect/key-persons` | 登录 |  | `getOctopusEffectKeyPersons` |
+| POST | `/api/octopus/effect/list` | 登录 |  | `getOctopusEffects` |
+| POST | `/api/pearl/item/delete` | 登录 |  | `deletePearlResource` |
+| POST | `/api/pearl/reminder/list` | 登录 |  | `getPearlReminders` |
+| POST | `/api/pearl/resources` | 登录 |  | `getPearlResources` |
+
+### pages/action-detail/interaction-log  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/interaction/add` | 登录 |  | `addInteraction` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+
+### pages/action-detail/member-action-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/action-detail/octopus-add-effect  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/octopus/effect/add` | 登录 |  | `addOctopusEffect` |
+| POST | `/api/octopus/key-person/bind-system-user` | 登录 |  | `bindOctopusKeyPersonSystemUser` |
+| POST | `/api/octopus/key-person/list` | 登录 |  | `getOctopusKeyPersons` |
+| POST | `/api/octopus/key-person/match-by-phone` | 登录 |  | `matchOctopusKeyPersonByPhone` |
+
+### pages/action-detail/octopus-add-key-person  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/octopus/key-person/add` | 登录 |  | `addOctopusKeyPerson` |
+| POST | `/api/octopus/key-person/list` | 登录 |  | `getOctopusKeyPersons` |
+
+### pages/action-detail/octopus-effects-list  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/octopus/effect/delete` | 登录 |  | `deleteOctopusEffect` |
+| POST | `/api/octopus/effect/list` | 登录 |  | `getOctopusEffects` |
+
+### pages/action-detail/pearl-add-resource  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/contact/list` | 登录 |  | `getContactList` |
+| POST | `/api/pearl/connection-types` | 登录 |  | `getConnectionTypes` |
+| POST | `/api/pearl/item/add` | 登录 |  | `addPearlResource` |
+
+### pages/action-detail/relationship-questionnaire  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/questionnaire/generate` | 登录 |  | `generateQuestionnaire` |
+| POST | `/api/family/questionnaire/snapshot/'/:var, 'POST', {}, { timeout: 30000 })
+}
+
+export const getQuestionnaireHistory = (memberId) => {
+  return request('/api/family/questionnaire/history/'/:var, 'POST', {}, { timeout: 30000 })
+}
+
+// ===== 五维家庭自检(P0-1)=====
+export const getSelfCheckQuestions = (params) => {
+  return request('/api/family/self-check/questions` | 登录 | ✓ | `getQuestionnaireSnapshot` |
+| POST | `/api/family/questionnaire/submit` | 登录 |  | `submitQuestionnaire` |
+
+### pages/activity/activity-detail/activity-detail  (12 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/cancel-registration` | 公开 |  | `cancelActivityRegistration` |
+| POST | `/api/activity/checkin` | 公开 |  | `activityCheckin` |
+| POST | `/api/activity/detail` | 公开 |  | `getActivityDetail` |
+| POST | `/api/activity/feedback/my` | 公开 |  | `getMyActivityFeedback` |
+| POST | `/api/activity/feedback/submit` | 公开 |  | `submitActivityFeedback` |
+| POST | `/api/activity/order/create` | 公开 |  | `createActivityOrder` |
+| POST | `/api/activity/registration-roster` | 公开 |  | `getActivityRegistrationRoster` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/poster-template/list` | 登录 |  | `getPosterTemplates` |
+| POST | `/api/share/qrcode` | 登录 |  | `getShareQrCode` |
+| POST | `/api/user/profile/backfill` | 登录 |  | `backfillProfile` |
+
+### pages/activity/create  (6 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/create` | 公开 |  | `adminCreateActivity` |
+| POST | `/api/activity/detail` | 公开 |  | `getActivityDetail` |
+| POST | `/api/activity/publish` | 公开 |  | `adminPublishActivity` |
+| POST | `/api/activity/submit-review` | 公开 |  | `submitActivityForReview` |
+| POST | `/api/activity/update` | 公开 |  | `adminUpdateActivity` |
+| POST | `/api/poster-template/list` | 登录 |  | `getPosterTemplates` |
+
+### pages/activity/index  (11 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/cancel-registration` | 公开 |  | `cancelActivityRegistration` |
+| POST | `/api/activity/checkin` | 公开 |  | `activityCheckin` |
+| POST | `/api/activity/end` | 公开 |  | `adminEndActivity` |
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/activity/my-registrations` | 公开 |  | `getMyActivityRegistrations` |
+| POST | `/api/activity/publish` | 公开 |  | `adminPublishActivity` |
+| POST | `/api/activity/submit-review` | 公开 |  | `submitActivityForReview` |
+| POST | `/api/admin/activity/list` | 公开 |  | `adminListMyActivities` |
+| POST | `/api/admin/activity/withdraw` | 公开 |  | `adminWithdrawActivity` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/vendor/status` | 公开 |  | `vendorStatus` |
+
+### pages/activity/order-pay/order-pay  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/order/handlePaymentSuccess` | 公开 |  | `handleActivityOrderSuccess` |
+| POST | `/api/activity/order/pay` | 公开 |  | `payActivityOrder` |
+
+### pages/ai/chat  (9 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/ai/butler/send` | 公开 |  | `aiSendHealthButlerMessage` |
+| POST | `/api/ai/chat/conversations` | 登录 |  | `aiGetConversations` |
+| POST | `/api/ai/chat/messages` | 登录 |  | `aiGetMessages` |
+| POST | `/api/ai/health-coach/send` | 登录 |  | `aiSendHealthCoachMessage` |
+| POST | `/api/ai/nutrition/send` | 登录 |  | `aiSendNutritionMessage` |
+| POST | `/api/ai/transcribe` | 登录 |  | `sttTranscribe` |
+| POST | `/api/basic-quota/status/all` | 登录 |  | `getAllQuotaStatus` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/article-center/article-detail  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/audio` | 公开 |  | `getArticleAudio` |
+| POST | `/api/articles/complete-read` | 公开 |  | `completeArticleRead` |
+| POST | `/api/articles/detail` | 公开 |  | `getArticleDetail` |
+| POST | `/api/articles/quiz/generate` | 公开 |  | `generateQuiz` |
+| POST | `/api/articles/quiz/submit` | 公开 |  | `submitQuiz` |
+| POST | `/api/articles/report-reading-time` | 公开 |  | `reportReadingTime` |
+| POST | `/api/share/qrcode` | 登录 |  | `getShareQrCode` |
+| POST | `/api/tasks//:var/complete` | 登录 | ✓ | `completeTask` |
+
+### pages/article-center/article-edit  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/publish` | 公开 |  | `publishArticle` |
+
+### pages/article-center/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/featured` | 公开 |  | `getFeaturedArticles` |
+| POST | `/api/articles/list` | 公开 |  | `getArticleList` |
+
+### pages/article-center/my-posts  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/my-posts` | 公开 |  | `getMyPosts` |
+
+### pages/assessment-plan/detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/result/plans/list` | 公开 |  | `getMyAssessmentPlans` |
+
+### pages/assessment-plan/list  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/result/plans/list` | 公开 |  | `getMyAssessmentPlans` |
+
+### pages/assessment/apply  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/assessment/appointment/create` | 登录 |  | `createAssessmentAppointmentWithQuota` |
+| POST | `/api/assessment/quota/my-list` | 登录 |  | `getAssessmentQuotas` |
+| POST | `/api/guide/invite-code/validate` | 公开 |  | `validateInviteCode` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/package/available-guides` | 登录 |  | `getAvailableGuides` |
+
+### pages/assessment/purchase  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/order/create` | 登录 |  | `createAssessmentOrder` |
+| POST | `/api/dan-assessment/order/detail` | 登录 |  | `getAssessmentOrderDetail` |
+| POST | `/api/guide/invite-code/validate` | 公开 |  | `validateInviteCode` |
+| POST | `/api/package/available-guides` | 登录 |  | `getAvailableGuides` |
+
+### pages/assessment/quota  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/assessment/quota/my-list` | 登录 |  | `getAssessmentQuotas` |
+
+### pages/assessment/results  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/child-results` | 登录 |  | `getChildAssessmentResults` |
+| POST | `/api/dan-assessment/my-results` | 登录 |  | `getMyAssessmentResults` |
+
+### pages/assessment/upload-report  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/result/upload` | 公开 |  | `uploadAssessmentReport` |
+
+### pages/body-detail/dimension-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dimension/history` | 登录 |  | `getDimensionHistory` |
+| POST | `/api/dimension/overview` | 登录 |  | `getDimensionOverview` |
+
+### pages/body-detail/dimension-questionnaire  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/submit-answers` | 公开 |  | `submitAnswers` |
+| POST | `/api/dimension/questionnaire` | 登录 |  | `submitDimensionQuestionnaire` |
+
+### pages/body-detail/health-dimensions  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dimension/overview` | 登录 |  | `getDimensionOverview` |
+| POST | `/api/dimension/upload` | 登录 |  | `uploadDimensionScore` |
+
+### pages/body-detail/health-report  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/nutrition/deficiency` | 登录 |  | `getDeficiencyAnalysis` |
+
+### pages/body-detail/index  (10 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/content-sections/visible` | 登录 |  | `getVisibleSections` |
+| POST | `/api/dimension/overview` | 登录 |  | `getDimensionOverview` |
+| POST | `/api/dimension/radar-data` | 登录 |  | `getRadarData` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/gut-flora` | 登录 |  | `getGutFloraIndicators` |
+| POST | `/api/health/indicators` | 登录 |  | `getLatestIndicators` |
+| POST | `/api/health/report/body-abnormal` | 登录 |  | `getBodyAbnormalIndicators` |
+
+### pages/body-detail/member-body-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/butler/apply  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/butler/apply` | 公开 |  | `butlerApply` |
+
+### pages/butler/select  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/butler/available-list` | 公开 |  | `getAvailableButlers` |
+| POST | `/api/butler/my-butler` | 公开 |  | `getMyButler` |
+| POST | `/api/butler/select` | 公开 |  | `selectButler` |
+
+### pages/child/rewards  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/points/balance` | 登录 |  | `getPointsBalance` |
+| POST | `/api/rewards/wishlist` | 登录 |  | `getWishlist` |
+| POST | `/api/user/switch-back-to-parent` | 登录 |  | `switchBackToParent` |
+
+### pages/child/tasks  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/user/switch-back-to-parent` | 登录 |  | `switchBackToParent` |
+
+### pages/cognitive-hall  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/child` | 登录 |  | `getCognitiveChildScores` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/cognitive-test/language-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/cognitive-test/logic-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/cognitive-test/memory-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/cognitive-test/perception-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/cognitive-test/spatial-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/cognitive-test/speed-test  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/dan-assessment/comparison  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-report/compare` | 登录 |  | `compareDanReports` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/dan-assessment/report-result  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-report/'/:var, 'POST', {})
+// DAN 报告列表(对比页:某成员的所有上传)
+export const getDanReportList = (params) => request('/api/dan-report/list` | 登录 | ✓ | `getDanReportDetail` |
+
+### pages/diet/index  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/ingredients/add` | 登录 |  | `addDietIngredient` |
+| POST | `/api/diet/ingredients/recommend` | 登录 |  | `refreshDietIngredients` |
+| POST | `/api/diet/ingredients/remove` | 登录 |  | `removeDietIngredient` |
+| POST | `/api/diet/ingredients/search` | 登录 |  | `searchDietFoods` |
+| POST | `/api/diet/ingredients/suggest` | 登录 |  | `getDietIngredients` |
+| POST | `/api/diet/meals/config` | 登录 |  | `getMealConfig` |
+| POST | `/api/diet/recommendation/generate` | 登录 |  | `generateDietRecommendation` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+
+### pages/diet/meal-config  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/meals/config` | 登录 |  | `getMealConfig` |
+| POST | `/api/diet/meals/config/save` | 公开 |  | `saveMealConfig` |
+
+### pages/diet/preferences  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/preferences/current-member` | 登录 |  | `getDietPreferences` |
+| POST | `/api/diet/preferences/save` | 登录 |  | `saveDietPreferences` |
+
+### pages/diet/recommendation  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/recommendation/complete` | 登录 |  | `completeDietRecommendation` |
+| POST | `/api/diet/recommendation/generate` | 登录 |  | `generateDietRecommendation` |
+| POST | `/api/diet/recommendation/regenerate` | 登录 |  | `regenerateDietRecommendation` |
+| POST | `/api/diet/recommendation/today` | 登录 |  | `getDietRecommendation` |
+
+### pages/diet/record-detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/record/daily` | 登录 |  | `getDietDailyRecords` |
+
+### pages/diet/records  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/food/recommendation/members` | 登录 |  | `getCautionFamilyMembers` |
+| POST | `/api/health/meal/alerts` | 登录 |  | `getMealAlerts` |
+| POST | `/api/health/meal/daily` | 登录 |  | `getMealDaily` |
+| POST | `/api/health/meal/weekly` | 登录 |  | `getMealWeekly` |
+
+### pages/discover-detail/product-detail/product-detail  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cart/add` | 登录 |  | `cartAdd` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/product/detail` | 公开 |  | `productDetail` |
+| POST | `/api/product/order/pay` | 公开 |  | `productOrderPay` |
+| POST | `/api/product/spec/map` | 公开 |  | `productSpecMap` |
+| POST | `/api/share/qrcode` | 登录 |  | `getShareQrCode` |
+| POST | `/api/special-price/info` | 登录 |  | `getSpecialPriceInfo` |
+
+### pages/discover/circle-feed  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/circle/comment/add` | 登录 |  | `addCircleComment` |
+| POST | `/api/circle/comment/list` | 登录 |  | `getCircleComments` |
+| POST | `/api/circle/feed` | 公开 |  | `getCircleFeed` |
+| POST | `/api/circle/members` | 登录 |  | `getCircleMembers` |
+| POST | `/api/circle/post/create` | 登录 |  | `createCirclePost` |
+| POST | `/api/circle/post/delete` | 登录 |  | `deleteCirclePost` |
+| POST | `/api/circle/post/like` | 登录 |  | `toggleCircleLike` |
+
+### pages/discover/circles  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/circle/approve` | 登录 |  | `approveCircleMember` |
+| POST | `/api/circle/discover` | 登录 |  | `discoverCircles` |
+| POST | `/api/circle/join` | 登录 |  | `joinGeneralCircle` |
+| POST | `/api/circle/leave` | 登录 |  | `leaveGeneralCircle` |
+| POST | `/api/circle/my-circles` | 登录 |  | `getMyCircles` |
+| POST | `/api/circle/pending-members` | 登录 |  | `getPendingCircleMembers` |
+| POST | `/api/circle/update` | 登录 |  | `updateCircle` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+
+### pages/discover/create-circle  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/circle/create` | 登录 |  | `createGeneralCircle` |
+
+### pages/discover/index  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/featured` | 公开 |  | `getFeaturedArticles` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+
+### pages/energy/detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/logs` | 登录 |  | `getEnergyLogs` |
+
+### pages/energy/index  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/family/add-member  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/check-phone` | 公开 |  | `checkPhone` |
+| POST | `/api/consent/record` | 登录 |  | `recordConsent` |
+| POST | `/api/family/member/add` | 登录 |  | `addFamilyMember` |
+| POST | `/api/family/member/update` | 登录 |  | `updateFamilyMember` |
+
+### pages/family/manual-score-entry  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/manual-score/submit` | 登录 |  | `submitManualScore` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/family/mbti-entry  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/family/mbti-profile  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/mbti/profile` | 登录 |  | `getMbtiProfile` |
+
+### pages/family/mbti-result  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/mbti/latest` | 登录 |  | `getMbtiLatest` |
+
+### pages/family/mbti-test  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/mbti/questions` | 登录 |  | `getMbtiQuestions` |
+| POST | `/api/family/mbti/submit` | 登录 |  | `submitMbti` |
+
+### pages/family/self-check  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/self-check/submit` | 登录 |  | `submitSelfCheck` |
+
+### pages/family/self-check-ai  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/self-check/submit` | 登录 |  | `submitSelfCheck` |
+
+### pages/family/self-check-entry  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/self-check/ignore` | 登录 |  | `ignoreSelfCheck` |
+| POST | `/api/family/self-check/status` | 登录 |  | `getSelfCheckStatus` |
+| POST | `/api/family/self-check/trend-analysis` | 登录 |  | `getSelfCheckTrendAnalysis` |
+
+### pages/family/self-check-result  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/self-check/generate-plan` | 登录 |  | `generateSelfCheckPlan` |
+| POST | `/api/family/self-check/history` | 登录 |  | `getSelfCheckHistory` |
+| POST | `/api/family/self-check/latest` | 登录 |  | `getSelfCheckLatest` |
+| POST | `/api/micro-action/complete` | 登录 |  | `microActionComplete` |
+| POST | `/api/micro-action/today` | 登录 |  | `microActionToday` |
+
+### pages/games/1a2b  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/mini-game/complete` | 登录 |  | `completeMiniGame` |
+
+### pages/games/list  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/mini-game/list` | 登录 |  | `getMiniGameList` |
+
+### pages/games/records  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/game/history` | 登录 |  | `getGameHistory` |
+
+### pages/games/schulte  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/mini-game/complete` | 登录 |  | `completeMiniGame` |
+
+### pages/games/stats  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/game/best` | 登录 |  | `getGameBestScores` |
+| POST | `/api/game/leaderboard` | 登录 |  | `getGameLeaderboard` |
+| POST | `/api/game/stats` | 登录 |  | `getGameStats` |
+
+### pages/games/sudoku  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/mini-game/complete` | 登录 |  | `completeMiniGame` |
+
+### pages/growth-main/index  (10 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/food/recommendation/caution` | 登录 |  | `getFoodCautionList` |
+| POST | `/api/growth/recommendations` | 登录 |  | `getGrowthRecommendations` |
+| POST | `/api/health/checkin/list` | 登录 |  | `healthCheckinList` |
+| POST | `/api/health/exercise/list` | 登录 |  | `getExerciseRecords` |
+| POST | `/api/health/meal/list` | 登录 |  | `getHealthMealList` |
+| POST | `/api/health/sleep/list` | 登录 |  | `getSleepRecords` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/mind/checkin/list` | 登录 |  | `getEmotionCheckinList` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/wealth/checkin/list` | 登录 |  | `getCheckinList` |
+
+### pages/growth/assessment-result  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/result/'/:var, 'POST')
+}
+
+// 创建测评预约
+export const createAssessmentAppointment = (data) => {
+  return request('/api/dan-assessment/appointment/create` | 公开 | ✓ | `getAssessmentResult` |
+
+### pages/growth/caution-detail  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/food/recommendation/caution` | 登录 |  | `getFoodCautionList` |
+| POST | `/api/food/recommendation/members` | 登录 |  | `getCautionFamilyMembers` |
+| POST | `/api/food/recommendation/trend` | 登录 |  | `getFoodCautionTrend` |
+| POST | `/api/health/knowledge/v3/section` | 登录 |  | `getKnowledgeSection` |
+
+### pages/growth/challenge-progress  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/purchase/challenge/progress` | 登录 |  | `getChallengeProgress` |
+
+### pages/growth/create  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/growth/record/create` | 登录 |  | `createGrowthRecord` |
+| POST | `/api/growth/record/create-with-order` | 登录 |  | `createGrowthRecord` |
+
+### pages/growth/detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/growth/record/'/:var + '/supplements` | 登录 | ✓ | `getGrowthSupplements` |
+
+### pages/growth/diet-checkin  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/ai/transcribe` | 登录 |  | `sttTranscribe` |
+| POST | `/api/basic-quota/status/all` | 登录 |  | `getAllQuotaStatus` |
+
+### pages/growth/exercise-checkin  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/ai/transcribe` | 登录 |  | `sttTranscribe` |
+
+### pages/growth/supplement  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/growth/record/supplement` | 登录 |  | `createGrowthSupplement` |
+| POST | `/api/growth/record/upload-and-parse` | 登录 |  | `uploadAndParseReport` |
+
+### pages/growth/upload  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/growth/record/child/'/:var, 'POST')
+}
+export const getGrowthRecordDetail = (id) => {
+  return request('/api/growth/record/'/:var, 'POST')
+}
+export const deleteGrowthRecord = (id) => {
+  return request('/api/growth/record/'/:var + '/delete` | 登录 | ✓ | `getChildRecords` |
+| POST | `/api/growth/record/create-from-upload` | 登录 |  | `createGrowthRecordFromUpload` |
+| POST | `/api/growth/record/upload-and-parse` | 登录 |  | `uploadAndParseReport` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+
+### pages/guide/activities/detail  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/activities/create` | 登录 |  | `createActivity` |
+| POST | `/api/guide/activities/detail` | 登录 |  | `getGuideActivityDetail` |
+| POST | `/api/guide/activities/publish` | 登录 |  | `publishActivity` |
+| POST | `/api/guide/activities/update` | 登录 |  | `updateActivity` |
+
+### pages/guide/activities/index  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/activities/cancel` | 登录 |  | `cancelActivity` |
+| POST | `/api/guide/activities/delete` | 登录 |  | `deleteActivity` |
+| POST | `/api/guide/activities/list` | 登录 |  | `getGuideActivityList` |
+| POST | `/api/guide/activities/publish` | 登录 |  | `publishActivity` |
+
+### pages/guide/bind/invite  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/common/qrcode` | 登录 |  | `generateQrCodeFromText` |
+| POST | `/api/guide/bind/confirm` | 登录 |  | `confirmBind` |
+| POST | `/api/guide/bind/invite` | 登录 |  | `generateBindInvite` |
+
+### pages/guide/hierarchy/index  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/all-child-guides` | 登录 |  | `getAllChildGuides` |
+| POST | `/api/guide/child-guides` | 登录 |  | `getChildGuides` |
+| POST | `/api/guide/parent-guide` | 登录 |  | `getParentGuide` |
+
+### pages/guide/packages/create  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/packages` | 登录 |  | `createPackage` |
+
+### pages/guide/packages/detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/packages//:var/items` | 登录 | ✓ | `addPackageItem` |
+| POST | `/api/packages/items/'/:var, 'POST', { _method: 'PUT' }, data)
+}
+
+// 删除任务项
+export const deletePackageItem = (itemId) => {
+  return request('/api/packages/items/'/:var, 'POST', { _method: 'DELETE' })
+}
+
+// 获取任务模板任务项
+export const getPackageItems = (packageId) => {
+  return request(`/api/packages//:var/items`, 'POST')
+}
+
+
+// 获取我的任务计划
+export const getMyPlans = () => {
+  return request('/api/market/plans` | 公开 | ✓ | `updatePackageItem` |
+
+### pages/guide/packages/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/packages//:var/publish` | 登录 | ✓ | `publishPackage` |
+| POST | `/api/packages//:var/submit` | 登录 | ✓ | `submitPackageForReview` |
+
+### pages/guide/register/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/invite-code/validate` | 公开 |  | `validateInviteCode` |
+| POST | `/api/guide/register` | 公开 |  | `registerGuide` |
+
+### pages/health-main/index  (10 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/featured` | 公开 |  | `getFeaturedArticles` |
+| POST | `/api/cognitive/child` | 登录 |  | `getCognitiveChildScores` |
+| POST | `/api/cognitive/family` | 登录 |  | `getCognitiveFamilyScores` |
+| POST | `/api/dimension/overview` | 登录 |  | `getDimensionOverview` |
+| POST | `/api/emireport/latest` | 登录 |  | `getEmiReport` |
+| POST | `/api/energy/wealth-detail` | 登录 |  | `getWealthDetail` |
+| POST | `/api/family/relationship/scores` | 登录 |  | `getRelationshipScores` |
+| POST | `/api/health/plan/list` | 登录 |  | `getHealthPlanList` |
+| POST | `/api/health/report/list` | 登录 |  | `getReportList` |
+| POST | `/api/survey/status` | 登录 |  | `getSurveyStatus` |
+
+### pages/health/bodyfat-confirm  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/report/bodyfat-save` | 登录 |  | `saveBodyFatMetrics` |
+
+### pages/health/challenge-manage  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/challenge/create` | 登录 |  | `createChallenge` |
+| POST | `/api/health/challenge/history` | 登录 |  | `getChallengeHistory` |
+| POST | `/api/health/challenge/list` | 登录 |  | `getChallengeList` |
+| POST | `/api/health/challenge/respond` | 登录 |  | `respondChallenge` |
+| POST | `/api/health/challenge/update/'/:var, 'POST', data)
+export const deleteChallenge = (id) => request('/api/health/challenge/delete/'/:var, 'POST', data)
+export const getChallengeTemplates = () => request('/api/health/challenge/templates` | 登录 | ✓ | `updateChallenge` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/health/components/MemberChipPicker  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/health/components/feedback-popup  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/feedback/submit` | 公开 |  | `submitFeedback` |
+
+### pages/health/doa-index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/doa/overview` | 登录 |  | `getDoaOverview` |
+
+### pages/health/doa-stage-create  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/doa/stage/create` | 登录 |  | `createDoaStage` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/health/doa-stage-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/doa/stage/cancel` | 登录 |  | `cancelDoaStage` |
+| POST | `/api/doa/stage/detail` | 登录 |  | `getDoaStageDetail` |
+
+### pages/health/doa-week-edit  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/doa/stage/detail` | 登录 |  | `getDoaStageDetail` |
+| POST | `/api/doa/week/plan` | 登录 |  | `submitDoaWeekPlan` |
+| POST | `/api/doa/week/review` | 登录 |  | `submitDoaWeekReview` |
+
+### pages/health/gut-flora-detail  (13 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/add` | 登录 |  | `addFamilyMember` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/food/recommendation/caution` | 登录 |  | `getFoodCautionList` |
+| POST | `/api/health/foods` | 登录 |  | `getHealthFoods` |
+| POST | `/api/health/knowledge/query` | 登录 |  | `queryKnowledgeBase` |
+| POST | `/api/health/knowledge/v3/indicator/query` | 登录 |  | `queryIndicatorKnowledge` |
+| POST | `/api/health/report/confirm` | 登录 |  | `confirmReportPreview` |
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+| POST | `/api/health/report/discard` | 登录 |  | `discardReportDraft` |
+| POST | `/api/health/report/edit` | 登录 |  | `editHealthReport` |
+| POST | `/api/health/report/parse` | 登录 |  | `parseReportDraft` |
+| POST | `/api/indicator/change-ranking` | 登录 |  | `getIndicatorChangeRanking` |
+| POST | `/api/nutrition/beijing/analysis` | 登录 |  | `getGutFloraAnalysis` |
+
+### pages/health/gut-flora-foods-detail  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/food/recommendation/members` | 登录 |  | `getCautionFamilyMembers` |
+| POST | `/api/food/recommendation/trend` | 登录 |  | `getFoodCautionTrend` |
+| POST | `/api/health/foods` | 登录 |  | `getHealthFoods` |
+| POST | `/api/health/knowledge/v3/food/query` | 登录 |  | `queryFoodKnowledge` |
+| POST | `/api/health/report/edit` | 登录 |  | `editHealthReport` |
+
+### pages/health/gut-flora-risks-detail  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/knowledge/query` | 登录 |  | `queryKnowledgeBase` |
+| POST | `/api/health/knowledge/unified/disease/query` | 登录 |  | `queryDiseaseKnowledge` |
+| POST | `/api/health/knowledge/v3/indicator/query` | 登录 |  | `queryIndicatorKnowledge` |
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+| POST | `/api/health/report/edit` | 登录 |  | `editHealthReport` |
+
+### pages/health/gut-flora-species-detail  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/knowledge/query` | 登录 |  | `queryKnowledgeBase` |
+| POST | `/api/health/knowledge/v3/bacteria/query` | 登录 |  | `queryBacteriaKnowledge` |
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+| POST | `/api/health/report/edit` | 登录 |  | `editHealthReport` |
+
+### pages/health/health-plan-summary  (11 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/preferences/current-member` | 登录 |  | `getDietPreferences` |
+| POST | `/api/diet/preferences/save` | 登录 |  | `saveDietPreferences` |
+| POST | `/api/health-status/get` | 登录 |  | `getHealthStatus` |
+| POST | `/api/health-status/save` | 登录 |  | `saveHealthStatus` |
+| POST | `/api/health-status/signature` | 登录 |  | `saveHealthSignature` |
+| POST | `/api/health/plan/confirm` | 登录 |  | `confirmPlan` |
+| POST | `/api/health/plan/detail` | 登录 |  | `getHealthPlanDetail` |
+| POST | `/api/health/plan/generate` | 登录 |  | `generateHealthPlan` |
+| POST | `/api/health/plan/regenerate-section` | 登录 |  | `regenerateSection` |
+| POST | `/api/health/plan/save` | 登录 |  | `saveHealthPlan` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/health/health-status-form  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health-status/get` | 登录 |  | `getHealthStatus` |
+| POST | `/api/health-status/save` | 登录 |  | `saveHealthStatus` |
+
+### pages/health/health-survey  (6 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/diet/preferences/current-member` | 登录 |  | `getDietPreferences` |
+| POST | `/api/diet/preferences/save` | 登录 |  | `saveDietPreferences` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health-status/get` | 登录 |  | `getHealthStatus` |
+| POST | `/api/health-status/save` | 登录 |  | `saveHealthStatus` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/health/indicator-curve  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/indicator/change-ranking` | 登录 |  | `getIndicatorChangeRanking` |
+| POST | `/api/indicator/trend` | 登录 |  | `getIndicatorTrend` |
+
+### pages/health/indicator-quicklook  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/indicator/quick-lookup` | 登录 |  | `getIndicatorQuickLookup` |
+
+### pages/health/my-feedback  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/feedback/list` | 公开 |  | `getMyReportFeedbacks` |
+
+### pages/health/nutrition-profile  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/nutrition/deficiency` | 登录 |  | `getDeficiencyAnalysis` |
+| POST | `/api/health/nutrition/profile` | 登录 |  | `getChildNutritionProfile` |
+
+### pages/health/physical-exam-detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+
+### pages/health/plan-list  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/plan/delete` | 登录 |  | `deleteHealthPlan` |
+| POST | `/api/health/plan/list` | 登录 |  | `getHealthPlanList` |
+
+### pages/health/report-confirm  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/add` | 登录 |  | `addFamilyMember` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/report/parse` | 登录 |  | `parseReportDraft` |
+
+### pages/health/report-detail  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/add` | 登录 |  | `addFamilyMember` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/report/edit` | 登录 |  | `editHealthReport` |
+| POST | `/api/health/report/parse` | 登录 |  | `parseReportDraft` |
+| POST | `/api/health/report/payload` | 登录 |  | `getReportPayload` |
+
+### pages/health/report-list  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/report/collecting-list` | 登录 |  | `getCollectingReports` |
+| POST | `/api/health/report/delete` | 登录 |  | `deleteReport` |
+| POST | `/api/health/report/list` | 登录 |  | `getReportList` |
+| POST | `/api/health/report/reassign` | 登录 |  | `reassignReport` |
+| POST | `/api/health/report/transfer/approve` | 登录 |  | `approveReportTransfer` |
+| POST | `/api/health/report/transfer/deny` | 登录 |  | `denyReportTransfer` |
+| POST | `/api/health/report/transfer/list` | 登录 |  | `getReportTransferList` |
+
+### pages/health/report-survey  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/survey/create` | 登录 |  | `createReportSurvey` |
+| POST | `/api/health/survey/submit` | 登录 |  | `submitReportSurvey` |
+| POST | `/api/survey/status` | 登录 |  | `getSurveyStatus` |
+
+### pages/health/report-upload  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/report/collect/status` | 登录 |  | `getReportCollectStatus` |
+| POST | `/api/health/report/transfer/request` | 登录 |  | `requestReportTransfer` |
+| POST | `/api/health/report/upload-only` | 登录 |  | `uploadReportOnly` |
+
+### pages/health/survey-history  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/survey/history` | 登录 |  | `getSurveyHistory` |
+| POST | `/api/survey/template/active` | 登录 |  | `getActiveTemplates` |
+
+### pages/health/survey-questionnaire  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/survey/submit` | 登录 |  | `submitSurvey` |
+| POST | `/api/survey/template/active` | 登录 |  | `getActiveTemplates` |
+
+### pages/health/teacher-service  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health-plan/available-teachers` | 登录 |  | `getAvailableTeachers` |
+
+### pages/home-pages/child-index  (11 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/energy/logs` | 登录 |  | `getEnergyLogs` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/guide-config/current` | 登录 |  | `getGuideConfig` |
+| POST | `/api/guide/popup/consume` | 登录 |  | `consumeGuidePopup` |
+| POST | `/api/guide/popup/list` | 登录 |  | `getGuidePopupList` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/unlock/status` | 登录 |  | `getUnlockStatus` |
+| POST | `/api/user/switch-mode` | 登录 |  | `switchMode` |
+
+### pages/home-pages/components/AdBanner  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home-banner/list` | 登录 |  | `getHomeBanners` |
+
+### pages/home-pages/components/ContactImport  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/contact/import-phone` | 登录 |  | `importPhoneContact` |
+
+### pages/home-pages/components/DailySummary  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/feedback/read` | 公开 |  | `markFeedbackRead` |
+| POST | `/api/feedback/today` | 公开 |  | `getTodayFeedback` |
+
+### pages/home-pages/components/MicroActionCard  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/micro-action/complete` | 登录 |  | `microActionComplete` |
+| POST | `/api/micro-action/today` | 登录 |  | `microActionToday` |
+
+### pages/home-pages/member-home-detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/home-pages/parent-index  (23 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/articles/featured` | 公开 |  | `getFeaturedArticles` |
+| POST | `/api/contact/list` | 登录 |  | `getContactList` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/member/switch` | 登录 |  | `switchToFamilyMember` |
+| POST | `/api/family/self-check/status` | 登录 |  | `getSelfCheckStatus` |
+| POST | `/api/health/alert/dismiss` | 登录 |  | `dismissAlert` |
+| POST | `/api/health/alert/list` | 登录 |  | `getActiveAlerts` |
+| POST | `/api/health/challenge/list` | 登录 |  | `getChallengeList` |
+| POST | `/api/health/circle/list` | 登录 |  | `getCircleList` |
+| POST | `/api/health/circle/ranking` | 登录 |  | `getCircleRanking` |
+| POST | `/api/health/family/ranking` | 登录 |  | `getFamilyRanking` |
+| POST | `/api/invite/qrcode` | 登录 |  | `getInviteQrCode` |
+| POST | `/api/parent/dashboard` | 登录 |  | `getParentDashboard` |
+| POST | `/api/stats/child-completion` | 登录 |  | `getChildCompletionStats` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `approveTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `rejectTask` |
+| POST | `/api/tasks/pending-review` | 登录 |  | `getPendingReviewTasks` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/unlock/status` | 登录 |  | `getUnlockStatus` |
+| POST | `/api/wishes/pending` | 登录 |  | `getPendingWishes` |
+
+### pages/home/app-library  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home/app-library` | 登录 |  | `getAppLibrary` |
+| POST | `/api/home/shortcut/reset` | 登录 |  | `resetShortcutConfig` |
+| POST | `/api/home/shortcut/save` | 登录 |  | `saveShortcutConfig` |
+
+### pages/index-home/index  (28 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/admin/notices/all` | 登录 |  | `getNotices` |
+| POST | `/api/articles/featured` | 公开 |  | `getFeaturedArticles` |
+| POST | `/api/commission/cf/list` | 登录 |  | `getCfList` |
+| POST | `/api/commission/cf/summary` | 登录 |  | `getCfSummary` |
+| POST | `/api/energy/logs` | 登录 |  | `getEnergyLogs` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/member/switch` | 登录 |  | `switchToFamilyMember` |
+| POST | `/api/family/self-check/status` | 登录 |  | `getSelfCheckStatus` |
+| POST | `/api/guide-config/current` | 登录 |  | `getGuideConfig` |
+| POST | `/api/guide/parent-invite/accept` | 登录 |  | `acceptParentInvite` |
+| POST | `/api/guide/popup/consume` | 登录 |  | `consumeGuidePopup` |
+| POST | `/api/guide/popup/list` | 登录 |  | `getGuidePopupList` |
+| POST | `/api/health/challenge/list` | 登录 |  | `getChallengeList` |
+| POST | `/api/health/challenge/progress` | 登录 |  | `updateChallengeProgress` |
+| POST | `/api/health/challenge/respond` | 登录 |  | `respondChallenge` |
+| POST | `/api/home/app-library` | 登录 |  | `getAppLibrary` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/notification/list` | 登录 |  | `getNotificationList` |
+| POST | `/api/notification/read` | 登录 |  | `readNotification` |
+| POST | `/api/points/logs` | 登录 |  | `getPointsLogs` |
+| POST | `/api/survey/status` | 登录 |  | `getSurveyStatus` |
+| POST | `/api/tasks/history` | 登录 |  | `getTaskHistory` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+
+### pages/invite/join  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/invite/check-family` | 公开 |  | `checkUserFamily` |
+| POST | `/api/family/invite/validate` | 公开 |  | `validateInvitation` |
+| POST | `/api/family/invite/validate-family-code` | 公开 |  | `validateFamilyCode` |
+| POST | `/api/invite/bind` | 登录 |  | `bindReferral` |
+
+### pages/invite/join-form  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/invite/request-join-by-code` | 公开 |  | `requestJoinByCode` |
+| POST | `/api/user/update` | 登录 |  | `updateUserInfo` |
+
+### pages/login/scan-login  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/wechat-web/scan` | 公开 |  | `wechatWebScan` |
+
+### pages/match/street-match  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/admin/families/count` | 登录 |  | `countFamiliesByStreetIds` |
+| POST | `/api/admin/teachers/count` | 登录 |  | `countTeachersByStreetIds` |
+| POST | `/api/streets//:var/match`)
+}
+
+// 按区域统计
+export const getStreetStats = (level = 4) => {
+  return request('/api/streets/stats', 'POST', { level })
+}
+
+// 获取家庭详情(含地址信息)
+export const getFamilyDetail = (id) => {
+  return request(`/api/admin/families//:var`)
+}
+
+// 更新家庭地址
+export const updateFamilyAddress = (data) => {
+  return request(`/api/admin/families/update` | 公开 | ✓ | `matchByStreet` |
+
+### pages/meal/log  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/meal/log` | 登录 |  | `logMeal` |
+| POST | `/api/meal/logs` | 登录 |  | `getMealLogs` |
+| POST | `/api/meal/nutrition-summary` | 登录 |  | `getNutritionSummary` |
+
+### pages/meal/preference  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/nutrition/profile/get` | 登录 |  | `getNutritionProfile` |
+| POST | `/api/nutrition/profile/save` | 登录 |  | `saveNutritionProfile` |
+
+### pages/meal/recommend  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/meal/recommend` | 登录 |  | `getMealRecommend` |
+| POST | `/api/meal/replace` | 登录 |  | `replaceFood` |
+
+### pages/member-detail/components/member-detail-sections/action-section  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasksByCategory` |
+| POST | `/api/wealth/checkin/stats` | 登录 |  | `getCheckinStats` |
+
+### pages/member-detail/components/member-detail-sections/body-section  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dimension/overview` | 登录 |  | `getDimensionOverview` |
+| POST | `/api/health/analysis` | 登录 |  | `getHealthAnalysis` |
+| POST | `/api/wealth/checkin/list` | 登录 |  | `getCheckinList` |
+
+### pages/member-detail/components/member-detail-sections/mind-section  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/contact/list` | 登录 |  | `getContactList` |
+| POST | `/api/family/relationship/health-alerts` | 登录 |  | `getHealthAlerts` |
+| POST | `/api/family/relationship/milestones` | 登录 |  | `getMilestones` |
+| POST | `/api/family/relationship/scores` | 登录 |  | `getRelationshipScores` |
+
+### pages/member-detail/components/member-detail-sections/wisdom-section  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/assessment/history` | 登录 |  | `getAssessmentHistory` |
+| POST | `/api/assessment/latest-result` | 登录 |  | `getAssessmentLatestResult` |
+
+### pages/member-detail/member-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/activity/list` | 公开 |  | `getActivityList` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/member-detail/report-detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/report/detail` | 登录 |  | `getReportDetail` |
+
+### pages/membership/benefits  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/membership/benefits` | 登录 |  | `getMembershipBenefits` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/membership/index  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/butler/my-butler` | 公开 |  | `getMyButler` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/membership/benefits` | 登录 |  | `getMembershipBenefits` |
+| POST | `/api/membership/compare` | 登录 |  | `getMembershipCompare` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/membership/pay  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/coupon/list` | 登录 |  | `getCouponList` |
+| POST | `/api/membership/orders` | 登录 |  | `createOrder` |
+| POST | `/api/membership/orders/continue` | 登录 |  | `nextOrder` |
+| POST | `/api/membership/plans` | 登录 |  | `getMembershipPlans` |
+
+### pages/membership/result  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/coupon/join-rules` | 登录 |  | `getJoinCouponRules` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/membership/orders/continue` | 登录 |  | `nextOrder` |
+
+### pages/membership/upgrade  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/coupon/join-rules` | 登录 |  | `getJoinCouponRules` |
+| POST | `/api/membership/compare` | 登录 |  | `getMembershipCompare` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/membership/plans` | 登录 |  | `getMembershipPlans` |
+| POST | `/api/membership/upgrade-records` | 登录 |  | `getUpgradeRecords` |
+
+### pages/mind-detail/articles  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/articles/categories` | 公开 |  | `getArticleCategories` |
+| POST | `/api/articles/list` | 公开 |  | `getArticleList` |
+
+### pages/mind-detail/components/PsychCrisisBanner  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/alert/dismiss` | 登录 |  | `dismissAlert` |
+
+### pages/mind-detail/emotion-report  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/emireport/latest` | 登录 |  | `getEmiReport` |
+
+### pages/mind-detail/family-dashboard  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/mind/fortune` | 登录 |  | `getFamilyFortune` |
+| POST | `/api/mind/fortune/month` | 登录 |  | `getMonthFortune` |
+| POST | `/api/mind/fortune/reports` | 登录 |  | `getFortuneReports` |
+| POST | `/api/mind/fortune/week` | 登录 |  | `getWeekFortune` |
+
+### pages/mind-detail/index  (14 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/contact/list` | 登录 |  | `getContactList` |
+| POST | `/api/content-sections/visible` | 登录 |  | `getVisibleSections` |
+| POST | `/api/dan-assessment/report/child` | 登录 |  | `getDanReportByChild` |
+| POST | `/api/dimension/radar-data` | 登录 |  | `getRadarData` |
+| POST | `/api/emireport/latest` | 登录 |  | `getEmiReport` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/relationship/health-alerts` | 登录 |  | `getHealthAlerts` |
+| POST | `/api/family/relationship/milestones` | 登录 |  | `getMilestones` |
+| POST | `/api/health/indicators` | 登录 |  | `getLatestIndicators` |
+| POST | `/api/mind/fortune` | 登录 |  | `getFamilyFortune` |
+
+### pages/mind-detail/innate-portrait  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/mind/innate/reading` | 登录 |  | `getInnateReading` |
+
+### pages/mind-detail/innate-trajectory  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/mind/innate/trajectory` | 登录 |  | `getInnateTrajectory` |
+
+### pages/mind-detail/member-mind-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/mind-detail/training  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/game/stats` | 登录 |  | `getGameStats` |
+
+### pages/notification/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/notification/list` | 登录 |  | `getNotificationList` |
+| POST | `/api/notification/read` | 登录 |  | `readNotification` |
+
+### pages/nutritionist/apply  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/nutritionist/apply` | 公开 |  | `nutritionistApply` |
+
+### pages/orchestration/editor  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/admin/task-templates` | 登录 |  | `getNodeTemplateList` |
+| POST | `/api/orchestration/flow/detail` | 登录 |  | `getOrchestrationFlowDetail` |
+| POST | `/api/orchestration/flow/publish` | 登录 |  | `publishOrchestrationFlow` |
+| POST | `/api/orchestration/flow/save` | 登录 |  | `saveOrchestrationFlow` |
+
+### pages/orchestration/index  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/orchestration/flow/archive` | 登录 |  | `archiveOrchestrationFlow` |
+| POST | `/api/orchestration/flow/delete` | 登录 |  | `deleteOrchestrationFlow` |
+| POST | `/api/orchestration/flow/list` | 登录 |  | `getOrchestrationFlowList` |
+| POST | `/api/orchestration/flow/publish` | 登录 |  | `publishOrchestrationFlow` |
+
+### pages/orchestration/node-edit  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/parent/appointments  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/dan-assessment/appointment/cancel` | 登录 |  | `cancelAppointment` |
+| POST | `/api/dan-assessment/appointment/user` | 登录 |  | `getMyAppointments` |
+
+### pages/parent/child-detail  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tasks/pending-review` | 登录 |  | `getPendingReviewTasks` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+| POST | `/api/wishes/pending` | 登录 |  | `getPendingWishes` |
+
+### pages/parent/plans/detail  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/plans/detail` | 登录 |  | `getGuidePlanDetail` |
+
+### pages/parent/plans/index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/plans/family-list` | 登录 |  | `listFamilyPlans` |
+
+### pages/parent/wishes/index  (6 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/wishes//:var/approve-exchange` | 登录 | ✓ | `approveWishExchange` |
+| POST | `/api/wishes//:var/fulfill` | 登录 | ✓ | `markWishFulfilled` |
+| POST | `/api/wishes//:var/price` | 登录 | ✓ | `setWishPrice` |
+| POST | `/api/wishes//:var/reject` | 登录 | ✓ | `rejectWish` |
+| POST | `/api/wishes/list` | 登录 |  | `getWishes` |
+| POST | `/api/wishes/pending` | 登录 |  | `getPendingWishes` |
+
+### pages/pearl-reminders/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/pearl/interaction/add` | 登录 |  | `addPearlInteraction` |
+| POST | `/api/pearl/reminder/list` | 登录 |  | `getPearlReminders` |
+
+### pages/profile-extra/coupons  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/coupon/claim` | 登录 |  | `claimCoupon` |
+| POST | `/api/coupon/exchangeable` | 登录 |  | `getExchangeableCoupons` |
+| POST | `/api/coupon/my` | 登录 |  | `getMyCoupons` |
+| POST | `/api/family-platform/exchange-coupon` | 登录 |  | `exchangeCouponByCf` |
+
+### pages/profile-extra/family-members  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/invite/generate` | 公开 |  | `generateFamilyInvite` |
+| POST | `/api/family/invite/pending-requests` | 公开 |  | `getPendingJoinRequests` |
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/member/switch` | 登录 |  | `switchToFamilyMember` |
+| POST | `/api/health/report/member-permission/members/'/:var, 'POST', {})
+
+/** 授权:让指定用户可查看某成员的报告(管理员) */
+export const grantReportMemberPermission = (targetMemberId, granteeUserId) =>
+  request('/api/health/report/member-permission/grant` | 登录 | ✓ | `getMemberGrantedUsers` |
+| POST | `/api/health/report/member-permission/revoke` | 登录 |  | `revokeReportMemberPermission` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+
+### pages/profile-extra/gates  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/unlock/status` | 登录 |  | `getUnlockStatus` |
+
+### pages/profile-extra/onboarding  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/onboarding/claim` | 登录 |  | `claimOnboardingReward` |
+| POST | `/api/onboarding/progress` | 登录 |  | `getOnboardingProgress` |
+
+### pages/profile-main/profile  (16 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/cart/count` | 登录 |  | `cartCount` |
+| POST | `/api/commission/my-referrer` | 登录 |  | `getMyReferrer` |
+| POST | `/api/commission/team/consumption` | 登录 |  | `getTeamConsumption` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/challenge/list` | 登录 |  | `getChallengeList` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/invite/summary` | 登录 |  | `getReferralSummary` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/product/order/my/counts` | 公开 |  | `getOrderCounts` |
+| POST | `/api/share/qrcode` | 登录 |  | `getShareQrCode` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasksByCategory` |
+| POST | `/api/user/info` | 登录 |  | `getUserInfo` |
+| POST | `/api/user/profile-stats` | 登录 |  | `getProfileStats` |
+| POST | `/api/vendor/status` | 公开 |  | `vendorStatus` |
+
+### pages/profile/components/ProfileHeader  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/family/member/switch` | 登录 |  | `switchToFamilyMember` |
+
+### pages/profile/components/ProfileMenu  (6 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/set-password` | 公开 |  | `setPassword` |
+| POST | `/api/auth/verify-password` | 公开 |  | `verifyPassword` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/user/members/update-visibility` | 登录 |  | `updateMemberVisibility` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/vendor/status` | 公开 |  | `vendorStatus` |
+
+### pages/profile/components/ProfileStats  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/user/action-stats` | 登录 |  | `getUserActionStats` |
+
+### pages/profile/index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+
+### pages/profile/message-history  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/commission/cf/list` | 登录 |  | `getCfList` |
+| POST | `/api/energy/logs` | 登录 |  | `getEnergyLogs` |
+| POST | `/api/notification/list` | 登录 |  | `getNotificationList` |
+| POST | `/api/notification/read` | 登录 |  | `readNotification` |
+| POST | `/api/points/logs` | 登录 |  | `getPointsLogs` |
+
+### pages/profile/portrait-edit  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/sandbox` | 登录 |  | `getEnergySandbox` |
+| POST | `/api/user/portrait/edit` | 登录 |  | `editPortrait` |
+| POST | `/api/user/portrait/get` | 登录 |  | `getPortrait` |
+
+### pages/profile/report-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/report-summary/detail/'/:var, 'POST', {})
+export const downloadReportSummary = (id) => request('/api/report-summary/download/'/:var, 'POST', {})
+
+// 服务角色统一申请
+export const submitServiceRoleApply = (data) => {
+    return request('/api/service-role/apply` | 登录 | ✓ | `getReportSummaryDetail` |
+
+### pages/profile/report-management  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/report-summary/list` | 登录 |  | `getReportSummaryList` |
+
+### pages/profile/service-role-apply  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/service-role/my-apply` | 登录 |  | `getMyServiceRoleApply` |
+| POST | `/api/service-role/upload-image` | 登录 |  | `uploadServiceRoleImage` |
+
+### pages/promotion/commission  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/commission/cf/list` | 登录 |  | `getCfList` |
+| POST | `/api/commission/cf/summary` | 登录 |  | `getCfSummary` |
+
+### pages/promotion/index  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/commission/cf/summary` | 登录 |  | `getCfSummary` |
+| POST | `/api/earnings/admin/distribute` | 登录 |  | `distributeToMember` |
+| POST | `/api/earnings/admin/toggle-member` | 登录 |  | `toggleMemberBalance` |
+| POST | `/api/earnings/admin/withdraw` | 登录 |  | `withdrawFamilyEarnings` |
+| POST | `/api/earnings/family/summary` | 登录 |  | `getFamilyEarningsSummary` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/invite/summary` | 登录 |  | `getReferralSummary` |
+
+### pages/promotion/invite  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/invite/bind` | 登录 |  | `bindReferral` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/invite/list` | 登录 |  | `getReferralList` |
+| POST | `/api/invite/milestone/claim` | 登录 |  | `claimInviteMilestone` |
+| POST | `/api/invite/milestone/list` | 登录 |  | `getInviteMilestones` |
+| POST | `/api/invite/qrcode` | 登录 |  | `getInviteQrCode` |
+| POST | `/api/invite/summary` | 登录 |  | `getReferralSummary` |
+
+### pages/promotion/leaderboard  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/leaderboard/my-rank` | 登录 |  | `getLeaderboardMyRank` |
+| POST | `/api/leaderboard/top` | 登录 |  | `getLeaderboardTop` |
+
+### pages/promotion/team  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/commission/cf/rate` | 登录 |  | `getCfRate` |
+| POST | `/api/commission/my-referrer` | 登录 |  | `getMyReferrer` |
+| POST | `/api/commission/team/consumption` | 登录 |  | `getTeamConsumption` |
+| POST | `/api/commission/team/consumption-curve` | 登录 |  | `getTeamAllMembersConsumptionCurve` |
+| POST | `/api/commission/team/growth-curve` | 登录 |  | `getTeamGrowthCurve` |
+| POST | `/api/commission/team/l1-consumption-curve` | 登录 |  | `getTeamL1ConsumptionCurve` |
+| POST | `/api/commission/team/list` | 登录 |  | `getTeamList` |
+| POST | `/api/commission/team/tree` | 登录 |  | `getTeamTree` |
+
+### pages/promotion/withdraw  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/commission/summary` | 登录 |  | `getCommissionSummary` |
+| POST | `/api/withdrawal/apply` | 登录 |  | `applyWithdrawal` |
+| POST | `/api/withdrawal/history` | 登录 |  | `getWithdrawalHistory` |
+
+### pages/psych-assessment/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/child` | 登录 |  | `getCognitiveChildScores` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+
+### pages/psych-assessment/quiz  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cognitive/self-test` | 登录 |  | `submitCognitiveSelfTest` |
+
+### pages/reminder-config/index  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/task/reminder-config/get` | 登录 |  | `getReminderConfig` |
+| POST | `/api/task/reminder-config/save` | 登录 |  | `saveReminderConfig` |
+
+### pages/rewards/badge  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/badges/child/list` | 登录 |  | `getChildBadges` |
+| POST | `/api/badges/favorite` | 登录 |  | `toggleBadgeFavorite` |
+| POST | `/api/badges/list` | 登录 |  | `getActiveBadges` |
+| POST | `/api/badges/ranking/family` | 登录 |  | `getFamilyBadgeRanking` |
+| POST | `/api/badges/statistics/child` | 登录 |  | `getChildBadgeStats` |
+
+### pages/rewards/rewards  (9 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/parent/wishlist` | 登录 |  | `createParentWishlist` |
+| POST | `/api/parent/wishlist//:var/exchange` | 登录 | ✓ | `exchangeParentWishlist` |
+| POST | `/api/parent/wishlist/list` | 登录 |  | `getParentWishlist` |
+| POST | `/api/points/balance` | 登录 |  | `getPointsBalance` |
+| POST | `/api/rewards` | 登录 |  | `createReward` |
+| POST | `/api/rewards//:var/exchange` | 登录 | ✓ | `exchangeReward` |
+| POST | `/api/rewards/wishlist` | 登录 |  | `getWishlist` |
+| POST | `/api/user/info` | 登录 |  | `getUserInfo` |
+
+### pages/share/index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/share/family-footprint` | 登录 |  | `getFamilyFootprint` |
+
+### pages/shop/cart/cart  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/membership/gift-membership-progress` | 登录 |  | `getGiftMembershipProgress` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/shop/checkout/checkout  (12 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/coupon/apply` | 登录 |  | `applyCoupon` |
+| POST | `/api/coupon/checkout-list` | 登录 |  | `getCouponCheckoutList` |
+| POST | `/api/coupon/list` | 登录 |  | `getCouponList` |
+| POST | `/api/family-platform/balance` | 登录 |  | `getFamilyPlatformBalance` |
+| POST | `/api/family-platform/exchange-coupon` | 登录 |  | `exchangeCouponByCf` |
+| POST | `/api/membership/gift-membership-progress` | 登录 |  | `getGiftMembershipProgress` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/product/detail` | 公开 |  | `productDetail` |
+| POST | `/api/product/purchase_fields/required` | 公开 |  | `getProductRequiredFields` |
+| POST | `/api/shop/discount/calculate` | 公开 |  | `shopDiscountCalculate` |
+| POST | `/api/special-price/info` | 登录 |  | `getSpecialPriceInfo` |
+| POST | `/api/user/address/list` | 登录 |  | `addressList` |
+
+### pages/shop/consignee-edit/consignee-edit  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/consignee/detail` | 登录 |  | `consigneeDetail` |
+| POST | `/api/consignee/save` | 登录 |  | `consigneeSave` |
+
+### pages/shop/consignee-list/consignee-list  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/consignee/delete` | 登录 |  | `consigneeDelete` |
+| POST | `/api/consignee/list` | 登录 |  | `consigneeList` |
+
+### pages/shop/index/index  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/cart/count` | 登录 |  | `cartCount` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+| POST | `/api/shop/category/tree` | 公开 |  | `goodsCategory` |
+
+### pages/shop/order-detail/order-detail  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/order/cancel` | 公开 |  | `productOrderCancel` |
+| POST | `/api/product/order/confirm` | 公开 |  | `productOrderConfirm` |
+| POST | `/api/product/order/detail` | 公开 |  | `productOrderDetail` |
+
+### pages/shop/order-list/order-list  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/order/cancel` | 公开 |  | `productOrderCancel` |
+| POST | `/api/product/order/confirm` | 公开 |  | `productOrderConfirm` |
+| POST | `/api/product/order/my` | 公开 |  | `productOrderMy` |
+| POST | `/api/product/order/my/counts` | 公开 |  | `productOrderCounts` |
+
+### pages/shop/payment/payment  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+
+### pages/shop/search/search  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/list` | 公开 |  | `productList` |
+
+### pages/stats/completion-rate  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/stats/child-completion` | 登录 |  | `getChildCompletionStats` |
+| POST | `/api/stats/family-completion` | 登录 |  | `getFamilyCompletionStats` |
+
+### pages/stats/index  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/stats/child/overview` | 登录 |  | `getChildOverview` |
+
+### pages/tasks/create-task  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tasks/create` | 登录 |  | `createTask` |
+| POST | `/api/tasks/list` | 登录 |  | `getTaskListForPicker` |
+
+### pages/tasks/daily-tasks  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/growth-task/claim` | 登录 |  | `claimGrowthTaskReward` |
+| POST | `/api/growth-task/list` | 登录 |  | `getGrowthTaskList` |
+
+### pages/tasks/review  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `approveTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `rejectTask` |
+| POST | `/api/tasks/history` | 登录 |  | `getTaskHistory` |
+| POST | `/api/tasks/pending-review` | 登录 |  | `getPendingReviewTasks` |
+
+### pages/tasks/tasks  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/tasks//:var/complete` | 登录 | ✓ | `completeTask` |
+| POST | `/api/tasks/accept` | 登录 |  | `acceptTask` |
+| POST | `/api/tasks/create` | 登录 |  | `createTask` |
+| POST | `/api/tasks/my-pending` | 登录 |  | `getMyPendingTasks` |
+| POST | `/api/tasks/today` | 登录 |  | `getTodayTasks` |
+
+### pages/teacher/chat  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/messages/list` | 登录 |  | `getGuideMessages` |
+
+### pages/teacher/families  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/families` | 登录 |  | `getBoundFamilies` |
+
+### pages/teacher/messages  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/messages/list` | 登录 |  | `getGuideMessages` |
+
+### pages/teacher/orders  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/orders/list` | 登录 |  | `getGuideOrders` |
+| POST | `/api/guide/orders/stats` | 登录 |  | `getOrderStats` |
+
+### pages/teacher/plan-create  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/training-plans/create` | 登录 |  | `createTrainingPlan` |
+
+### pages/teacher/plan-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/families//:var/plans//:var/update` | 登录 | ✓ | `updateGuidePlanContent` |
+| POST | `/api/guide/families//:var/plans/pending` | 登录 | ✓ | `getGuidePendingPlans` |
+
+### pages/teacher/plan-list  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/training-plans/list` | 登录 |  | `getTrainingPlanList` |
+
+### pages/teacher/review-family  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/families//:var/children//:var/pending-review` | 登录 | ✓ | `getGuideChildPendingTasks` |
+| POST | `/api/guide/families//:var/members` | 登录 | ✓ | `getGuideFamilyMembers` |
+| POST | `/api/guide/families//:var/plans/pending` | 登录 | ✓ | `getGuidePendingPlans` |
+| POST | `/api/guide/families//:var/tasks//:var/review` | 登录 | ✓ | `reviewGuideTask` |
+| POST | `/api/tasks//:var/review` | 登录 | ✓ | `reviewTask` |
+
+### pages/teacher/review-workbench  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/families/my-families` | 登录 |  | `getGuideMyFamilies` |
+
+### pages/teacher/service-tasks  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tasks//:var/complete` | 登录 | ✓ | `completeTask` |
+
+### pages/teacher/teacher-profile  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/parent-invite/generate` | 登录 |  | `generateParentInvite` |
+| POST | `/api/user/switch-role` | 登录 |  | `switchRole` |
+
+### pages/teacher/team  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/guide/invite-code/generate` | 公开 |  | `generateInviteCode` |
+| POST | `/api/guide/team/invite-code/generate` | 登录 |  | `generateTeamInviteCode` |
+| POST | `/api/guide/team/members` | 登录 |  | `getTeamMembers` |
+| POST | `/api/guide/team/stats` | 登录 |  | `getTeamStats` |
+
+### pages/user-edit/user-edit  (6 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/direct-register` | 公开 |  | `directRegister` |
+| POST | `/api/family/invite/request-join-by-code` | 公开 |  | `requestJoinByCode` |
+| POST | `/api/family/user/create-family` | 登录 |  | `createFamily` |
+| POST | `/api/membership/my` | 登录 |  | `getMyMembership` |
+| POST | `/api/user/info` | 登录 |  | `getUserInfo` |
+| POST | `/api/user/update` | 登录 |  | `updateUserInfo` |
+
+### pages/vendor/apply  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/vendor/apply` | 登录 |  | `vendorApply` |
+
+### pages/vendor/center  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/vendor/info` | 公开 |  | `vendorInfo` |
+| POST | `/api/vendor/status` | 公开 |  | `vendorStatus` |
+
+### pages/vendor/order-review/order-review  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/order/detail` | 公开 |  | `productOrderDetail` |
+| POST | `/api/product/order/review/update` | 公开 |  | `productOrderReviewUpdate` |
+
+### pages/vendor/orders/orders  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/order/confirm` | 公开 |  | `productOrderConfirm` |
+| POST | `/api/product/order/vendor` | 公开 |  | `productOrderVendor` |
+
+### pages/vendor/product-edit/product-edit  (3 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/create` | 公开 |  | `productCreate` |
+| POST | `/api/product/detail` | 公开 |  | `productDetail` |
+| POST | `/api/product/update` | 公开 |  | `productUpdate` |
+
+### pages/vendor/products/products  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/product/my` | 公开 |  | `productMy` |
+| POST | `/api/product/shelve` | 公开 |  | `productShelve` |
+
+### pages/vendor/team-customers/team-customers  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/admin/supply-team/customers` | 登录 |  | `getTeamCustomers` |
+
+### pages/vendor/team-system/team-system  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/admin/supply-hierarchy/my` | 登录 |  | `getVendorHierarchyInfo` |
+| POST | `/api/admin/supply-system/my-system` | 登录 |  | `getVendorSystemInfo` |
+| POST | `/api/admin/supply-team/customers` | 登录 |  | `getVendorTeamCustomers` |
+| POST | `/api/admin/supply-team/members` | 登录 |  | `getVendorTeamMembers` |
+
+### pages/wealth-cf/index  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| GET | `/api/cf/balance` | 登录 |  | `getCfBalance` |
+| GET | `/api/cf/family-coupons` | 登录 |  | `getFamilyCoupons` |
+| GET | `/api/cf/logs` | 登录 |  | `getCfLogs` |
+| POST | `/api/coupon/exchangeable` | 登录 |  | `getExchangeableCoupons` |
+| POST | `/api/family-platform/exchange-coupon` | 登录 |  | `exchangeCouponByCf` |
+
+### pages/wealth-detail/member-wealth-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/wealth-sub/checkin  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/wealth/checkin/create` | 登录 |  | `createCheckin` |
+| POST | `/api/wealth/checkin/delete` | 登录 |  | `deleteCheckin` |
+| POST | `/api/wealth/checkin/list` | 登录 |  | `getCheckinList` |
+| POST | `/api/wealth/checkin/stats` | 登录 |  | `getCheckinStats` |
+
+### pages/wealth-sub/insurance-add  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/wealth/insurance/create` | 公开 |  | `createInsurance` |
+| POST | `/api/wealth/insurance/detail` | 公开 |  | `getInsuranceDetail` |
+| POST | `/api/wealth/insurance/update` | 公开 |  | `updateInsurance` |
+| POST | `/api/wealth/insurance/upload` | 公开 |  | `uploadPolicy` |
+
+### pages/wealth-sub/insurance-list  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/wealth/insurance/delete` | 公开 |  | `deleteInsurance` |
+| POST | `/api/wealth/insurance/list` | 公开 |  | `getInsuranceList` |
+
+### pages/wealth-sub/insurance-planning  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/insurance/planning` | 登录 |  | `getInsurancePlanning` |
+
+### pages/wealth/index  (12 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/badges/statistics/child` | 登录 |  | `getChildBadgeStats` |
+| POST | `/api/commission/summary` | 登录 |  | `getCommissionSummary` |
+| POST | `/api/daily-task/overview` | 登录 |  | `getDailyTaskOverview` |
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+| POST | `/api/energy/wealth-detail` | 登录 |  | `getWealthDetail` |
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/invite/summary` | 登录 |  | `getReferralSummary` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+| POST | `/api/wealth/insurance/list` | 公开 |  | `getInsuranceList` |
+
+### pages/wisdom-detail/cognitive-report  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/assessment/latest-result` | 登录 |  | `getAssessmentLatestResult` |
+| POST | `/api/cognitive/norms` | 登录 |  | `getCognitiveNorms` |
+| POST | `/api/cognitive/recommendations` | 登录 |  | `getCognitiveRecommendations` |
+| POST | `/api/cognitive/recommendations/create-task` | 登录 |  | `createTaskFromRecommendation` |
+| POST | `/api/cognitive/trend` | 登录 |  | `getCognitiveTrend` |
+
+### pages/wisdom-detail/index  (8 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/assessment/latest-result` | 登录 |  | `getAssessmentLatestResult` |
+| POST | `/api/content-sections/visible` | 登录 |  | `getVisibleSections` |
+| POST | `/api/dan-assessment/report/child` | 登录 |  | `getDanReportByChild` |
+| POST | `/api/dimension/radar-data` | 登录 |  | `getRadarData` |
+| POST | `/api/family/member/kick` | 登录 |  | `kickFamilyMemberById` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/health/indicators` | 登录 |  | `getLatestIndicators` |
+| POST | `/api/wisdom/gut-cognition` | 登录 |  | `getGutCognitionIndicators` |
+
+### pages/wisdom-detail/member-wisdom-detail  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/energy/overview` | 登录 |  | `getEnergyOverview` |
+| POST | `/api/energy/sandbox` | 登录 |  | `getFamilyEnergySandbox` |
+
+### pages/wishes/create  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/wishes/create` | 登录 |  | `createWish` |
+
+### pages/wishes/detail  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/points/balance` | 登录 |  | `getPointsBalance` |
+| POST | `/api/wishes//:var` | 登录 | ✓ | `cancelWish` |
+| POST | `/api/wishes//:var` | 登录 | ✓ | `getWishById` |
+| POST | `/api/wishes//:var/confirm` | 登录 | ✓ | `confirmWishReceived` |
+| POST | `/api/wishes//:var/exchange` | 登录 | ✓ | `requestWishExchange` |
+
+### pages/wishes/index  (7 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/home/app/enter` | 登录 |  | `reportAppEnter` |
+| POST | `/api/points/balance` | 登录 |  | `getPointsBalance` |
+| POST | `/api/wishes//:var` | 登录 | ✓ | `cancelWish` |
+| POST | `/api/wishes//:var/confirm` | 登录 | ✓ | `confirmWishReceived` |
+| POST | `/api/wishes//:var/exchange` | 登录 | ✓ | `requestWishExchange` |
+| POST | `/api/wishes/create` | 登录 |  | `createWish` |
+| POST | `/api/wishes/list` | 登录 |  | `getWishes` |
+
+### store/health-alert  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/alert/dismiss` | 登录 |  | `dismissAlert` |
+| POST | `/api/health/alert/list` | 登录 |  | `getActiveAlerts` |
+
+### store/health-score  (2 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/health/score/info` | 登录 |  | `getHealthScoreInfo` |
+| POST | `/api/health/timeline/list` | 登录 |  | `getHealthTimeline` |
+
+### store/index  (4 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/family/user/switch-back-verify` | 登录 |  | `switchBackVerify` |
+| POST | `/api/user/switch-back-to-parent` | 登录 |  | `switchBackToParent` |
+| POST | `/api/user/switch-role` | 登录 |  | `switchRole` |
+| POST | `/api/user/switch-to-child` | 登录 |  | `switchToChild` |
+
+### store/modules/tianpan  (5 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/tianpan/annual-energy` | 公开 |  | `tianpanAnnualEnergy` |
+| POST | `/api/tianpan/daily-fortune` | 公开 |  | `tianpanDailyFortune` |
+| POST | `/api/tianpan/dashboard` | 公开 |  | `tianpanDashboard` |
+| POST | `/api/tianpan/member/'/:var, 'POST', data)
+}
+
+export const tianpanCompatibility = (data) => {
+  return request('/api/tianpan/compatibility` | 公开 | ✓ | `tianpanMemberDetail` |
+| POST | `/api/tianpan/related-items` | 公开 |  | `tianpanRelatedItems` |
+
+### utils/api  (38 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/admin/activity/list` | 公开 |  | `adminListMyActivities` |
+| POST | `/api/admin/task-templates` | 登录 |  | `getNodeTemplateList` |
+| POST | `/api/admin/task/reminder-config/get?userId='/:var, 'POST', {})
+}
+
+export function saveReminderConfigByUser(data) {
+  return request('/api/admin/task/reminder-config/save` | 登录 | ✓ | `getReminderConfigByUser` |
+| POST | `/api/auth/silent-login` | 公开 |  | `silentLogin` |
+| POST | `/api/badges/child/list` | 登录 |  | `getChildBadges` |
+| POST | `/api/butler/available-list` | 公开 |  | `getAvailableButlers` |
+| POST | `/api/butler/my-butler` | 公开 |  | `getMyButler` |
+| POST | `/api/butler/select` | 公开 |  | `selectButler` |
+| POST | `/api/dan-assessment/order/pay` | 登录 |  | `payAssessmentOrder` |
+| POST | `/api/family/invite/approve-request` | 公开 |  | `approveJoinRequest` |
+| POST | `/api/family/invite/my-request` | 公开 |  | `getMyJoinRequest` |
+| POST | `/api/family/invite/pending-requests` | 公开 |  | `getPendingJoinRequests` |
+| POST | `/api/family/invite/reject-request` | 公开 |  | `rejectJoinRequest` |
+| POST | `/api/family/member/list` | 登录 |  | `getFamilyMemberList` |
+| POST | `/api/family/user/create-family` | 登录 |  | `createFamily` |
+| POST | `/api/internal/virtual-pay/error-report` | 登录 |  | `reportVirtualPayError` |
+| POST | `/api/invite/bind` | 登录 |  | `bindReferral` |
+| POST | `/api/invite/code` | 登录 |  | `getReferralCode` |
+| POST | `/api/orchestration/execution/detail` | 登录 |  | `getOrchestrationExecutionDetail` |
+| POST | `/api/orchestration/execution/start` | 登录 |  | `startOrchestrationExecution` |
+| POST | `/api/orchestration/execution/terminate` | 登录 |  | `terminateOrchestrationExecution` |
+| POST | `/api/orchestration/flow/archive` | 登录 |  | `archiveOrchestrationFlow` |
+| POST | `/api/orchestration/flow/delete` | 登录 |  | `deleteOrchestrationFlow` |
+| POST | `/api/orchestration/flow/detail` | 登录 |  | `getOrchestrationFlowDetail` |
+| POST | `/api/orchestration/flow/list` | 登录 |  | `getOrchestrationFlowList` |
+| POST | `/api/orchestration/flow/publish` | 登录 |  | `publishOrchestrationFlow` |
+| POST | `/api/orchestration/flow/save` | 登录 |  | `saveOrchestrationFlow` |
+| POST | `/api/product/list` | 公开 |  | `productList` |
+| POST | `/api/profile/history` | 登录 |  | `getProfileTrend` |
+| POST | `/api/profile/my` | 登录 |  | `getMyProfile` |
+| POST | `/api/purchase/challenge/progress` | 登录 |  | `getChallengeProgress` |
+| POST | `/api/recommend/list` | 登录 |  | `getRecommendList` |
+| POST | `/api/stats/child/overview` | 登录 |  | `getChildOverview` |
+| POST | `/api/tasks/history` | 登录 |  | `getTaskHistory` |
+| POST | `/api/user/portrait/edit` | 登录 |  | `editPortrait` |
+| POST | `/api/user/portrait/generate` | 登录 |  | `generatePortrait` |
+| POST | `/api/user/portrait/get` | 登录 |  | `getPortrait` |
+| POST | `/api/user/portrait/regenerate` | 登录 |  | `regeneratePortrait` |
+
+### utils/profile-backfill  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/user/profile/backfill` | 登录 |  | `backfillProfile` |
+
+### utils/sso  (1 个接口)
+
+| 方法 | 路径 | 鉴权 | 参数 | 来源函数 |
+|------|------|:----:|:----:|----------|
+| POST | `/api/auth/sso-ticket` | 公开 |  | `createSsoTicket` |

+ 24 - 0
interface_test_biz_retest.tsv

@@ -0,0 +1,24 @@
+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	None	NOT_FOUND
+healthReport	indicatorsCurrent	POST	/api/health-report/indicators/current	404	None	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	None	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	None	NOT_FOUND

+ 2 - 0
interface_test_extra_cases.tsv

@@ -0,0 +1,2 @@
+auto	auto	POST	/api/packages/create	false	false
+auto	auto	POST	/api/packages/my	false	false

+ 20 - 0
interface_test_focus_biz.tsv

@@ -0,0 +1,20 @@
+page	fn	method	path	auth	param
+auth	directRegister	POST	/api/auth/direct-register	false	false
+auth	ssoLogin	POST	/api/auth/sso-login	false	false
+auth	verify	POST	/api/auth/verify	true	false
+auth	switchRole	POST	/api/auth/switch-role	true	false
+family	inviteCheck	POST	/api/family/invite/check-family	true	false
+family	guideBind	POST	/api/family/guide-bind	true	false
+family	memberSwitch	POST	/api/family/member/switch	true	false
+family	switchBackToParent	POST	/api/family/user/switch-back-to-parent	true	false
+family	switchMode	POST	/api/family/user/switch-mode	true	false
+family	switchToChild	POST	/api/family/user/switch-to-child	true	false
+healthStatus	get	POST	/api/health-status/get	true	false
+healthStatus	save	POST	/api/health-status/save	true	false
+healthReport	latest	POST	/api/health-report/report/latest	true	false
+healthReport	indicatorsCurrent	POST	/api/health-report/indicators/current	true	false
+activity	list	POST	/api/activity/list	false	false
+activity	detail	POST	/api/activity/detail	true	false
+task	today	POST	/api/task/today	true	false
+product	list	POST	/api/product/list	false	false
+product	detail	POST	/api/product/detail	false	false

+ 1008 - 0
interface_test_report.tsv

@@ -0,0 +1,1008 @@
+page	fn	method	path	http	biz	cat
+App	autoLogin	POST	/api/auth/auto-login	200	410	BIZ_FAIL
+App	ssoLogin	POST	/api/auth/sso-login	200	500	BIZ_FAIL
+App	verifyToken	POST	/api/auth/verify	200	200	BIZ_OK
+App	checkUserFamily	POST	/api/family/invite/check-family	200	200	BIZ_OK
+__tests__/api/api.indicator.test	getIndicatorChangeRanking	POST	/api/indicator/change-ranking	200	500	BIZ_FAIL
+__tests__/api/api.indicator.test	getIndicatorCorrelationList	POST	/api/indicator/correlation/list	200	500	BIZ_FAIL
+__tests__/api/api.indicator.test	getIndicatorQuickLookup	POST	/api/indicator/quick-lookup	200	500	BIZ_FAIL
+__tests__/api/api.indicator.test	getIndicatorTrend	POST	/api/indicator/trend	200	500	BIZ_FAIL
+__tests__/api/api.test	aiGetConversations	POST	/api/ai/chat/conversations	200	200	BIZ_OK
+__tests__/api/api.test	aiSendMessage	POST	/api/ai/chat/send	200	500	BIZ_FAIL
+__tests__/api/api.test	getArticleCategories	POST	/api/articles/categories	200	200	BIZ_OK
+__tests__/api/api.test	getDailyTip	POST	/api/articles/daily-tip	200	200	BIZ_OK
+__tests__/api/api.test	getArticleDetail	POST	/api/articles/detail	200	403	BIZ_FAIL
+__tests__/api/api.test	getArticleList	POST	/api/articles/list	200	200	BIZ_OK
+__tests__/api/api.test	getRelatedArticles	POST	/api/articles/related	200	500	BIZ_FAIL
+__tests__/api/api.test	autoLogin	POST	/api/auth/auto-login	200	410	BIZ_FAIL
+__tests__/api/api.test	checkPhone	POST	/api/auth/check-phone	200	500	BIZ_FAIL
+__tests__/api/api.test	directRegister	POST	/api/auth/direct-register	200	500	BIZ_FAIL
+__tests__/api/api.test	phoneLogin	POST	/api/auth/phone-login	200	500	BIZ_FAIL
+__tests__/api/api.test	sendCode	POST	/api/auth/send-code	200	500	BIZ_FAIL
+__tests__/api/api.test	setPassword	POST	/api/auth/set-password	200	400	BIZ_FAIL
+__tests__/api/api.test	silentLogin	POST	/api/auth/silent-login	200	500	BIZ_FAIL
+__tests__/api/api.test	verifyToken	POST	/api/auth/verify	200	200	BIZ_OK
+__tests__/api/api.test	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+__tests__/api/api.test	wechatLogin	POST	/api/auth/wechat-login	200	200	BIZ_OK
+__tests__/api/api.test	wechatPhoneLogin	POST	/api/auth/wechat-phone-login	200	500	BIZ_FAIL
+__tests__/api/api.test	getChildBadges	POST	/api/badges/child/list	200	200	BIZ_OK
+__tests__/api/api.test	toggleBadgeFavorite	POST	/api/badges/favorite	200	200	BIZ_OK
+__tests__/api/api.test	getActiveBadges	POST	/api/badges/list	200	200	BIZ_OK
+__tests__/api/api.test	getCommissionSummary	POST	/api/commission/summary	200	200	BIZ_OK
+__tests__/api/api.test	createContact	POST	/api/contact/create	200	400	BIZ_FAIL
+__tests__/api/api.test	deleteContact	POST	/api/contact/delete	200	500	BIZ_FAIL
+__tests__/api/api.test	importPhoneContact	POST	/api/contact/import-phone	200	400	BIZ_FAIL
+__tests__/api/api.test	getContactList	POST	/api/contact/list	200	200	BIZ_OK
+__tests__/api/api.test	getChildAssessmentResults	POST	/api/dan-assessment/child-results	200	200	BIZ_OK
+__tests__/api/api.test	getMyAssessmentResults	POST	/api/dan-assessment/my-results	200	200	BIZ_OK
+__tests__/api/api.test	payAssessmentOrder	POST	/api/dan-assessment/order/pay	200	500	BIZ_FAIL
+__tests__/api/api.test	recordAssessmentResult	POST	/api/dan-assessment/result/record	200	400	BIZ_FAIL
+__tests__/api/api.test	getEnergyLogs	POST	/api/energy/logs	200	200	BIZ_OK
+__tests__/api/api.test	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+__tests__/api/api.test	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+__tests__/api/api.test	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+__tests__/api/api.test	createChild	POST	/api/family/user/children	200	400	BIZ_FAIL
+__tests__/api/api.test	updateChild	POST	/api/family/user/children/update	200	200	BIZ_OK
+__tests__/api/api.test	createFamily	POST	/api/family/user/create-family	200	200	BIZ_OK
+__tests__/api/api.test	kickFamilyMember	POST	/api/family/user/kick	200	500	BIZ_FAIL
+__tests__/api/api.test	updateMemberVisibility	POST	/api/family/user/members/update-visibility	200	500	BIZ_FAIL
+__tests__/api/api.test	getGameHistory	POST	/api/game/history	200	200	BIZ_OK
+__tests__/api/api.test	getGameLeaderboard	POST	/api/game/leaderboard	200	200	BIZ_OK
+__tests__/api/api.test	createGrowthRecord	POST	/api/growth/record/create	200	500	BIZ_FAIL
+__tests__/api/api.test	createGrowthRecord	POST	/api/growth/record/create-with-order	200	500	BIZ_FAIL
+__tests__/api/api.test	getGrowthRecordList	POST	/api/growth/record/list	200	500	BIZ_FAIL
+__tests__/api/api.test	generateBindInvite	POST	/api/guide/bind/invite	200	200	BIZ_OK
+__tests__/api/api.test	getBoundFamilies	POST	/api/guide/families	404	None	NOT_FOUND
+__tests__/api/api.test	getGuideMessages	POST	/api/guide/messages/list	200	500	BIZ_FAIL
+__tests__/api/api.test	getGuideOrders	POST	/api/guide/orders/list	200	403	BIZ_FAIL
+__tests__/api/api.test	getGuidePackages	POST	/api/guide/packages/my	404	None	NOT_FOUND
+__tests__/api/api.test	registerGuide	POST	/api/guide/register	200	500	BIZ_FAIL
+__tests__/api/api.test	getTeamMembers	POST	/api/guide/team/members	200	200	BIZ_OK
+__tests__/api/api.test	healthCheckinList	POST	/api/health/checkin/list	200	200	BIZ_OK
+__tests__/api/api.test	getHealthIndicatorList	POST	/api/health/indicator/list	200	500	BIZ_FAIL
+__tests__/api/api.test	createHealthReport	POST	/api/health/report/create	200	4001	BIZ_FAIL
+__tests__/api/api.test	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+__tests__/api/api.test	getLatestHealthReport	POST	/api/health/report/latest	200	200	BIZ_OK
+__tests__/api/api.test	getReportList	POST	/api/health/report/list	200	200	BIZ_OK
+__tests__/api/api.test	createReportSurvey	POST	/api/health/survey/create	200	500	BIZ_FAIL
+__tests__/api/api.test	submitReportSurvey	POST	/api/health/survey/submit	200	500	BIZ_FAIL
+__tests__/api/api.test	generateInviteCard	POST	/api/invite-card/generate	200	500	BIZ_FAIL
+__tests__/api/api.test	verifyInviteCard	POST	/api/invite-card/verify	200	500	BIZ_FAIL
+__tests__/api/api.test	bindReferral	POST	/api/invite/bind	200	500	BIZ_FAIL
+__tests__/api/api.test	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+__tests__/api/api.test	getMembershipLevels	POST	/api/membership/levels	200	200	BIZ_OK
+__tests__/api/api.test	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+__tests__/api/api.test	createOrder	POST	/api/membership/orders	200	500	BIZ_FAIL
+__tests__/api/api.test	getMiniGameByCode	POST	/api/mini-game/1	200	500	BIZ_FAIL
+__tests__/api/api.test	completeMiniGame	POST	/api/mini-game/complete	200	400	BIZ_FAIL
+__tests__/api/api.test	getMiniGameList	POST	/api/mini-game/list	200	200	BIZ_OK
+__tests__/api/api.test	publishPackage	POST	/api/packages/1/publish	200	200	BIZ_OK
+__tests__/api/api.test	getPointsBalance	POST	/api/points/balance	200	200	BIZ_OK
+__tests__/api/api.test	getPointsLogs	POST	/api/points/logs	200	200	BIZ_OK
+__tests__/api/api.test	productCreate	POST	/api/product/create	200	500	BIZ_FAIL
+__tests__/api/api.test	productDetail	POST	/api/product/detail	200	500	BIZ_FAIL
+__tests__/api/api.test	productList	POST	/api/product/list	200	200	BIZ_OK
+__tests__/api/api.test	productOrderCreate	POST	/api/product/order/create	200	500	BIZ_FAIL
+__tests__/api/api.test	createReward	POST	/api/rewards	404	None	NOT_FOUND
+__tests__/api/api.test	exchangeReward	POST	/api/rewards/1/exchange	200	200	BIZ_OK
+__tests__/api/api.test	getWishlist	POST	/api/rewards/wishlist	200	200	BIZ_OK
+__tests__/api/api.test	getChildCompletionStats	POST	/api/stats/child-completion	200	200	BIZ_OK
+__tests__/api/api.test	getChildOverview	POST	/api/stats/child/overview	200	200	BIZ_OK
+__tests__/api/api.test	getSurveyStatus	POST	/api/survey/status	200	200	BIZ_OK
+__tests__/api/api.test	deleteTask	POST	/api/tasks/1	200	200	BIZ_OK
+__tests__/api/api.test	completeTask	POST	/api/tasks/1/complete	200	500	BIZ_FAIL
+__tests__/api/api.test	approveTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+__tests__/api/api.test	rejectTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+__tests__/api/api.test	reviewTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+__tests__/api/api.test	batchCompleteTasks	POST	/api/tasks/batch-complete	200	500	BIZ_FAIL
+__tests__/api/api.test	createTask	POST	/api/tasks/create	200	400	BIZ_FAIL
+__tests__/api/api.test	getTaskHistory	POST	/api/tasks/history	200	200	BIZ_OK
+__tests__/api/api.test	getPendingReviewTasks	POST	/api/tasks/pending-review	200	200	BIZ_OK
+__tests__/api/api.test	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+__tests__/api/api.test	getTodayTasksByCategory	POST	/api/tasks/today	200	200	BIZ_OK
+__tests__/api/api.test	getTodayParentTasks	POST	/api/tasks/today-parent	200	200	BIZ_OK
+__tests__/api/api.test	getUserInfo	POST	/api/user/info	200	200	BIZ_OK
+__tests__/api/api.test	joinFamily	POST	/api/user/join-family	404	None	NOT_FOUND
+__tests__/api/api.test	switchBackToParent	POST	/api/family/user/switch-back-to-parent	200	410	BIZ_FAIL
+__tests__/api/api.test	switchMode	POST	/api/family/user/switch-mode	200	410	BIZ_FAIL
+__tests__/api/api.test	switchToChild	POST	/api/family/user/switch-to-child	200	410	BIZ_FAIL
+__tests__/api/api.test	updateUserInfo	POST	/api/user/update	200	200	BIZ_OK
+__tests__/api/api.test	vendorApply	POST	/api/vendor/apply	200	200	BIZ_OK
+__tests__/api/api.test	vendorInfo	POST	/api/vendor/info	200	500	BIZ_FAIL
+__tests__/api/api.test	vendorStatus	POST	/api/vendor/status	200	200	BIZ_OK
+__tests__/api/api.test	getCheckinList	POST	/api/wealth/checkin/list	200	200	BIZ_OK
+__tests__/api/api.test	getInsuranceList	POST	/api/wealth/insurance/list	200	200	BIZ_OK
+__tests__/api/api.test	approveWishExchange	POST	/api/wishes/1/approve-exchange	200	500	BIZ_FAIL
+__tests__/api/api.test	setWishPrice	POST	/api/wishes/1/price	404	None	NOT_FOUND
+__tests__/api/api.test	createWish	POST	/api/wishes/create	200	500	BIZ_FAIL
+__tests__/api/api.test	getWishes	POST	/api/wishes/list	200	500	BIZ_FAIL
+__tests__/api/api.test	getPendingWishes	POST	/api/wishes/pending	200	200	BIZ_OK
+__tests__/api/api.test	applyWithdrawal	POST	/api/withdrawal/apply	200	500	BIZ_FAIL
+__tests__/store/store.test	switchRole	POST	/api/auth/switch-role	200	200	BIZ_OK
+components/DimensionActivities	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+components/DimensionActivities	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+components/DimensionProducts	getDimensionProducts	POST	/api/recommend/dimension-products	200	200	BIZ_OK
+components/DimensionTasks	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+components/MemberSelector	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+components/MemberSelector	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+components/MemberSelector	getPairwiseRelationships	POST	/api/family/relationship/pairwise	200	500	BIZ_FAIL
+components/MemberSelector	createFamily	POST	/api/family/user/create-family	200	200	BIZ_OK
+components/OnboardingGuide	getGuideConfig	POST	/api/guide-config/current	200	500	BIZ_FAIL
+components/OnboardingProgressBar	getOnboardingProgress	POST	/api/onboarding/progress	200	200	BIZ_OK
+components/RelatedContent	getContentRelated	POST	/api/content/related-items	200	500	BIZ_FAIL
+components/daily-task-card	getDailyTaskOverview	POST	/api/daily-task/overview	200	200	BIZ_OK
+components/login-sheet	wechatPhoneLogin	POST	/api/auth/wechat-phone-login	200	500	BIZ_FAIL
+components/share-mixin	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/achievement/index	getChildBadges	POST	/api/badges/child/list	200	200	BIZ_OK
+pages/action-detail/components/PearlDiagram	addPearlInteraction	POST	/api/pearl/interaction/add	200	500	BIZ_FAIL
+pages/action-detail/components/PearlDiagram	updatePearlPriority	POST	/api/pearl/item/update-priority	200	500	BIZ_FAIL
+pages/action-detail/contact-detail	deleteContact	POST	/api/contact/delete	200	500	BIZ_FAIL
+pages/action-detail/contact-detail	getContactDetail	POST	/api/contact/detail	200	500	BIZ_FAIL
+pages/action-detail/contact-detail	recordContactInteraction	POST	/api/contact/interaction	200	500	BIZ_FAIL
+pages/action-detail/contact-detail	updateContact	POST	/api/contact/update	200	500	BIZ_FAIL
+pages/action-detail/index	getAbilityMap	POST	/api/ability/map	200	200	BIZ_OK
+pages/action-detail/index	getVisibleSections	POST	/api/content-sections/visible	200	500	BIZ_FAIL
+pages/action-detail/index	getRadarData	POST	/api/dimension/radar-data	200	200	BIZ_OK
+pages/action-detail/index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/action-detail/index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/action-detail/index	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/action-detail/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/action-detail/index	getOctopusAnalysisSummary	POST	/api/octopus/analysis/summary	200	200	BIZ_OK
+pages/action-detail/index	getOctopusEffectKeyPersons	POST	/api/octopus/effect/key-persons	200	500	BIZ_FAIL
+pages/action-detail/index	getOctopusEffects	POST	/api/octopus/effect/list	200	200	BIZ_OK
+pages/action-detail/index	deletePearlResource	POST	/api/pearl/item/delete	200	500	BIZ_FAIL
+pages/action-detail/index	getPearlReminders	POST	/api/pearl/reminder/list	200	200	BIZ_OK
+pages/action-detail/index	getPearlResources	POST	/api/pearl/resources	200	200	BIZ_OK
+pages/action-detail/interaction-log	addInteraction	POST	/api/family/interaction/add	200	500	BIZ_FAIL
+pages/action-detail/interaction-log	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/action-detail/interaction-log	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/action-detail/member-action-detail	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/action-detail/member-action-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/action-detail/octopus-add-effect	addOctopusEffect	POST	/api/octopus/effect/add	200	200	BIZ_OK
+pages/action-detail/octopus-add-effect	bindOctopusKeyPersonSystemUser	POST	/api/octopus/key-person/bind-system-user	200	500	BIZ_FAIL
+pages/action-detail/octopus-add-effect	getOctopusKeyPersons	POST	/api/octopus/key-person/list	200	200	BIZ_OK
+pages/action-detail/octopus-add-effect	matchOctopusKeyPersonByPhone	POST	/api/octopus/key-person/match-by-phone	200	500	BIZ_FAIL
+pages/action-detail/octopus-add-key-person	addOctopusKeyPerson	POST	/api/octopus/key-person/add	200	500	BIZ_FAIL
+pages/action-detail/octopus-add-key-person	getOctopusKeyPersons	POST	/api/octopus/key-person/list	200	200	BIZ_OK
+pages/action-detail/octopus-effects-list	deleteOctopusEffect	POST	/api/octopus/effect/delete	200	500	BIZ_FAIL
+pages/action-detail/octopus-effects-list	getOctopusEffects	POST	/api/octopus/effect/list	200	200	BIZ_OK
+pages/action-detail/pearl-add-resource	getContactList	POST	/api/contact/list	200	200	BIZ_OK
+pages/action-detail/pearl-add-resource	getConnectionTypes	POST	/api/pearl/connection-types	200	200	BIZ_OK
+pages/action-detail/pearl-add-resource	addPearlResource	POST	/api/pearl/item/add	200	500	BIZ_FAIL
+pages/action-detail/relationship-questionnaire	generateQuestionnaire	POST	/api/family/questionnaire/generate	200	500	BIZ_FAIL
+pages/action-detail/relationship-questionnaire	submitQuestionnaire	POST	/api/family/questionnaire/submit	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	cancelActivityRegistration	POST	/api/activity/cancel-registration	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	activityCheckin	POST	/api/activity/checkin	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	getActivityDetail	POST	/api/activity/detail	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	getMyActivityFeedback	POST	/api/activity/feedback/my	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	submitActivityFeedback	POST	/api/activity/feedback/submit	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	createActivityOrder	POST	/api/activity/order/create	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	getActivityRegistrationRoster	POST	/api/activity/registration-roster	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/activity/activity-detail/activity-detail	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/activity/activity-detail/activity-detail	getPosterTemplates	POST	/api/poster-template/list	200	200	BIZ_OK
+pages/activity/activity-detail/activity-detail	getShareQrCode	POST	/api/share/qrcode	200	500	BIZ_FAIL
+pages/activity/activity-detail/activity-detail	backfillProfile	POST	/api/user/profile/backfill	200	500	BIZ_FAIL
+pages/activity/create	adminCreateActivity	POST	/api/activity/create	200	400	BIZ_FAIL
+pages/activity/create	getActivityDetail	POST	/api/activity/detail	200	500	BIZ_FAIL
+pages/activity/create	adminPublishActivity	POST	/api/activity/publish	200	500	BIZ_FAIL
+pages/activity/create	submitActivityForReview	POST	/api/activity/submit-review	200	500	BIZ_FAIL
+pages/activity/create	adminUpdateActivity	POST	/api/activity/update	200	500	BIZ_FAIL
+pages/activity/create	getPosterTemplates	POST	/api/poster-template/list	200	200	BIZ_OK
+pages/activity/index	cancelActivityRegistration	POST	/api/activity/cancel-registration	200	500	BIZ_FAIL
+pages/activity/index	activityCheckin	POST	/api/activity/checkin	200	500	BIZ_FAIL
+pages/activity/index	adminEndActivity	POST	/api/activity/end	200	500	BIZ_FAIL
+pages/activity/index	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/activity/index	getMyActivityRegistrations	POST	/api/activity/my-registrations	200	200	BIZ_OK
+pages/activity/index	adminPublishActivity	POST	/api/activity/publish	200	500	BIZ_FAIL
+pages/activity/index	submitActivityForReview	POST	/api/activity/submit-review	200	500	BIZ_FAIL
+pages/activity/index	adminListMyActivities	POST	/api/admin/activity/list	200	200	BIZ_OK
+pages/activity/index	adminWithdrawActivity	POST	/api/admin/activity/withdraw	200	500	BIZ_FAIL
+pages/activity/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/activity/index	vendorStatus	POST	/api/vendor/status	200	200	BIZ_OK
+pages/activity/order-pay/order-pay	handleActivityOrderSuccess	POST	/api/activity/order/handlePaymentSuccess	200	500	BIZ_FAIL
+pages/activity/order-pay/order-pay	payActivityOrder	POST	/api/activity/order/pay	200	500	BIZ_FAIL
+pages/ai/chat	aiSendHealthButlerMessage	POST	/api/ai/butler/send	200	500	BIZ_FAIL
+pages/ai/chat	aiGetConversations	POST	/api/ai/chat/conversations	200	200	BIZ_OK
+pages/ai/chat	aiGetMessages	POST	/api/ai/chat/messages	200	500	BIZ_FAIL
+pages/ai/chat	aiSendHealthCoachMessage	POST	/api/ai/health-coach/send	200	500	BIZ_FAIL
+pages/ai/chat	aiSendNutritionMessage	POST	/api/ai/nutrition/send	200	500	BIZ_FAIL
+pages/ai/chat	sttTranscribe	POST	/api/ai/transcribe	200	400	BIZ_FAIL
+pages/ai/chat	getAllQuotaStatus	POST	/api/basic-quota/status/all	200	200	BIZ_OK
+pages/ai/chat	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/ai/chat	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/article-center/article-detail	getArticleAudio	POST	/api/articles/audio	200	500	BIZ_FAIL
+pages/article-center/article-detail	completeArticleRead	POST	/api/articles/complete-read	200	200	BIZ_OK
+pages/article-center/article-detail	getArticleDetail	POST	/api/articles/detail	200	403	BIZ_FAIL
+pages/article-center/article-detail	generateQuiz	POST	/api/articles/quiz/generate	200	500	BIZ_FAIL
+pages/article-center/article-detail	submitQuiz	POST	/api/articles/quiz/submit	200	500	BIZ_FAIL
+pages/article-center/article-detail	reportReadingTime	POST	/api/articles/report-reading-time	200	500	BIZ_FAIL
+pages/article-center/article-detail	getShareQrCode	POST	/api/share/qrcode	200	500	BIZ_FAIL
+pages/article-center/article-detail	completeTask	POST	/api/tasks/1/complete	200	500	BIZ_FAIL
+pages/article-center/article-edit	publishArticle	POST	/api/articles/publish	200	500	BIZ_FAIL
+pages/article-center/index	getFeaturedArticles	POST	/api/articles/featured	200	200	BIZ_OK
+pages/article-center/index	getArticleList	POST	/api/articles/list	200	200	BIZ_OK
+pages/article-center/my-posts	getMyPosts	POST	/api/articles/my-posts	200	200	BIZ_OK
+pages/assessment-plan/detail	getMyAssessmentPlans	POST	/api/dan-assessment/result/plans/list	200	200	BIZ_OK
+pages/assessment-plan/list	getMyAssessmentPlans	POST	/api/dan-assessment/result/plans/list	200	200	BIZ_OK
+pages/assessment/apply	createAssessmentAppointmentWithQuota	POST	/api/assessment/appointment/create	200	500	BIZ_FAIL
+pages/assessment/apply	getAssessmentQuotas	POST	/api/assessment/quota/my-list	200	200	BIZ_OK
+pages/assessment/apply	validateInviteCode	POST	/api/guide/invite-code/validate	200	400	BIZ_FAIL
+pages/assessment/apply	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/assessment/apply	getAvailableGuides	POST	/api/package/available-guides	200	400	BIZ_FAIL
+pages/assessment/purchase	createAssessmentOrder	POST	/api/dan-assessment/order/create	200	400	BIZ_FAIL
+pages/assessment/purchase	getAssessmentOrderDetail	POST	/api/dan-assessment/order/detail	200	400	BIZ_FAIL
+pages/assessment/purchase	validateInviteCode	POST	/api/guide/invite-code/validate	200	400	BIZ_FAIL
+pages/assessment/purchase	getAvailableGuides	POST	/api/package/available-guides	200	400	BIZ_FAIL
+pages/assessment/quota	getAssessmentQuotas	POST	/api/assessment/quota/my-list	200	200	BIZ_OK
+pages/assessment/results	getChildAssessmentResults	POST	/api/dan-assessment/child-results	200	200	BIZ_OK
+pages/assessment/results	getMyAssessmentResults	POST	/api/dan-assessment/my-results	200	200	BIZ_OK
+pages/assessment/upload-report	uploadAssessmentReport	POST	/api/dan-assessment/result/upload	200	400	BIZ_FAIL
+pages/body-detail/dimension-detail	getDimensionHistory	POST	/api/dimension/history	200	500	BIZ_FAIL
+pages/body-detail/dimension-detail	getDimensionOverview	POST	/api/dimension/overview	200	200	BIZ_OK
+pages/body-detail/dimension-questionnaire	submitAnswers	POST	/api/articles/submit-answers	200	500	BIZ_FAIL
+pages/body-detail/dimension-questionnaire	submitDimensionQuestionnaire	POST	/api/dimension/questionnaire	200	500	BIZ_FAIL
+pages/body-detail/health-dimensions	getDimensionOverview	POST	/api/dimension/overview	200	200	BIZ_OK
+pages/body-detail/health-dimensions	uploadDimensionScore	POST	/api/dimension/upload	200	500	BIZ_FAIL
+pages/body-detail/health-report	getDeficiencyAnalysis	POST	/api/health/nutrition/deficiency	200	500	BIZ_FAIL
+pages/body-detail/index	getVisibleSections	POST	/api/content-sections/visible	200	500	BIZ_FAIL
+pages/body-detail/index	getDimensionOverview	POST	/api/dimension/overview	200	200	BIZ_OK
+pages/body-detail/index	getRadarData	POST	/api/dimension/radar-data	200	200	BIZ_OK
+pages/body-detail/index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/body-detail/index	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/body-detail/index	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+pages/body-detail/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/body-detail/index	getGutFloraIndicators	POST	/api/health/gut-flora	200	200	BIZ_OK
+pages/body-detail/index	getLatestIndicators	POST	/api/health/indicators	200	500	BIZ_FAIL
+pages/body-detail/index	getBodyAbnormalIndicators	POST	/api/health/report/body-abnormal	200	200	BIZ_OK
+pages/body-detail/member-body-detail	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/body-detail/member-body-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/butler/apply	butlerApply	POST	/api/butler/apply	200	200	BIZ_OK
+pages/butler/select	getAvailableButlers	POST	/api/butler/available-list	200	200	BIZ_OK
+pages/butler/select	getMyButler	POST	/api/butler/my-butler	200	200	BIZ_OK
+pages/butler/select	selectButler	POST	/api/butler/select	200	500	BIZ_FAIL
+pages/child/rewards	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+pages/child/rewards	getPointsBalance	POST	/api/points/balance	200	200	BIZ_OK
+pages/child/rewards	getWishlist	POST	/api/rewards/wishlist	200	200	BIZ_OK
+pages/child/rewards	switchBackToParent	POST	/api/family/user/switch-back-to-parent	200	410	BIZ_FAIL
+pages/child/tasks	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+pages/child/tasks	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/child/tasks	switchBackToParent	POST	/api/family/user/switch-back-to-parent	200	410	BIZ_FAIL
+pages/cognitive-hall	getCognitiveChildScores	POST	/api/cognitive/child	200	200	BIZ_OK
+pages/cognitive-hall	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/cognitive-test/language-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/cognitive-test/logic-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/cognitive-test/memory-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/cognitive-test/perception-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/cognitive-test/spatial-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/cognitive-test/speed-test	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/dan-assessment/comparison	compareDanReports	POST	/api/dan-report/compare	200	500	BIZ_FAIL
+pages/dan-assessment/comparison	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/diet/index	addDietIngredient	POST	/api/diet/ingredients/add	200	500	BIZ_FAIL
+pages/diet/index	refreshDietIngredients	POST	/api/diet/ingredients/recommend	200	500	BIZ_FAIL
+pages/diet/index	removeDietIngredient	POST	/api/diet/ingredients/remove	200	500	BIZ_FAIL
+pages/diet/index	searchDietFoods	POST	/api/diet/ingredients/search	200	200	BIZ_OK
+pages/diet/index	getDietIngredients	POST	/api/diet/ingredients/suggest	200	500	BIZ_FAIL
+pages/diet/index	getMealConfig	POST	/api/diet/meals/config	200	200	BIZ_OK
+pages/diet/index	generateDietRecommendation	POST	/api/diet/recommendation/generate	200	500	BIZ_FAIL
+pages/diet/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/diet/meal-config	getMealConfig	POST	/api/diet/meals/config	200	200	BIZ_OK
+pages/diet/meal-config	saveMealConfig	POST	/api/diet/meals/config/save	200	400	BIZ_FAIL
+pages/diet/preferences	getDietPreferences	POST	/api/diet/preferences/current-member	200	200	BIZ_OK
+pages/diet/preferences	saveDietPreferences	POST	/api/diet/preferences/save	200	200	BIZ_OK
+pages/diet/recommendation	completeDietRecommendation	POST	/api/diet/recommendation/complete	200	200	BIZ_OK
+pages/diet/recommendation	generateDietRecommendation	POST	/api/diet/recommendation/generate	200	500	BIZ_FAIL
+pages/diet/recommendation	regenerateDietRecommendation	POST	/api/diet/recommendation/regenerate	200	200	BIZ_OK
+pages/diet/recommendation	getDietRecommendation	POST	/api/diet/recommendation/today	200	500	BIZ_FAIL
+pages/diet/record-detail	getDietDailyRecords	POST	/api/diet/record/daily	200	200	BIZ_OK
+pages/diet/records	getCautionFamilyMembers	POST	/api/food/recommendation/members	200	200	BIZ_OK
+pages/diet/records	getMealAlerts	POST	/api/health/meal/alerts	200	200	BIZ_OK
+pages/diet/records	getMealDaily	POST	/api/health/meal/daily	200	200	BIZ_OK
+pages/diet/records	getMealWeekly	POST	/api/health/meal/weekly	200	200	BIZ_OK
+pages/discover-detail/product-detail/product-detail	cartAdd	POST	/api/cart/add	200	500	BIZ_FAIL
+pages/discover-detail/product-detail/product-detail	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/discover-detail/product-detail/product-detail	productDetail	POST	/api/product/detail	200	500	BIZ_FAIL
+pages/discover-detail/product-detail/product-detail	productOrderPay	POST	/api/product/order/pay	200	500	BIZ_FAIL
+pages/discover-detail/product-detail/product-detail	productSpecMap	POST	/api/product/spec/map	200	200	BIZ_OK
+pages/discover-detail/product-detail/product-detail	getShareQrCode	POST	/api/share/qrcode	200	500	BIZ_FAIL
+pages/discover-detail/product-detail/product-detail	getSpecialPriceInfo	POST	/api/special-price/info	200	200	BIZ_OK
+pages/discover/circle-feed	addCircleComment	POST	/api/circle/comment/add	200	500	BIZ_FAIL
+pages/discover/circle-feed	getCircleComments	POST	/api/circle/comment/list	200	500	BIZ_FAIL
+pages/discover/circle-feed	getCircleFeed	POST	/api/circle/feed	200	500	BIZ_FAIL
+pages/discover/circle-feed	getCircleMembers	POST	/api/circle/members	200	500	BIZ_FAIL
+pages/discover/circle-feed	createCirclePost	POST	/api/circle/post/create	200	500	BIZ_FAIL
+pages/discover/circle-feed	deleteCirclePost	POST	/api/circle/post/delete	200	500	BIZ_FAIL
+pages/discover/circle-feed	toggleCircleLike	POST	/api/circle/post/like	200	500	BIZ_FAIL
+pages/discover/circles	approveCircleMember	POST	/api/circle/approve	200	500	BIZ_FAIL
+pages/discover/circles	discoverCircles	POST	/api/circle/discover	200	200	BIZ_OK
+pages/discover/circles	joinGeneralCircle	POST	/api/circle/join	200	500	BIZ_FAIL
+pages/discover/circles	leaveGeneralCircle	POST	/api/circle/leave	200	500	BIZ_FAIL
+pages/discover/circles	getMyCircles	POST	/api/circle/my-circles	200	500	BIZ_FAIL
+pages/discover/circles	getPendingCircleMembers	POST	/api/circle/pending-members	200	500	BIZ_FAIL
+pages/discover/circles	updateCircle	POST	/api/circle/update	200	500	BIZ_FAIL
+pages/discover/circles	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/discover/create-circle	createGeneralCircle	POST	/api/circle/create	200	500	BIZ_FAIL
+pages/discover/index	getFeaturedArticles	POST	/api/articles/featured	200	200	BIZ_OK
+pages/discover/index	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/discover/index	productList	POST	/api/product/list	200	200	BIZ_OK
+pages/energy/detail	getEnergyLogs	POST	/api/energy/logs	200	200	BIZ_OK
+pages/energy/index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/energy/index	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/energy/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/family/add-member	checkPhone	POST	/api/auth/check-phone	200	500	BIZ_FAIL
+pages/family/add-member	recordConsent	POST	/api/consent/record	200	500	BIZ_FAIL
+pages/family/add-member	addFamilyMember	POST	/api/family/member/add	200	500	BIZ_FAIL
+pages/family/add-member	updateFamilyMember	POST	/api/family/member/update	200	500	BIZ_FAIL
+pages/family/manual-score-entry	submitManualScore	POST	/api/family/manual-score/submit	200	500	BIZ_FAIL
+pages/family/manual-score-entry	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/family/mbti-entry	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/family/mbti-profile	getMbtiProfile	POST	/api/family/mbti/profile	200	500	BIZ_FAIL
+pages/family/mbti-result	getMbtiLatest	POST	/api/family/mbti/latest	200	500	BIZ_FAIL
+pages/family/mbti-test	getMbtiQuestions	POST	/api/family/mbti/questions	200	500	BIZ_FAIL
+pages/family/mbti-test	submitMbti	POST	/api/family/mbti/submit	200	500	BIZ_FAIL
+pages/family/self-check	submitSelfCheck	POST	/api/family/self-check/submit	200	500	BIZ_FAIL
+pages/family/self-check-ai	submitSelfCheck	POST	/api/family/self-check/submit	200	500	BIZ_FAIL
+pages/family/self-check-entry	ignoreSelfCheck	POST	/api/family/self-check/ignore	200	200	BIZ_OK
+pages/family/self-check-entry	getSelfCheckStatus	POST	/api/family/self-check/status	200	200	BIZ_OK
+pages/family/self-check-entry	getSelfCheckTrendAnalysis	POST	/api/family/self-check/trend-analysis	200	200	BIZ_OK
+pages/family/self-check-result	generateSelfCheckPlan	POST	/api/family/self-check/generate-plan	200	500	BIZ_FAIL
+pages/family/self-check-result	getSelfCheckHistory	POST	/api/family/self-check/history	200	200	BIZ_OK
+pages/family/self-check-result	getSelfCheckLatest	POST	/api/family/self-check/latest	200	200	BIZ_OK
+pages/family/self-check-result	microActionComplete	POST	/api/micro-action/complete	200	500	BIZ_FAIL
+pages/family/self-check-result	microActionToday	POST	/api/micro-action/today	200	200	BIZ_OK
+pages/games/1a2b	completeMiniGame	POST	/api/mini-game/complete	200	400	BIZ_FAIL
+pages/games/list	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/games/list	getMiniGameList	POST	/api/mini-game/list	200	200	BIZ_OK
+pages/games/records	getGameHistory	POST	/api/game/history	200	200	BIZ_OK
+pages/games/schulte	completeMiniGame	POST	/api/mini-game/complete	200	400	BIZ_FAIL
+pages/games/stats	getGameBestScores	POST	/api/game/best	200	200	BIZ_OK
+pages/games/stats	getGameLeaderboard	POST	/api/game/leaderboard	200	200	BIZ_OK
+pages/games/stats	getGameStats	POST	/api/game/stats	200	200	BIZ_OK
+pages/games/sudoku	completeMiniGame	POST	/api/mini-game/complete	200	400	BIZ_FAIL
+pages/growth-main/index	getFoodCautionList	POST	/api/food/recommendation/caution	200	200	BIZ_OK
+pages/growth-main/index	getGrowthRecommendations	POST	/api/growth/recommendations	200	200	BIZ_OK
+pages/growth-main/index	healthCheckinList	POST	/api/health/checkin/list	200	200	BIZ_OK
+pages/growth-main/index	getExerciseRecords	POST	/api/health/exercise/list	200	200	BIZ_OK
+pages/growth-main/index	getHealthMealList	POST	/api/health/meal/list	200	200	BIZ_OK
+pages/growth-main/index	getSleepRecords	POST	/api/health/sleep/list	200	200	BIZ_OK
+pages/growth-main/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/growth-main/index	getEmotionCheckinList	POST	/api/mind/checkin/list	200	200	BIZ_OK
+pages/growth-main/index	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/growth-main/index	getCheckinList	POST	/api/wealth/checkin/list	200	200	BIZ_OK
+pages/growth/caution-detail	getFoodCautionList	POST	/api/food/recommendation/caution	200	200	BIZ_OK
+pages/growth/caution-detail	getCautionFamilyMembers	POST	/api/food/recommendation/members	200	200	BIZ_OK
+pages/growth/caution-detail	getFoodCautionTrend	POST	/api/food/recommendation/trend	200	200	BIZ_OK
+pages/growth/caution-detail	getKnowledgeSection	POST	/api/health/knowledge/v3/section	200	200	BIZ_OK
+pages/growth/challenge-progress	getChallengeProgress	POST	/api/purchase/challenge/progress	200	200	BIZ_OK
+pages/growth/create	createGrowthRecord	POST	/api/growth/record/create	200	500	BIZ_FAIL
+pages/growth/create	createGrowthRecord	POST	/api/growth/record/create-with-order	200	500	BIZ_FAIL
+pages/growth/diet-checkin	sttTranscribe	POST	/api/ai/transcribe	200	400	BIZ_FAIL
+pages/growth/diet-checkin	getAllQuotaStatus	POST	/api/basic-quota/status/all	200	200	BIZ_OK
+pages/growth/exercise-checkin	sttTranscribe	POST	/api/ai/transcribe	200	400	BIZ_FAIL
+pages/growth/supplement	createGrowthSupplement	POST	/api/growth/record/supplement	200	500	BIZ_FAIL
+pages/growth/supplement	uploadAndParseReport	POST	/api/growth/record/upload-and-parse	200	400	BIZ_FAIL
+pages/growth/upload	createGrowthRecordFromUpload	POST	/api/growth/record/create-from-upload	200	500	BIZ_FAIL
+pages/growth/upload	uploadAndParseReport	POST	/api/growth/record/upload-and-parse	200	400	BIZ_FAIL
+pages/growth/upload	productList	POST	/api/product/list	200	200	BIZ_OK
+pages/guide/activities/detail	createActivity	POST	/api/guide/activities/create	200	200	BIZ_OK
+pages/guide/activities/detail	getGuideActivityDetail	POST	/api/guide/activities/detail	200	500	BIZ_FAIL
+pages/guide/activities/detail	publishActivity	POST	/api/guide/activities/publish	200	500	BIZ_FAIL
+pages/guide/activities/detail	updateActivity	POST	/api/guide/activities/update	200	500	BIZ_FAIL
+pages/guide/activities/index	cancelActivity	POST	/api/guide/activities/cancel	200	500	BIZ_FAIL
+pages/guide/activities/index	deleteActivity	POST	/api/guide/activities/delete	200	500	BIZ_FAIL
+pages/guide/activities/index	getGuideActivityList	POST	/api/guide/activities/list	200	200	BIZ_OK
+pages/guide/activities/index	publishActivity	POST	/api/guide/activities/publish	200	500	BIZ_FAIL
+pages/guide/bind/invite	generateQrCodeFromText	POST	/api/common/qrcode	200	500	BIZ_FAIL
+pages/guide/bind/invite	confirmBind	POST	/api/guide/bind/confirm	404	None	NOT_FOUND
+pages/guide/bind/invite	generateBindInvite	POST	/api/guide/bind/invite	200	200	BIZ_OK
+pages/guide/hierarchy/index	getAllChildGuides	POST	/api/guide/all-child-guides	200	200	BIZ_OK
+pages/guide/hierarchy/index	getChildGuides	POST	/api/guide/child-guides	200	200	BIZ_OK
+pages/guide/hierarchy/index	getParentGuide	POST	/api/guide/parent-guide	200	200	BIZ_OK
+pages/guide/packages/create	createPackage	POST	/api/packages	404	None	NOT_FOUND
+pages/guide/packages/detail	addPackageItem	POST	/api/packages/1/items	200	400	BIZ_FAIL
+pages/guide/packages/index	publishPackage	POST	/api/packages/1/publish	200	200	BIZ_OK
+pages/guide/packages/index	submitPackageForReview	POST	/api/packages/1/submit	200	200	BIZ_OK
+pages/guide/register/index	validateInviteCode	POST	/api/guide/invite-code/validate	200	400	BIZ_FAIL
+pages/guide/register/index	registerGuide	POST	/api/guide/register	200	500	BIZ_FAIL
+pages/health-main/index	getFeaturedArticles	POST	/api/articles/featured	200	200	BIZ_OK
+pages/health-main/index	getCognitiveChildScores	POST	/api/cognitive/child	200	200	BIZ_OK
+pages/health-main/index	getCognitiveFamilyScores	POST	/api/cognitive/family	200	200	BIZ_OK
+pages/health-main/index	getDimensionOverview	POST	/api/dimension/overview	200	200	BIZ_OK
+pages/health-main/index	getEmiReport	POST	/api/emireport/latest	200	200	BIZ_OK
+pages/health-main/index	getWealthDetail	POST	/api/energy/wealth-detail	200	500	BIZ_FAIL
+pages/health-main/index	getRelationshipScores	POST	/api/family/relationship/scores	200	200	BIZ_OK
+pages/health-main/index	getHealthPlanList	POST	/api/health/plan/list	200	200	BIZ_OK
+pages/health-main/index	getReportList	POST	/api/health/report/list	200	200	BIZ_OK
+pages/health-main/index	getSurveyStatus	POST	/api/survey/status	200	200	BIZ_OK
+pages/health/bodyfat-confirm	saveBodyFatMetrics	POST	/api/health/report/bodyfat-save	404	None	NOT_FOUND
+pages/health/challenge-manage	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/challenge-manage	createChallenge	POST	/api/health/challenge/create	200	500	BIZ_FAIL
+pages/health/challenge-manage	getChallengeHistory	POST	/api/health/challenge/history	200	200	BIZ_OK
+pages/health/challenge-manage	getChallengeList	POST	/api/health/challenge/list	200	200	BIZ_OK
+pages/health/challenge-manage	respondChallenge	POST	/api/health/challenge/respond	200	500	BIZ_FAIL
+pages/health/challenge-manage	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/health/components/MemberChipPicker	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/components/feedback-popup	submitFeedback	POST	/api/health/feedback/submit	200	500	BIZ_FAIL
+pages/health/doa-index	getDoaOverview	POST	/api/doa/overview	200	200	BIZ_OK
+pages/health/doa-stage-create	createDoaStage	POST	/api/doa/stage/create	200	500	BIZ_FAIL
+pages/health/doa-stage-create	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/doa-stage-detail	cancelDoaStage	POST	/api/doa/stage/cancel	200	500	BIZ_FAIL
+pages/health/doa-stage-detail	getDoaStageDetail	POST	/api/doa/stage/detail	200	500	BIZ_FAIL
+pages/health/doa-week-edit	getDoaStageDetail	POST	/api/doa/stage/detail	200	500	BIZ_FAIL
+pages/health/doa-week-edit	submitDoaWeekPlan	POST	/api/doa/week/plan	200	500	BIZ_FAIL
+pages/health/doa-week-edit	submitDoaWeekReview	POST	/api/doa/week/review	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	addFamilyMember	POST	/api/family/member/add	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/gut-flora-detail	getFoodCautionList	POST	/api/food/recommendation/caution	200	200	BIZ_OK
+pages/health/gut-flora-detail	getHealthFoods	POST	/api/health/foods	200	200	BIZ_OK
+pages/health/gut-flora-detail	queryKnowledgeBase	POST	/api/health/knowledge/query	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	queryIndicatorKnowledge	POST	/api/health/knowledge/v3/indicator/query	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	confirmReportPreview	POST	/api/health/report/confirm	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	discardReportDraft	POST	/api/health/report/discard	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	editHealthReport	POST	/api/health/report/edit	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	parseReportDraft	POST	/api/health/report/parse	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	getIndicatorChangeRanking	POST	/api/indicator/change-ranking	200	500	BIZ_FAIL
+pages/health/gut-flora-detail	getGutFloraAnalysis	POST	/api/nutrition/beijing/analysis	200	500	BIZ_FAIL
+pages/health/gut-flora-foods-detail	getCautionFamilyMembers	POST	/api/food/recommendation/members	200	200	BIZ_OK
+pages/health/gut-flora-foods-detail	getFoodCautionTrend	POST	/api/food/recommendation/trend	200	200	BIZ_OK
+pages/health/gut-flora-foods-detail	getHealthFoods	POST	/api/health/foods	200	200	BIZ_OK
+pages/health/gut-flora-foods-detail	queryFoodKnowledge	POST	/api/health/knowledge/v3/food/query	200	500	BIZ_FAIL
+pages/health/gut-flora-foods-detail	editHealthReport	POST	/api/health/report/edit	200	500	BIZ_FAIL
+pages/health/gut-flora-risks-detail	queryKnowledgeBase	POST	/api/health/knowledge/query	200	500	BIZ_FAIL
+pages/health/gut-flora-risks-detail	queryDiseaseKnowledge	POST	/api/health/knowledge/unified/disease/query	200	500	BIZ_FAIL
+pages/health/gut-flora-risks-detail	queryIndicatorKnowledge	POST	/api/health/knowledge/v3/indicator/query	200	500	BIZ_FAIL
+pages/health/gut-flora-risks-detail	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+pages/health/gut-flora-risks-detail	editHealthReport	POST	/api/health/report/edit	200	500	BIZ_FAIL
+pages/health/gut-flora-species-detail	queryKnowledgeBase	POST	/api/health/knowledge/query	200	500	BIZ_FAIL
+pages/health/gut-flora-species-detail	queryBacteriaKnowledge	POST	/api/health/knowledge/v3/bacteria/query	200	500	BIZ_FAIL
+pages/health/gut-flora-species-detail	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+pages/health/gut-flora-species-detail	editHealthReport	POST	/api/health/report/edit	200	500	BIZ_FAIL
+pages/health/health-plan-summary	getDietPreferences	POST	/api/diet/preferences/current-member	200	200	BIZ_OK
+pages/health/health-plan-summary	saveDietPreferences	POST	/api/diet/preferences/save	200	200	BIZ_OK
+pages/health/health-plan-summary	getHealthStatus	POST	/api/health-status/get	200	200	BIZ_OK
+pages/health/health-plan-summary	saveHealthStatus	POST	/api/health-status/save	200	500	BIZ_FAIL
+pages/health/health-plan-summary	saveHealthSignature	POST	/api/health-status/signature	200	500	BIZ_FAIL
+pages/health/health-plan-summary	confirmPlan	POST	/api/health/plan/confirm	200	500	BIZ_FAIL
+pages/health/health-plan-summary	getHealthPlanDetail	POST	/api/health/plan/detail	200	500	BIZ_FAIL
+pages/health/health-plan-summary	generateHealthPlan	POST	/api/health/plan/generate	200	4001	BIZ_FAIL
+pages/health/health-plan-summary	regenerateSection	POST	/api/health/plan/regenerate-section	200	500	BIZ_FAIL
+pages/health/health-plan-summary	saveHealthPlan	POST	/api/health/plan/save	200	500	BIZ_FAIL
+pages/health/health-plan-summary	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/health/health-status-form	getHealthStatus	POST	/api/health-status/get	200	200	BIZ_OK
+pages/health/health-status-form	saveHealthStatus	POST	/api/health-status/save	200	500	BIZ_FAIL
+pages/health/health-survey	getDietPreferences	POST	/api/diet/preferences/current-member	200	200	BIZ_OK
+pages/health/health-survey	saveDietPreferences	POST	/api/diet/preferences/save	200	200	BIZ_OK
+pages/health/health-survey	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/health-survey	getHealthStatus	POST	/api/health-status/get	200	200	BIZ_OK
+pages/health/health-survey	saveHealthStatus	POST	/api/health-status/save	200	500	BIZ_FAIL
+pages/health/health-survey	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/health/indicator-curve	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/indicator-curve	getIndicatorChangeRanking	POST	/api/indicator/change-ranking	200	500	BIZ_FAIL
+pages/health/indicator-curve	getIndicatorTrend	POST	/api/indicator/trend	200	500	BIZ_FAIL
+pages/health/indicator-quicklook	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/indicator-quicklook	getIndicatorQuickLookup	POST	/api/indicator/quick-lookup	200	500	BIZ_FAIL
+pages/health/my-feedback	getMyReportFeedbacks	POST	/api/health/feedback/list	200	200	BIZ_OK
+pages/health/nutrition-profile	getDeficiencyAnalysis	POST	/api/health/nutrition/deficiency	200	500	BIZ_FAIL
+pages/health/nutrition-profile	getChildNutritionProfile	POST	/api/health/nutrition/profile	200	500	BIZ_FAIL
+pages/health/physical-exam-detail	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+pages/health/plan-list	deleteHealthPlan	POST	/api/health/plan/delete	200	500	BIZ_FAIL
+pages/health/plan-list	getHealthPlanList	POST	/api/health/plan/list	200	200	BIZ_OK
+pages/health/report-confirm	addFamilyMember	POST	/api/family/member/add	200	500	BIZ_FAIL
+pages/health/report-confirm	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/report-confirm	parseReportDraft	POST	/api/health/report/parse	200	500	BIZ_FAIL
+pages/health/report-detail	addFamilyMember	POST	/api/family/member/add	200	500	BIZ_FAIL
+pages/health/report-detail	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/report-detail	editHealthReport	POST	/api/health/report/edit	200	500	BIZ_FAIL
+pages/health/report-detail	parseReportDraft	POST	/api/health/report/parse	200	500	BIZ_FAIL
+pages/health/report-detail	getReportPayload	POST	/api/health/report/payload	200	500	BIZ_FAIL
+pages/health/report-list	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/report-list	getCollectingReports	POST	/api/health/report/collecting-list	200	200	BIZ_OK
+pages/health/report-list	deleteReport	POST	/api/health/report/delete	200	500	BIZ_FAIL
+pages/health/report-list	getReportList	POST	/api/health/report/list	200	200	BIZ_OK
+pages/health/report-list	reassignReport	POST	/api/health/report/reassign	200	500	BIZ_FAIL
+pages/health/report-list	approveReportTransfer	POST	/api/health/report/transfer/approve	200	500	BIZ_FAIL
+pages/health/report-list	denyReportTransfer	POST	/api/health/report/transfer/deny	200	500	BIZ_FAIL
+pages/health/report-list	getReportTransferList	POST	/api/health/report/transfer/list	200	200	BIZ_OK
+pages/health/report-survey	createReportSurvey	POST	/api/health/survey/create	200	500	BIZ_FAIL
+pages/health/report-survey	submitReportSurvey	POST	/api/health/survey/submit	200	500	BIZ_FAIL
+pages/health/report-survey	getSurveyStatus	POST	/api/survey/status	200	200	BIZ_OK
+pages/health/report-upload	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/health/report-upload	getReportCollectStatus	POST	/api/health/report/collect/status	200	500	BIZ_FAIL
+pages/health/report-upload	requestReportTransfer	POST	/api/health/report/transfer/request	200	500	BIZ_FAIL
+pages/health/report-upload	uploadReportOnly	POST	/api/health/report/upload-only	200	400	BIZ_FAIL
+pages/health/survey-history	getSurveyHistory	POST	/api/survey/history	200	200	BIZ_OK
+pages/health/survey-history	getActiveTemplates	POST	/api/survey/template/active	200	200	BIZ_OK
+pages/health/survey-questionnaire	submitSurvey	POST	/api/survey/submit	200	400	BIZ_FAIL
+pages/health/survey-questionnaire	getActiveTemplates	POST	/api/survey/template/active	200	200	BIZ_OK
+pages/health/teacher-service	getAvailableTeachers	POST	/api/health-plan/available-teachers	404	None	NOT_FOUND
+pages/home-pages/child-index	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/home-pages/child-index	getEnergyLogs	POST	/api/energy/logs	200	200	BIZ_OK
+pages/home-pages/child-index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/home-pages/child-index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/home-pages/child-index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/home-pages/child-index	getGuideConfig	POST	/api/guide-config/current	200	500	BIZ_FAIL
+pages/home-pages/child-index	consumeGuidePopup	POST	/api/guide/popup/consume	200	500	BIZ_FAIL
+pages/home-pages/child-index	getGuidePopupList	POST	/api/guide/popup/list	200	200	BIZ_OK
+pages/home-pages/child-index	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/home-pages/child-index	getUnlockStatus	POST	/api/unlock/status	200	200	BIZ_OK
+pages/home-pages/child-index	switchMode	POST	/api/family/user/switch-mode	200	410	BIZ_FAIL
+pages/home-pages/components/AdBanner	getHomeBanners	POST	/api/home-banner/list	200	200	BIZ_OK
+pages/home-pages/components/ContactImport	importPhoneContact	POST	/api/contact/import-phone	200	400	BIZ_FAIL
+pages/home-pages/components/DailySummary	markFeedbackRead	POST	/api/feedback/read	200	500	BIZ_FAIL
+pages/home-pages/components/DailySummary	getTodayFeedback	POST	/api/feedback/today	200	200	BIZ_OK
+pages/home-pages/components/MicroActionCard	microActionComplete	POST	/api/micro-action/complete	200	500	BIZ_FAIL
+pages/home-pages/components/MicroActionCard	microActionToday	POST	/api/micro-action/today	200	200	BIZ_OK
+pages/home-pages/member-home-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/home-pages/parent-index	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/home-pages/parent-index	getFeaturedArticles	POST	/api/articles/featured	200	200	BIZ_OK
+pages/home-pages/parent-index	getContactList	POST	/api/contact/list	200	200	BIZ_OK
+pages/home-pages/parent-index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/home-pages/parent-index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/home-pages/parent-index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/home-pages/parent-index	switchToFamilyMember	POST	/api/family/member/switch	200	500	BIZ_FAIL
+pages/home-pages/parent-index	getSelfCheckStatus	POST	/api/family/self-check/status	200	200	BIZ_OK
+pages/home-pages/parent-index	dismissAlert	POST	/api/health/alert/dismiss	200	500	BIZ_FAIL
+pages/home-pages/parent-index	getActiveAlerts	POST	/api/health/alert/list	200	200	BIZ_OK
+pages/home-pages/parent-index	getChallengeList	POST	/api/health/challenge/list	200	200	BIZ_OK
+pages/home-pages/parent-index	getCircleList	POST	/api/health/circle/list	200	200	BIZ_OK
+pages/home-pages/parent-index	getCircleRanking	POST	/api/health/circle/ranking	200	200	BIZ_OK
+pages/home-pages/parent-index	getFamilyRanking	POST	/api/health/family/ranking	200	200	BIZ_OK
+pages/home-pages/parent-index	getInviteQrCode	POST	/api/invite/qrcode	200	200	BIZ_OK
+pages/home-pages/parent-index	getParentDashboard	POST	/api/parent/dashboard	200	200	BIZ_OK
+pages/home-pages/parent-index	getChildCompletionStats	POST	/api/stats/child-completion	200	200	BIZ_OK
+pages/home-pages/parent-index	approveTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+pages/home-pages/parent-index	rejectTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+pages/home-pages/parent-index	getPendingReviewTasks	POST	/api/tasks/pending-review	200	200	BIZ_OK
+pages/home-pages/parent-index	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/home-pages/parent-index	getUnlockStatus	POST	/api/unlock/status	200	200	BIZ_OK
+pages/home-pages/parent-index	getPendingWishes	POST	/api/wishes/pending	200	200	BIZ_OK
+pages/home/app-library	getAppLibrary	POST	/api/home/app-library	200	200	BIZ_OK
+pages/home/app-library	resetShortcutConfig	POST	/api/home/shortcut/reset	200	200	BIZ_OK
+pages/home/app-library	saveShortcutConfig	POST	/api/home/shortcut/save	200	200	BIZ_OK
+pages/index-home/index	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/index-home/index	getNotices	POST	/api/admin/notices/all	200	200	BIZ_OK
+pages/index-home/index	getFeaturedArticles	POST	/api/articles/featured	200	200	BIZ_OK
+pages/index-home/index	getCfList	POST	/api/commission/cf/list	200	200	BIZ_OK
+pages/index-home/index	getCfSummary	POST	/api/commission/cf/summary	200	200	BIZ_OK
+pages/index-home/index	getEnergyLogs	POST	/api/energy/logs	200	200	BIZ_OK
+pages/index-home/index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/index-home/index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/index-home/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/index-home/index	switchToFamilyMember	POST	/api/family/member/switch	200	500	BIZ_FAIL
+pages/index-home/index	getSelfCheckStatus	POST	/api/family/self-check/status	200	200	BIZ_OK
+pages/index-home/index	getGuideConfig	POST	/api/guide-config/current	200	500	BIZ_FAIL
+pages/index-home/index	acceptParentInvite	POST	/api/guide/parent-invite/accept	200	500	BIZ_FAIL
+pages/index-home/index	consumeGuidePopup	POST	/api/guide/popup/consume	200	500	BIZ_FAIL
+pages/index-home/index	getGuidePopupList	POST	/api/guide/popup/list	200	200	BIZ_OK
+pages/index-home/index	getChallengeList	POST	/api/health/challenge/list	200	200	BIZ_OK
+pages/index-home/index	updateChallengeProgress	POST	/api/health/challenge/progress	200	500	BIZ_FAIL
+pages/index-home/index	respondChallenge	POST	/api/health/challenge/respond	200	500	BIZ_FAIL
+pages/index-home/index	getAppLibrary	POST	/api/home/app-library	200	200	BIZ_OK
+pages/index-home/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/index-home/index	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/index-home/index	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/index-home/index	getNotificationList	POST	/api/notification/list	200	200	BIZ_OK
+pages/index-home/index	readNotification	POST	/api/notification/read	200	200	BIZ_OK
+pages/index-home/index	getPointsLogs	POST	/api/points/logs	200	200	BIZ_OK
+pages/index-home/index	getSurveyStatus	POST	/api/survey/status	200	200	BIZ_OK
+pages/index-home/index	getTaskHistory	POST	/api/tasks/history	200	200	BIZ_OK
+pages/index-home/index	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/invite/join	checkUserFamily	POST	/api/family/invite/check-family	200	200	BIZ_OK
+pages/invite/join	validateInvitation	POST	/api/family/invite/validate	200	500	BIZ_FAIL
+pages/invite/join	validateFamilyCode	POST	/api/family/invite/validate-family-code	200	500	BIZ_FAIL
+pages/invite/join	bindReferral	POST	/api/invite/bind	200	500	BIZ_FAIL
+pages/invite/join-form	requestJoinByCode	POST	/api/family/invite/request-join-by-code	200	500	BIZ_FAIL
+pages/invite/join-form	updateUserInfo	POST	/api/user/update	200	200	BIZ_OK
+pages/login/scan-login	wechatWebScan	POST	/api/auth/wechat-web/scan	200	500	BIZ_FAIL
+pages/match/street-match	countFamiliesByStreetIds	POST	/api/admin/families/count	200	500	BIZ_FAIL
+pages/match/street-match	countTeachersByStreetIds	POST	/api/admin/teachers/count	200	200	BIZ_OK
+pages/meal/log	logMeal	POST	/api/meal/log	200	400	BIZ_FAIL
+pages/meal/log	getMealLogs	POST	/api/meal/logs	200	200	BIZ_OK
+pages/meal/log	getNutritionSummary	POST	/api/meal/nutrition-summary	200	200	BIZ_OK
+pages/meal/preference	getNutritionProfile	POST	/api/nutrition/profile/get	200	200	BIZ_OK
+pages/meal/preference	saveNutritionProfile	POST	/api/nutrition/profile/save	200	200	BIZ_OK
+pages/meal/recommend	getMealRecommend	POST	/api/meal/recommend	200	500	BIZ_FAIL
+pages/meal/recommend	replaceFood	POST	/api/meal/replace	200	500	BIZ_FAIL
+pages/member-detail/components/member-detail-sections/action-section	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/action-section	getTodayTasksByCategory	POST	/api/tasks/today	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/action-section	getCheckinStats	POST	/api/wealth/checkin/stats	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/body-section	getDimensionOverview	POST	/api/dimension/overview	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/body-section	getHealthAnalysis	POST	/api/health/analysis	200	500	BIZ_FAIL
+pages/member-detail/components/member-detail-sections/body-section	getCheckinList	POST	/api/wealth/checkin/list	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/mind-section	getContactList	POST	/api/contact/list	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/mind-section	getHealthAlerts	POST	/api/family/relationship/health-alerts	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/mind-section	getMilestones	POST	/api/family/relationship/milestones	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/mind-section	getRelationshipScores	POST	/api/family/relationship/scores	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/wisdom-section	getAssessmentHistory	POST	/api/assessment/history	200	200	BIZ_OK
+pages/member-detail/components/member-detail-sections/wisdom-section	getAssessmentLatestResult	POST	/api/assessment/latest-result	200	200	BIZ_OK
+pages/member-detail/member-detail	getActivityList	POST	/api/activity/list	200	200	BIZ_OK
+pages/member-detail/member-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/member-detail/report-detail	getReportDetail	POST	/api/health/report/detail	200	500	BIZ_FAIL
+pages/membership/benefits	getMembershipBenefits	POST	/api/membership/benefits	200	200	BIZ_OK
+pages/membership/benefits	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/membership/index	getMyButler	POST	/api/butler/my-butler	200	200	BIZ_OK
+pages/membership/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/membership/index	getMembershipBenefits	POST	/api/membership/benefits	200	200	BIZ_OK
+pages/membership/index	getMembershipCompare	POST	/api/membership/compare	200	500	BIZ_FAIL
+pages/membership/index	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/membership/pay	getCouponList	POST	/api/coupon/list	200	200	BIZ_OK
+pages/membership/pay	createOrder	POST	/api/membership/orders	200	500	BIZ_FAIL
+pages/membership/pay	nextOrder	POST	/api/membership/orders/continue	200	400	BIZ_FAIL
+pages/membership/pay	getMembershipPlans	POST	/api/membership/plans	200	200	BIZ_OK
+pages/membership/result	getJoinCouponRules	POST	/api/coupon/join-rules	200	200	BIZ_OK
+pages/membership/result	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/membership/result	nextOrder	POST	/api/membership/orders/continue	200	400	BIZ_FAIL
+pages/membership/upgrade	getJoinCouponRules	POST	/api/coupon/join-rules	200	200	BIZ_OK
+pages/membership/upgrade	getMembershipCompare	POST	/api/membership/compare	200	500	BIZ_FAIL
+pages/membership/upgrade	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/membership/upgrade	getMembershipPlans	POST	/api/membership/plans	200	200	BIZ_OK
+pages/membership/upgrade	getUpgradeRecords	POST	/api/membership/upgrade-records	200	200	BIZ_OK
+pages/mind-detail/articles	getArticleCategories	POST	/api/articles/categories	200	200	BIZ_OK
+pages/mind-detail/articles	getArticleList	POST	/api/articles/list	200	200	BIZ_OK
+pages/mind-detail/components/PsychCrisisBanner	dismissAlert	POST	/api/health/alert/dismiss	200	500	BIZ_FAIL
+pages/mind-detail/emotion-report	getEmiReport	POST	/api/emireport/latest	200	200	BIZ_OK
+pages/mind-detail/family-dashboard	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/mind-detail/family-dashboard	getFamilyFortune	POST	/api/mind/fortune	200	200	BIZ_OK
+pages/mind-detail/family-dashboard	getMonthFortune	POST	/api/mind/fortune/month	200	200	BIZ_OK
+pages/mind-detail/family-dashboard	getFortuneReports	POST	/api/mind/fortune/reports	200	200	BIZ_OK
+pages/mind-detail/family-dashboard	getWeekFortune	POST	/api/mind/fortune/week	200	200	BIZ_OK
+pages/mind-detail/index	getContactList	POST	/api/contact/list	200	200	BIZ_OK
+pages/mind-detail/index	getVisibleSections	POST	/api/content-sections/visible	200	500	BIZ_FAIL
+pages/mind-detail/index	getDanReportByChild	POST	/api/dan-assessment/report/child	200	500	BIZ_FAIL
+pages/mind-detail/index	getRadarData	POST	/api/dimension/radar-data	200	200	BIZ_OK
+pages/mind-detail/index	getEmiReport	POST	/api/emireport/latest	200	200	BIZ_OK
+pages/mind-detail/index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/mind-detail/index	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/mind-detail/index	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/mind-detail/index	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+pages/mind-detail/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/mind-detail/index	getHealthAlerts	POST	/api/family/relationship/health-alerts	200	200	BIZ_OK
+pages/mind-detail/index	getMilestones	POST	/api/family/relationship/milestones	200	200	BIZ_OK
+pages/mind-detail/index	getLatestIndicators	POST	/api/health/indicators	200	500	BIZ_FAIL
+pages/mind-detail/index	getFamilyFortune	POST	/api/mind/fortune	200	200	BIZ_OK
+pages/mind-detail/innate-portrait	getInnateReading	POST	/api/mind/innate/reading	200	500	BIZ_FAIL
+pages/mind-detail/innate-trajectory	getInnateTrajectory	POST	/api/mind/innate/trajectory	200	500	BIZ_FAIL
+pages/mind-detail/member-mind-detail	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/mind-detail/member-mind-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/mind-detail/training	getGameStats	POST	/api/game/stats	200	200	BIZ_OK
+pages/notification/index	getNotificationList	POST	/api/notification/list	200	200	BIZ_OK
+pages/notification/index	readNotification	POST	/api/notification/read	200	200	BIZ_OK
+pages/nutritionist/apply	nutritionistApply	POST	/api/nutritionist/apply	200	200	BIZ_OK
+pages/orchestration/editor	getNodeTemplateList	POST	/api/admin/task-templates	200	403	BIZ_FAIL
+pages/orchestration/editor	getOrchestrationFlowDetail	POST	/api/orchestration/flow/detail	200	500	BIZ_FAIL
+pages/orchestration/editor	publishOrchestrationFlow	POST	/api/orchestration/flow/publish	200	500	BIZ_FAIL
+pages/orchestration/editor	saveOrchestrationFlow	POST	/api/orchestration/flow/save	200	500	BIZ_FAIL
+pages/orchestration/index	archiveOrchestrationFlow	POST	/api/orchestration/flow/archive	200	500	BIZ_FAIL
+pages/orchestration/index	deleteOrchestrationFlow	POST	/api/orchestration/flow/delete	200	500	BIZ_FAIL
+pages/orchestration/index	getOrchestrationFlowList	POST	/api/orchestration/flow/list	200	200	BIZ_OK
+pages/orchestration/index	publishOrchestrationFlow	POST	/api/orchestration/flow/publish	200	500	BIZ_FAIL
+pages/orchestration/node-edit	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/parent/appointments	cancelAppointment	POST	/api/dan-assessment/appointment/cancel	200	500	BIZ_FAIL
+pages/parent/appointments	getMyAppointments	POST	/api/dan-assessment/appointment/user	200	500	BIZ_FAIL
+pages/parent/child-detail	getPendingReviewTasks	POST	/api/tasks/pending-review	200	200	BIZ_OK
+pages/parent/child-detail	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/parent/child-detail	getPendingWishes	POST	/api/wishes/pending	200	200	BIZ_OK
+pages/parent/plans/detail	getGuidePlanDetail	POST	/api/guide/plans/detail	200	500	BIZ_FAIL
+pages/parent/plans/index	listFamilyPlans	POST	/api/guide/plans/family-list	200	500	BIZ_FAIL
+pages/parent/wishes/index	approveWishExchange	POST	/api/wishes/1/approve-exchange	200	500	BIZ_FAIL
+pages/parent/wishes/index	markWishFulfilled	POST	/api/wishes/1/fulfill	200	500	BIZ_FAIL
+pages/parent/wishes/index	setWishPrice	POST	/api/wishes/1/price	404	None	NOT_FOUND
+pages/parent/wishes/index	rejectWish	POST	/api/wishes/1/reject	200	500	BIZ_FAIL
+pages/parent/wishes/index	getWishes	POST	/api/wishes/list	200	500	BIZ_FAIL
+pages/parent/wishes/index	getPendingWishes	POST	/api/wishes/pending	200	200	BIZ_OK
+pages/pearl-reminders/index	addPearlInteraction	POST	/api/pearl/interaction/add	200	500	BIZ_FAIL
+pages/pearl-reminders/index	getPearlReminders	POST	/api/pearl/reminder/list	200	200	BIZ_OK
+pages/profile-extra/coupons	claimCoupon	POST	/api/coupon/claim	200	500	BIZ_FAIL
+pages/profile-extra/coupons	getExchangeableCoupons	POST	/api/coupon/exchangeable	200	200	BIZ_OK
+pages/profile-extra/coupons	getMyCoupons	POST	/api/coupon/my	200	200	BIZ_OK
+pages/profile-extra/coupons	exchangeCouponByCf	POST	/api/family-platform/exchange-coupon	200	500	BIZ_FAIL
+pages/profile-extra/family-members	generateFamilyInvite	POST	/api/family/invite/generate	200	200	BIZ_OK
+pages/profile-extra/family-members	getPendingJoinRequests	POST	/api/family/invite/pending-requests	200	200	BIZ_OK
+pages/profile-extra/family-members	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+pages/profile-extra/family-members	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/profile-extra/family-members	switchToFamilyMember	POST	/api/family/member/switch	200	500	BIZ_FAIL
+pages/profile-extra/family-members	revokeReportMemberPermission	POST	/api/health/report/member-permission/revoke	200	500	BIZ_FAIL
+pages/profile-extra/family-members	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/profile-extra/gates	getUnlockStatus	POST	/api/unlock/status	200	200	BIZ_OK
+pages/profile-extra/onboarding	claimOnboardingReward	POST	/api/onboarding/claim	200	200	BIZ_OK
+pages/profile-extra/onboarding	getOnboardingProgress	POST	/api/onboarding/progress	200	200	BIZ_OK
+pages/profile-main/profile	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+pages/profile-main/profile	cartCount	POST	/api/cart/count	200	200	BIZ_OK
+pages/profile-main/profile	getMyReferrer	POST	/api/commission/my-referrer	200	200	BIZ_OK
+pages/profile-main/profile	getTeamConsumption	POST	/api/commission/team/consumption	200	200	BIZ_OK
+pages/profile-main/profile	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/profile-main/profile	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/profile-main/profile	getChallengeList	POST	/api/health/challenge/list	200	200	BIZ_OK
+pages/profile-main/profile	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/profile-main/profile	getReferralSummary	POST	/api/invite/summary	200	200	BIZ_OK
+pages/profile-main/profile	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/profile-main/profile	getOrderCounts	POST	/api/product/order/my/counts	200	200	BIZ_OK
+pages/profile-main/profile	getShareQrCode	POST	/api/share/qrcode	200	500	BIZ_FAIL
+pages/profile-main/profile	getTodayTasksByCategory	POST	/api/tasks/today	200	200	BIZ_OK
+pages/profile-main/profile	getUserInfo	POST	/api/user/info	200	200	BIZ_OK
+pages/profile-main/profile	getProfileStats	POST	/api/user/profile-stats	200	200	BIZ_OK
+pages/profile-main/profile	vendorStatus	POST	/api/vendor/status	200	200	BIZ_OK
+pages/profile/components/ProfileHeader	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+pages/profile/components/ProfileHeader	switchToFamilyMember	POST	/api/family/member/switch	200	500	BIZ_FAIL
+pages/profile/components/ProfileMenu	setPassword	POST	/api/auth/set-password	200	400	BIZ_FAIL
+pages/profile/components/ProfileMenu	verifyPassword	POST	/api/auth/verify-password	200	200	BIZ_OK
+pages/profile/components/ProfileMenu	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/profile/components/ProfileMenu	updateMemberVisibility	POST	/api/family/user/members/update-visibility	200	500	BIZ_FAIL
+pages/profile/components/ProfileMenu	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/profile/components/ProfileMenu	vendorStatus	POST	/api/vendor/status	200	200	BIZ_OK
+pages/profile/components/ProfileStats	getUserActionStats	POST	/api/user/action-stats	200	200	BIZ_OK
+pages/profile/index	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/profile/message-history	getCfList	POST	/api/commission/cf/list	200	200	BIZ_OK
+pages/profile/message-history	getEnergyLogs	POST	/api/energy/logs	200	200	BIZ_OK
+pages/profile/message-history	getNotificationList	POST	/api/notification/list	200	200	BIZ_OK
+pages/profile/message-history	readNotification	POST	/api/notification/read	200	200	BIZ_OK
+pages/profile/message-history	getPointsLogs	POST	/api/points/logs	200	200	BIZ_OK
+pages/profile/portrait-edit	getEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/profile/portrait-edit	editPortrait	POST	/api/user/portrait/edit	200	500	BIZ_FAIL
+pages/profile/portrait-edit	getPortrait	POST	/api/user/portrait/get	200	200	BIZ_OK
+pages/profile/report-detail	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/profile/report-management	getReportSummaryList	POST	/api/report-summary/list	200	200	BIZ_OK
+pages/profile/service-role-apply	getMyServiceRoleApply	POST	/api/service-role/my-apply	200	200	BIZ_OK
+pages/profile/service-role-apply	uploadServiceRoleImage	POST	/api/service-role/upload-image	200	400	BIZ_FAIL
+pages/promotion/commission	getCfList	POST	/api/commission/cf/list	200	200	BIZ_OK
+pages/promotion/commission	getCfSummary	POST	/api/commission/cf/summary	200	200	BIZ_OK
+pages/promotion/index	getCfSummary	POST	/api/commission/cf/summary	200	200	BIZ_OK
+pages/promotion/index	distributeToMember	POST	/api/earnings/admin/distribute	200	500	BIZ_FAIL
+pages/promotion/index	toggleMemberBalance	POST	/api/earnings/admin/toggle-member	200	500	BIZ_FAIL
+pages/promotion/index	withdrawFamilyEarnings	POST	/api/earnings/admin/withdraw	200	500	BIZ_FAIL
+pages/promotion/index	getFamilyEarningsSummary	POST	/api/earnings/family/summary	200	200	BIZ_OK
+pages/promotion/index	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/promotion/index	getReferralSummary	POST	/api/invite/summary	200	200	BIZ_OK
+pages/promotion/invite	bindReferral	POST	/api/invite/bind	200	500	BIZ_FAIL
+pages/promotion/invite	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+pages/promotion/invite	getReferralList	POST	/api/invite/list	200	200	BIZ_OK
+pages/promotion/invite	claimInviteMilestone	POST	/api/invite/milestone/claim	200	500	BIZ_FAIL
+pages/promotion/invite	getInviteMilestones	POST	/api/invite/milestone/list	200	200	BIZ_OK
+pages/promotion/invite	getInviteQrCode	POST	/api/invite/qrcode	200	200	BIZ_OK
+pages/promotion/invite	getReferralSummary	POST	/api/invite/summary	200	200	BIZ_OK
+pages/promotion/leaderboard	getLeaderboardMyRank	POST	/api/leaderboard/my-rank	200	200	BIZ_OK
+pages/promotion/leaderboard	getLeaderboardTop	POST	/api/leaderboard/top	200	200	BIZ_OK
+pages/promotion/team	getCfRate	POST	/api/commission/cf/rate	200	200	BIZ_OK
+pages/promotion/team	getMyReferrer	POST	/api/commission/my-referrer	200	200	BIZ_OK
+pages/promotion/team	getTeamConsumption	POST	/api/commission/team/consumption	200	200	BIZ_OK
+pages/promotion/team	getTeamAllMembersConsumptionCurve	POST	/api/commission/team/consumption-curve	200	200	BIZ_OK
+pages/promotion/team	getTeamGrowthCurve	POST	/api/commission/team/growth-curve	200	200	BIZ_OK
+pages/promotion/team	getTeamL1ConsumptionCurve	POST	/api/commission/team/l1-consumption-curve	200	200	BIZ_OK
+pages/promotion/team	getTeamList	POST	/api/commission/team/list	200	200	BIZ_OK
+pages/promotion/team	getTeamTree	POST	/api/commission/team/tree	200	200	BIZ_OK
+pages/promotion/withdraw	getCommissionSummary	POST	/api/commission/summary	200	200	BIZ_OK
+pages/promotion/withdraw	applyWithdrawal	POST	/api/withdrawal/apply	200	500	BIZ_FAIL
+pages/promotion/withdraw	getWithdrawalHistory	POST	/api/withdrawal/history	200	200	BIZ_OK
+pages/psych-assessment/index	getCognitiveChildScores	POST	/api/cognitive/child	200	200	BIZ_OK
+pages/psych-assessment/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/psych-assessment/quiz	submitCognitiveSelfTest	POST	/api/cognitive/self-test	200	500	BIZ_FAIL
+pages/reminder-config/index	getReminderConfig	POST	/api/task/reminder-config/get	200	200	BIZ_OK
+pages/reminder-config/index	saveReminderConfig	POST	/api/task/reminder-config/save	200	500	BIZ_FAIL
+pages/rewards/badge	getChildBadges	POST	/api/badges/child/list	200	200	BIZ_OK
+pages/rewards/badge	toggleBadgeFavorite	POST	/api/badges/favorite	200	200	BIZ_OK
+pages/rewards/badge	getActiveBadges	POST	/api/badges/list	200	200	BIZ_OK
+pages/rewards/badge	getFamilyBadgeRanking	POST	/api/badges/ranking/family	200	200	BIZ_OK
+pages/rewards/badge	getChildBadgeStats	POST	/api/badges/statistics/child	200	200	BIZ_OK
+pages/rewards/rewards	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/rewards/rewards	createParentWishlist	POST	/api/parent/wishlist	200	400	BIZ_FAIL
+pages/rewards/rewards	exchangeParentWishlist	POST	/api/parent/wishlist/1/exchange	200	500	BIZ_FAIL
+pages/rewards/rewards	getParentWishlist	POST	/api/parent/wishlist/list	200	200	BIZ_OK
+pages/rewards/rewards	getPointsBalance	POST	/api/points/balance	200	200	BIZ_OK
+pages/rewards/rewards	createReward	POST	/api/rewards	404	None	NOT_FOUND
+pages/rewards/rewards	exchangeReward	POST	/api/rewards/1/exchange	200	200	BIZ_OK
+pages/rewards/rewards	getWishlist	POST	/api/rewards/wishlist	200	200	BIZ_OK
+pages/rewards/rewards	getUserInfo	POST	/api/user/info	200	200	BIZ_OK
+pages/share/index	getFamilyFootprint	POST	/api/share/family-footprint	200	200	BIZ_OK
+pages/shop/cart/cart	getGiftMembershipProgress	POST	/api/membership/gift-membership-progress	200	500	BIZ_FAIL
+pages/shop/cart/cart	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/shop/checkout/checkout	applyCoupon	POST	/api/coupon/apply	200	500	BIZ_FAIL
+pages/shop/checkout/checkout	getCouponCheckoutList	POST	/api/coupon/checkout-list	200	200	BIZ_OK
+pages/shop/checkout/checkout	getCouponList	POST	/api/coupon/list	200	200	BIZ_OK
+pages/shop/checkout/checkout	getFamilyPlatformBalance	POST	/api/family-platform/balance	200	200	BIZ_OK
+pages/shop/checkout/checkout	exchangeCouponByCf	POST	/api/family-platform/exchange-coupon	200	500	BIZ_FAIL
+pages/shop/checkout/checkout	getGiftMembershipProgress	POST	/api/membership/gift-membership-progress	200	500	BIZ_FAIL
+pages/shop/checkout/checkout	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/shop/checkout/checkout	productDetail	POST	/api/product/detail	200	500	BIZ_FAIL
+pages/shop/checkout/checkout	getProductRequiredFields	POST	/api/product/purchase_fields/required	200	500	BIZ_FAIL
+pages/shop/checkout/checkout	shopDiscountCalculate	POST	/api/shop/discount/calculate	200	200	BIZ_OK
+pages/shop/checkout/checkout	getSpecialPriceInfo	POST	/api/special-price/info	200	200	BIZ_OK
+pages/shop/checkout/checkout	addressList	POST	/api/user/address/list	200	200	BIZ_OK
+pages/shop/consignee-edit/consignee-edit	consigneeDetail	POST	/api/consignee/detail	200	500	BIZ_FAIL
+pages/shop/consignee-edit/consignee-edit	consigneeSave	POST	/api/consignee/save	200	500	BIZ_FAIL
+pages/shop/consignee-list/consignee-list	consigneeDelete	POST	/api/consignee/delete	200	500	BIZ_FAIL
+pages/shop/consignee-list/consignee-list	consigneeList	POST	/api/consignee/list	200	200	BIZ_OK
+pages/shop/index/index	cartCount	POST	/api/cart/count	200	200	BIZ_OK
+pages/shop/index/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/shop/index/index	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/shop/index/index	productList	POST	/api/product/list	200	200	BIZ_OK
+pages/shop/index/index	goodsCategory	POST	/api/shop/category/tree	200	200	BIZ_OK
+pages/shop/order-detail/order-detail	productOrderCancel	POST	/api/product/order/cancel	200	500	BIZ_FAIL
+pages/shop/order-detail/order-detail	productOrderConfirm	POST	/api/product/order/confirm	200	500	BIZ_FAIL
+pages/shop/order-detail/order-detail	productOrderDetail	POST	/api/product/order/detail	200	500	BIZ_FAIL
+pages/shop/order-list/order-list	productOrderCancel	POST	/api/product/order/cancel	200	500	BIZ_FAIL
+pages/shop/order-list/order-list	productOrderConfirm	POST	/api/product/order/confirm	200	500	BIZ_FAIL
+pages/shop/order-list/order-list	productOrderMy	POST	/api/product/order/my	200	200	BIZ_OK
+pages/shop/order-list/order-list	productOrderCounts	POST	/api/product/order/my/counts	200	200	BIZ_OK
+pages/shop/payment/payment	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/shop/search/search	productList	POST	/api/product/list	200	200	BIZ_OK
+pages/stats/completion-rate	getChildCompletionStats	POST	/api/stats/child-completion	200	200	BIZ_OK
+pages/stats/completion-rate	getFamilyCompletionStats	POST	/api/stats/family-completion	200	200	BIZ_OK
+pages/stats/index	getChildOverview	POST	/api/stats/child/overview	200	200	BIZ_OK
+pages/tasks/create-task	createTask	POST	/api/tasks/create	200	400	BIZ_FAIL
+pages/tasks/create-task	getTaskListForPicker	POST	/api/tasks/list	200	200	BIZ_OK
+pages/tasks/daily-tasks	claimGrowthTaskReward	POST	/api/growth-task/claim	200	200	BIZ_OK
+pages/tasks/daily-tasks	getGrowthTaskList	POST	/api/growth-task/list	200	200	BIZ_OK
+pages/tasks/review	approveTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+pages/tasks/review	rejectTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+pages/tasks/review	getTaskHistory	POST	/api/tasks/history	200	200	BIZ_OK
+pages/tasks/review	getPendingReviewTasks	POST	/api/tasks/pending-review	200	200	BIZ_OK
+pages/tasks/tasks	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/tasks/tasks	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/tasks/tasks	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/tasks/tasks	completeTask	POST	/api/tasks/1/complete	200	500	BIZ_FAIL
+pages/tasks/tasks	acceptTask	POST	/api/tasks/accept	200	500	BIZ_FAIL
+pages/tasks/tasks	createTask	POST	/api/tasks/create	200	400	BIZ_FAIL
+pages/tasks/tasks	getMyPendingTasks	POST	/api/tasks/my-pending	200	200	BIZ_OK
+pages/tasks/tasks	getTodayTasks	POST	/api/tasks/today	200	200	BIZ_OK
+pages/teacher/chat	getGuideMessages	POST	/api/guide/messages/list	200	500	BIZ_FAIL
+pages/teacher/families	getBoundFamilies	POST	/api/guide/families	404	None	NOT_FOUND
+pages/teacher/messages	getGuideMessages	POST	/api/guide/messages/list	200	500	BIZ_FAIL
+pages/teacher/orders	getGuideOrders	POST	/api/guide/orders/list	200	403	BIZ_FAIL
+pages/teacher/orders	getOrderStats	POST	/api/guide/orders/stats	200	403	BIZ_FAIL
+pages/teacher/plan-create	createTrainingPlan	POST	/api/guide/training-plans/create	200	200	BIZ_OK
+pages/teacher/plan-detail	updateGuidePlanContent	POST	/api/guide/families/1/plans/1/update	200	403	BIZ_FAIL
+pages/teacher/plan-detail	getGuidePendingPlans	POST	/api/guide/families/1/plans/pending	200	403	BIZ_FAIL
+pages/teacher/plan-list	getTrainingPlanList	POST	/api/guide/training-plans/list	200	200	BIZ_OK
+pages/teacher/review-family	getGuideChildPendingTasks	POST	/api/guide/families/1/children/1/pending-review	200	500	BIZ_FAIL
+pages/teacher/review-family	getGuideFamilyMembers	POST	/api/guide/families/1/members	200	403	BIZ_FAIL
+pages/teacher/review-family	getGuidePendingPlans	POST	/api/guide/families/1/plans/pending	200	403	BIZ_FAIL
+pages/teacher/review-family	reviewGuideTask	POST	/api/guide/families/1/tasks/1/review	200	500	BIZ_FAIL
+pages/teacher/review-family	reviewTask	POST	/api/tasks/1/review	200	200	BIZ_OK
+pages/teacher/review-workbench	getGuideMyFamilies	POST	/api/guide/families/my-families	200	403	BIZ_FAIL
+pages/teacher/service-tasks	completeTask	POST	/api/tasks/1/complete	200	500	BIZ_FAIL
+pages/teacher/teacher-profile	generateParentInvite	POST	/api/guide/parent-invite/generate	200	200	BIZ_OK
+pages/teacher/teacher-profile	switchRole	POST	/api/auth/switch-role	200	200	BIZ_OK
+pages/teacher/team	generateInviteCode	POST	/api/guide/invite-code/generate	200	200	BIZ_OK
+pages/teacher/team	generateTeamInviteCode	POST	/api/guide/team/invite-code/generate	200	200	BIZ_OK
+pages/teacher/team	getTeamMembers	POST	/api/guide/team/members	200	200	BIZ_OK
+pages/teacher/team	getTeamStats	POST	/api/guide/team/stats	200	200	BIZ_OK
+pages/user-edit/user-edit	directRegister	POST	/api/auth/direct-register	200	500	BIZ_FAIL
+pages/user-edit/user-edit	requestJoinByCode	POST	/api/family/invite/request-join-by-code	200	500	BIZ_FAIL
+pages/user-edit/user-edit	createFamily	POST	/api/family/user/create-family	200	200	BIZ_OK
+pages/user-edit/user-edit	getMyMembership	POST	/api/membership/my	200	200	BIZ_OK
+pages/user-edit/user-edit	getUserInfo	POST	/api/user/info	200	200	BIZ_OK
+pages/user-edit/user-edit	updateUserInfo	POST	/api/user/update	200	200	BIZ_OK
+pages/vendor/apply	vendorApply	POST	/api/vendor/apply	200	200	BIZ_OK
+pages/vendor/center	vendorInfo	POST	/api/vendor/info	200	500	BIZ_FAIL
+pages/vendor/center	vendorStatus	POST	/api/vendor/status	200	200	BIZ_OK
+pages/vendor/order-review/order-review	productOrderDetail	POST	/api/product/order/detail	200	500	BIZ_FAIL
+pages/vendor/order-review/order-review	productOrderReviewUpdate	POST	/api/product/order/review/update	200	500	BIZ_FAIL
+pages/vendor/orders/orders	productOrderConfirm	POST	/api/product/order/confirm	200	500	BIZ_FAIL
+pages/vendor/orders/orders	productOrderVendor	POST	/api/product/order/vendor	200	200	BIZ_OK
+pages/vendor/product-edit/product-edit	productCreate	POST	/api/product/create	200	500	BIZ_FAIL
+pages/vendor/product-edit/product-edit	productDetail	POST	/api/product/detail	200	500	BIZ_FAIL
+pages/vendor/product-edit/product-edit	productUpdate	POST	/api/product/update	200	500	BIZ_FAIL
+pages/vendor/products/products	productMy	POST	/api/product/my	200	200	BIZ_OK
+pages/vendor/products/products	productShelve	POST	/api/product/shelve	200	500	BIZ_FAIL
+pages/vendor/team-customers/team-customers	getTeamCustomers	POST	/api/admin/supply-team/customers	200	200	BIZ_OK
+pages/vendor/team-system/team-system	getVendorHierarchyInfo	POST	/api/admin/supply-hierarchy/my	200	500	BIZ_FAIL
+pages/vendor/team-system/team-system	getVendorSystemInfo	POST	/api/admin/supply-system/my-system	200	500	BIZ_FAIL
+pages/vendor/team-system/team-system	getVendorTeamCustomers	POST	/api/admin/supply-team/customers	200	200	BIZ_OK
+pages/vendor/team-system/team-system	getVendorTeamMembers	POST	/api/admin/supply-team/members	200	200	BIZ_OK
+pages/wealth-cf/index	getCfBalance	GET	/api/cf/balance	200	200	BIZ_OK
+pages/wealth-cf/index	getFamilyCoupons	GET	/api/cf/family-coupons	200	200	BIZ_OK
+pages/wealth-cf/index	getCfLogs	GET	/api/cf/logs	200	200	BIZ_OK
+pages/wealth-cf/index	getExchangeableCoupons	POST	/api/coupon/exchangeable	200	200	BIZ_OK
+pages/wealth-cf/index	exchangeCouponByCf	POST	/api/family-platform/exchange-coupon	200	500	BIZ_FAIL
+pages/wealth-detail/member-wealth-detail	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/wealth-detail/member-wealth-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/wealth-sub/checkin	createCheckin	POST	/api/wealth/checkin/create	200	500	BIZ_FAIL
+pages/wealth-sub/checkin	deleteCheckin	POST	/api/wealth/checkin/delete	200	500	BIZ_FAIL
+pages/wealth-sub/checkin	getCheckinList	POST	/api/wealth/checkin/list	200	200	BIZ_OK
+pages/wealth-sub/checkin	getCheckinStats	POST	/api/wealth/checkin/stats	200	200	BIZ_OK
+pages/wealth-sub/insurance-add	createInsurance	POST	/api/wealth/insurance/create	200	400	BIZ_FAIL
+pages/wealth-sub/insurance-add	getInsuranceDetail	POST	/api/wealth/insurance/detail	200	500	BIZ_FAIL
+pages/wealth-sub/insurance-add	updateInsurance	POST	/api/wealth/insurance/update	200	200	BIZ_OK
+pages/wealth-sub/insurance-add	uploadPolicy	POST	/api/wealth/insurance/upload	200	400	BIZ_FAIL
+pages/wealth-sub/insurance-list	deleteInsurance	POST	/api/wealth/insurance/delete	200	500	BIZ_FAIL
+pages/wealth-sub/insurance-list	getInsuranceList	POST	/api/wealth/insurance/list	200	200	BIZ_OK
+pages/wealth-sub/insurance-planning	getInsurancePlanning	POST	/api/insurance/planning	200	500	BIZ_FAIL
+pages/wealth/index	getChildBadgeStats	POST	/api/badges/statistics/child	200	200	BIZ_OK
+pages/wealth/index	getCommissionSummary	POST	/api/commission/summary	200	200	BIZ_OK
+pages/wealth/index	getDailyTaskOverview	POST	/api/daily-task/overview	200	200	BIZ_OK
+pages/wealth/index	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/wealth/index	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/wealth/index	getWealthDetail	POST	/api/energy/wealth-detail	200	500	BIZ_FAIL
+pages/wealth/index	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+pages/wealth/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/wealth/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/wealth/index	getReferralSummary	POST	/api/invite/summary	200	200	BIZ_OK
+pages/wealth/index	productList	POST	/api/product/list	200	200	BIZ_OK
+pages/wealth/index	getInsuranceList	POST	/api/wealth/insurance/list	200	200	BIZ_OK
+pages/wisdom-detail/cognitive-report	getAssessmentLatestResult	POST	/api/assessment/latest-result	200	200	BIZ_OK
+pages/wisdom-detail/cognitive-report	getCognitiveNorms	POST	/api/cognitive/norms	200	500	BIZ_FAIL
+pages/wisdom-detail/cognitive-report	getCognitiveRecommendations	POST	/api/cognitive/recommendations	200	500	BIZ_FAIL
+pages/wisdom-detail/cognitive-report	createTaskFromRecommendation	POST	/api/cognitive/recommendations/create-task	200	500	BIZ_FAIL
+pages/wisdom-detail/cognitive-report	getCognitiveTrend	POST	/api/cognitive/trend	200	200	BIZ_OK
+pages/wisdom-detail/index	getAssessmentLatestResult	POST	/api/assessment/latest-result	200	200	BIZ_OK
+pages/wisdom-detail/index	getVisibleSections	POST	/api/content-sections/visible	200	500	BIZ_FAIL
+pages/wisdom-detail/index	getDanReportByChild	POST	/api/dan-assessment/report/child	200	500	BIZ_FAIL
+pages/wisdom-detail/index	getRadarData	POST	/api/dimension/radar-data	200	200	BIZ_OK
+pages/wisdom-detail/index	kickFamilyMemberById	POST	/api/family/member/kick	200	500	BIZ_FAIL
+pages/wisdom-detail/index	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+pages/wisdom-detail/index	getLatestIndicators	POST	/api/health/indicators	200	500	BIZ_FAIL
+pages/wisdom-detail/index	getGutCognitionIndicators	POST	/api/wisdom/gut-cognition	200	200	BIZ_OK
+pages/wisdom-detail/member-wisdom-detail	getEnergyOverview	POST	/api/energy/overview	200	200	BIZ_OK
+pages/wisdom-detail/member-wisdom-detail	getFamilyEnergySandbox	POST	/api/energy/sandbox	200	200	BIZ_OK
+pages/wishes/create	createWish	POST	/api/wishes/create	200	500	BIZ_FAIL
+pages/wishes/detail	getPointsBalance	POST	/api/points/balance	200	200	BIZ_OK
+pages/wishes/detail	cancelWish	POST	/api/wishes/1	200	200	BIZ_OK
+pages/wishes/detail	getWishById	POST	/api/wishes/1	200	200	BIZ_OK
+pages/wishes/detail	confirmWishReceived	POST	/api/wishes/1/confirm	200	500	BIZ_FAIL
+pages/wishes/detail	requestWishExchange	POST	/api/wishes/1/exchange	200	500	BIZ_FAIL
+pages/wishes/index	reportAppEnter	POST	/api/home/app/enter	200	500	BIZ_FAIL
+pages/wishes/index	getPointsBalance	POST	/api/points/balance	200	200	BIZ_OK
+pages/wishes/index	cancelWish	POST	/api/wishes/1	200	200	BIZ_OK
+pages/wishes/index	confirmWishReceived	POST	/api/wishes/1/confirm	200	500	BIZ_FAIL
+pages/wishes/index	requestWishExchange	POST	/api/wishes/1/exchange	200	500	BIZ_FAIL
+pages/wishes/index	createWish	POST	/api/wishes/create	200	500	BIZ_FAIL
+pages/wishes/index	getWishes	POST	/api/wishes/list	200	500	BIZ_FAIL
+store/health-alert	dismissAlert	POST	/api/health/alert/dismiss	200	500	BIZ_FAIL
+store/health-alert	getActiveAlerts	POST	/api/health/alert/list	200	200	BIZ_OK
+store/health-score	getHealthScoreInfo	POST	/api/health/score/info	200	200	BIZ_OK
+store/health-score	getHealthTimeline	POST	/api/health/timeline/list	200	200	BIZ_OK
+store/index	switchBackVerify	POST	/api/family/user/switch-back-verify	200	500	BIZ_FAIL
+store/index	switchBackToParent	POST	/api/family/user/switch-back-to-parent	200	410	BIZ_FAIL
+store/index	switchRole	POST	/api/auth/switch-role	200	200	BIZ_OK
+store/index	switchToChild	POST	/api/family/user/switch-to-child	200	410	BIZ_FAIL
+store/modules/tianpan	tianpanAnnualEnergy	POST	/api/tianpan/annual-energy	200	500	BIZ_FAIL
+store/modules/tianpan	tianpanDailyFortune	POST	/api/tianpan/daily-fortune	200	200	BIZ_OK
+store/modules/tianpan	tianpanDashboard	POST	/api/tianpan/dashboard	200	500	BIZ_FAIL
+store/modules/tianpan	tianpanRelatedItems	POST	/api/tianpan/related-items	200	200	BIZ_OK
+utils/api	adminListMyActivities	POST	/api/admin/activity/list	200	200	BIZ_OK
+utils/api	getNodeTemplateList	POST	/api/admin/task-templates	200	403	BIZ_FAIL
+utils/api	silentLogin	POST	/api/auth/silent-login	200	500	BIZ_FAIL
+utils/api	getChildBadges	POST	/api/badges/child/list	200	200	BIZ_OK
+utils/api	getAvailableButlers	POST	/api/butler/available-list	200	200	BIZ_OK
+utils/api	getMyButler	POST	/api/butler/my-butler	200	200	BIZ_OK
+utils/api	selectButler	POST	/api/butler/select	200	500	BIZ_FAIL
+utils/api	payAssessmentOrder	POST	/api/dan-assessment/order/pay	200	500	BIZ_FAIL
+utils/api	approveJoinRequest	POST	/api/family/invite/approve-request	200	500	BIZ_FAIL
+utils/api	getMyJoinRequest	POST	/api/family/invite/my-request	200	200	BIZ_OK
+utils/api	getPendingJoinRequests	POST	/api/family/invite/pending-requests	200	200	BIZ_OK
+utils/api	rejectJoinRequest	POST	/api/family/invite/reject-request	200	500	BIZ_FAIL
+utils/api	getFamilyMemberList	POST	/api/family/member/list	200	200	BIZ_OK
+utils/api	createFamily	POST	/api/family/user/create-family	200	200	BIZ_OK
+utils/api	reportVirtualPayError	POST	/api/internal/virtual-pay/error-report	200	200	BIZ_OK
+utils/api	bindReferral	POST	/api/invite/bind	200	500	BIZ_FAIL
+utils/api	getReferralCode	POST	/api/invite/code	200	200	BIZ_OK
+utils/api	getOrchestrationExecutionDetail	POST	/api/orchestration/execution/detail	200	500	BIZ_FAIL
+utils/api	startOrchestrationExecution	POST	/api/orchestration/execution/start	200	500	BIZ_FAIL
+utils/api	terminateOrchestrationExecution	POST	/api/orchestration/execution/terminate	200	500	BIZ_FAIL
+utils/api	archiveOrchestrationFlow	POST	/api/orchestration/flow/archive	200	500	BIZ_FAIL
+utils/api	deleteOrchestrationFlow	POST	/api/orchestration/flow/delete	200	500	BIZ_FAIL
+utils/api	getOrchestrationFlowDetail	POST	/api/orchestration/flow/detail	200	500	BIZ_FAIL
+utils/api	getOrchestrationFlowList	POST	/api/orchestration/flow/list	200	200	BIZ_OK
+utils/api	publishOrchestrationFlow	POST	/api/orchestration/flow/publish	200	500	BIZ_FAIL
+utils/api	saveOrchestrationFlow	POST	/api/orchestration/flow/save	200	500	BIZ_FAIL
+utils/api	productList	POST	/api/product/list	200	200	BIZ_OK
+utils/api	getProfileTrend	POST	/api/profile/history	200	200	BIZ_OK
+utils/api	getMyProfile	POST	/api/profile/my	200	200	BIZ_OK
+utils/api	getChallengeProgress	POST	/api/purchase/challenge/progress	200	200	BIZ_OK
+utils/api	getRecommendList	POST	/api/recommend/list	200	200	BIZ_OK
+utils/api	getChildOverview	POST	/api/stats/child/overview	200	200	BIZ_OK
+utils/api	getTaskHistory	POST	/api/tasks/history	200	200	BIZ_OK
+utils/api	editPortrait	POST	/api/user/portrait/edit	200	500	BIZ_FAIL
+utils/api	generatePortrait	POST	/api/user/portrait/generate	-1	None	CONN_ERR
+utils/api	getPortrait	POST	/api/user/portrait/get	200	200	BIZ_OK
+utils/api	regeneratePortrait	POST	/api/user/portrait/regenerate	-1	None	CONN_ERR
+utils/profile-backfill	backfillProfile	POST	/api/user/profile/backfill	200	500	BIZ_FAIL
+utils/sso	createSsoTicket	POST	/api/auth/sso-ticket	200	500	BIZ_FAIL
+auto	auto	GET	/api/cf/balance	200	200	BIZ_OK
+auto	auto	GET	/api/cf/family-coupons	200	200	BIZ_OK
+auto	auto	GET	/api/cf/logs	200	200	BIZ_OK
+auto	auto	POST	/api/admin/indicator/backfill	200	500	BIZ_FAIL
+auto	auto	POST	/api/health/report/indicators	200	500	BIZ_FAIL
+auto	auto	POST	/api/indicator/periods	200	500	BIZ_FAIL
+auto	auto	POST	/api/indicator/source-types	200	500	BIZ_FAIL

+ 1309 - 0
ops_interface_smoke.py

@@ -0,0 +1,1309 @@
+# -*- coding: utf-8 -*-
+"""
+CFC 小程序端「操作接口」冒烟脚本 — 由页面功能自动派生(共 1016 个接口用例)。
+
+用法:
+    # 公开接口冒烟(无需登录)
+    python ops_interface_smoke.py --base http://<可达地址>
+
+    # 带登录态接口测试
+    export CFC_TOKEN="eyJ..."
+    python ops_interface_smoke.py --base http://<可达地址> --authed
+
+    # 路径参数占位符(默认 '1',可换成真实 ID)
+    python ops_interface_smoke.py --base ... --param-val 真实ID
+
+说明:
+    * 仅做「连通性 + 返回结构」断言(HTTP 可达、JSON 可解析、含 code/data)。
+    * 业务正确性(字段值、状态机)需结合真实数据人工/用例补充。
+    * 鉴权流程(wechat-login 等)依赖微信 code,无法纯脚本自动化,见脚本底部 AUTH_NOTE。
+"""
+
+import argparse, json, os, sys, time
+import urllib.request, urllib.error
+
+# 纯标准库实现,无需 pip install requests。
+
+
+# 自动生成的用例: (page, method, path, auth, param, fn)
+CASES = [
+    ('App', 'POST', '/api/auth/auto-login', False, False, 'autoLogin'),
+    ('App', 'POST', '/api/auth/sso-login', False, False, 'ssoLogin'),
+    ('App', 'POST', '/api/auth/verify', False, False, 'verifyToken'),
+    ('App', 'POST', '/api/family/invite/check-family', False, False, 'checkUserFamily'),
+    ('__tests__/api/api.indicator.test', 'POST', '/api/indicator/change-ranking', True, False, 'getIndicatorChangeRanking'),
+    ('__tests__/api/api.indicator.test', 'POST', '/api/indicator/correlation/list', True, False, 'getIndicatorCorrelationList'),
+    ('__tests__/api/api.indicator.test', 'POST', '/api/indicator/quick-lookup', True, False, 'getIndicatorQuickLookup'),
+    ('__tests__/api/api.indicator.test', 'POST', '/api/indicator/trend', True, False, 'getIndicatorTrend'),
+    ('__tests__/api/api.test', 'POST', '/api/ai/chat/conversations', True, False, 'aiGetConversations'),
+    ('__tests__/api/api.test', 'POST', '/api/ai/chat/send', True, False, 'aiSendMessage'),
+    ('__tests__/api/api.test', 'POST', '/api/articles/categories', False, False, 'getArticleCategories'),
+    ('__tests__/api/api.test', 'POST', '/api/articles/daily-tip', False, False, 'getDailyTip'),
+    ('__tests__/api/api.test', 'POST', '/api/articles/detail', False, False, 'getArticleDetail'),
+    ('__tests__/api/api.test', 'POST', '/api/articles/list', False, False, 'getArticleList'),
+    ('__tests__/api/api.test', 'POST', '/api/articles/related', False, False, 'getRelatedArticles'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/auto-login', False, False, 'autoLogin'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/check-phone', False, False, 'checkPhone'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/direct-register', False, False, 'directRegister'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/phone-login', False, False, 'phoneLogin'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/send-code', False, False, 'sendCode'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/set-password', False, False, 'setPassword'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/silent-login', False, False, 'silentLogin'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/verify', False, False, 'verifyToken'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/wechat-login', False, False, 'wechatLogin'),
+    ('__tests__/api/api.test', 'POST', '/api/auth/wechat-phone-login', False, False, 'wechatPhoneLogin'),
+    ('__tests__/api/api.test', 'POST', '/api/badges/child/list', True, False, 'getChildBadges'),
+    ('__tests__/api/api.test', 'POST', '/api/badges/favorite', True, False, 'toggleBadgeFavorite'),
+    ('__tests__/api/api.test', 'POST', '/api/badges/list', True, False, 'getActiveBadges'),
+    ('__tests__/api/api.test', 'POST', '/api/commission/summary', True, False, 'getCommissionSummary'),
+    ('__tests__/api/api.test', 'POST', '/api/contact/create', True, False, 'createContact'),
+    ('__tests__/api/api.test', 'POST', '/api/contact/delete', True, False, 'deleteContact'),
+    ('__tests__/api/api.test', 'POST', '/api/contact/import-phone', True, False, 'importPhoneContact'),
+    ('__tests__/api/api.test', 'POST', '/api/contact/list', True, False, 'getContactList'),
+    ('__tests__/api/api.test', 'POST', '/api/dan-assessment/child-results', True, False, 'getChildAssessmentResults'),
+    ('__tests__/api/api.test', 'POST', '/api/dan-assessment/my-results', True, False, 'getMyAssessmentResults'),
+    ('__tests__/api/api.test', 'POST', '/api/dan-assessment/order/pay', True, False, 'payAssessmentOrder'),
+    ('__tests__/api/api.test', 'POST', '/api/dan-assessment/result/record', False, False, 'recordAssessmentResult'),
+    ('__tests__/api/api.test', 'POST', '/api/energy/logs', True, False, 'getEnergyLogs'),
+    ('__tests__/api/api.test', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('__tests__/api/api.test', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('__tests__/api/api.test', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/children', True, False, 'createChild'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/children/update', True, False, 'updateChild'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/create-family', True, False, 'createFamily'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/kick', True, False, 'kickFamilyMember'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/members/update-visibility', True, False, 'updateMemberVisibility'),
+    ('__tests__/api/api.test', 'POST', '/api/game/history', True, False, 'getGameHistory'),
+    ('__tests__/api/api.test', 'POST', '/api/game/leaderboard', True, False, 'getGameLeaderboard'),
+    ('__tests__/api/api.test', 'POST', '/api/growth/record/create', True, False, 'createGrowthRecord'),
+    ('__tests__/api/api.test', 'POST', '/api/growth/record/create-with-order', True, False, 'createGrowthRecord'),
+    ('__tests__/api/api.test', 'POST', '/api/growth/record/list', True, False, 'getGrowthRecordList'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/bind/invite', True, False, 'generateBindInvite'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/families', True, False, 'getBoundFamilies'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/messages/list', True, False, 'getGuideMessages'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/orders/list', True, False, 'getGuideOrders'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/packages/my', True, False, 'getGuidePackages'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/register', False, False, 'registerGuide'),
+    ('__tests__/api/api.test', 'POST', '/api/guide/team/members', True, False, 'getTeamMembers'),
+    ('__tests__/api/api.test', 'POST', '/api/health/checkin/list', True, False, 'healthCheckinList'),
+    ('__tests__/api/api.test', 'POST', '/api/health/indicator/list', True, False, 'getHealthIndicatorList'),
+    ('__tests__/api/api.test', 'POST', '/api/health/report/create', True, False, 'createHealthReport'),
+    ('__tests__/api/api.test', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('__tests__/api/api.test', 'POST', '/api/health/report/latest', True, False, 'getLatestHealthReport'),
+    ('__tests__/api/api.test', 'POST', '/api/health/report/list', True, False, 'getReportList'),
+    ('__tests__/api/api.test', 'POST', '/api/health/survey/create', True, False, 'createReportSurvey'),
+    ('__tests__/api/api.test', 'POST', '/api/health/survey/submit', True, False, 'submitReportSurvey'),
+    ('__tests__/api/api.test', 'POST', '/api/invite-card/generate', False, False, 'generateInviteCard'),
+    ('__tests__/api/api.test', 'POST', '/api/invite-card/verify', False, False, 'verifyInviteCard'),
+    ('__tests__/api/api.test', 'POST', '/api/invite/bind', True, False, 'bindReferral'),
+    ('__tests__/api/api.test', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('__tests__/api/api.test', 'POST', '/api/membership/levels', True, False, 'getMembershipLevels'),
+    ('__tests__/api/api.test', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('__tests__/api/api.test', 'POST', '/api/membership/orders', True, False, 'createOrder'),
+    ('__tests__/api/api.test', 'POST', '/api/mini-game//:var', True, True, 'getMiniGameByCode'),
+    ('__tests__/api/api.test', 'POST', '/api/mini-game/complete', True, False, 'completeMiniGame'),
+    ('__tests__/api/api.test', 'POST', '/api/mini-game/list', True, False, 'getMiniGameList'),
+    ('__tests__/api/api.test', 'POST', '/api/packages//:var/publish', True, True, 'publishPackage'),
+    ('__tests__/api/api.test', 'POST', '/api/points/balance', True, False, 'getPointsBalance'),
+    ('__tests__/api/api.test', 'POST', '/api/points/logs', True, False, 'getPointsLogs'),
+    ('__tests__/api/api.test', 'POST', '/api/product/create', False, False, 'productCreate'),
+    ('__tests__/api/api.test', 'POST', '/api/product/detail', False, False, 'productDetail'),
+    ('__tests__/api/api.test', 'POST', '/api/product/list', False, False, 'productList'),
+    ('__tests__/api/api.test', 'POST', '/api/product/order/create', False, False, 'productOrderCreate'),
+    ('__tests__/api/api.test', 'POST', '/api/rewards', True, False, 'createReward'),
+    ('__tests__/api/api.test', 'POST', '/api/rewards//:var/exchange', True, True, 'exchangeReward'),
+    ('__tests__/api/api.test', 'POST', '/api/rewards/wishlist', True, False, 'getWishlist'),
+    ('__tests__/api/api.test', 'POST', '/api/stats/child-completion', True, False, 'getChildCompletionStats'),
+    ('__tests__/api/api.test', 'POST', '/api/stats/child/overview', True, False, 'getChildOverview'),
+    ('__tests__/api/api.test', 'POST', '/api/survey/status', True, False, 'getSurveyStatus'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks//:var', True, True, 'deleteTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks//:var/complete', True, True, 'completeTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks//:var/review', True, True, 'approveTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks//:var/review', True, True, 'rejectTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks//:var/review', True, True, 'reviewTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/batch-complete', True, False, 'batchCompleteTasks'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/create', True, False, 'createTask'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/history', True, False, 'getTaskHistory'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/pending-review', True, False, 'getPendingReviewTasks'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/today', True, False, 'getTodayTasksByCategory'),
+    ('__tests__/api/api.test', 'POST', '/api/tasks/today-parent', True, False, 'getTodayParentTasks'),
+    ('__tests__/api/api.test', 'POST', '/api/user/info', True, False, 'getUserInfo'),
+    ('__tests__/api/api.test', 'POST', '/api/user/join-family', True, False, 'joinFamily'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/switch-back-to-parent', True, False, 'switchBackToParent'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/switch-mode', True, False, 'switchMode'),
+    ('__tests__/api/api.test', 'POST', '/api/family/user/switch-to-child', True, False, 'switchToChild'),
+    ('__tests__/api/api.test', 'POST', '/api/user/update', True, False, 'updateUserInfo'),
+    ('__tests__/api/api.test', 'POST', '/api/vendor/apply', True, False, 'vendorApply'),
+    ('__tests__/api/api.test', 'POST', '/api/vendor/info', False, False, 'vendorInfo'),
+    ('__tests__/api/api.test', 'POST', '/api/vendor/status', False, False, 'vendorStatus'),
+    ('__tests__/api/api.test', 'POST', '/api/wealth/checkin/list', True, False, 'getCheckinList'),
+    ('__tests__/api/api.test', 'POST', '/api/wealth/insurance/list', False, False, 'getInsuranceList'),
+    ('__tests__/api/api.test', 'POST', '/api/wishes//:var/approve-exchange', True, True, 'approveWishExchange'),
+    ('__tests__/api/api.test', 'POST', '/api/wishes//:var/price', True, True, 'setWishPrice'),
+    ('__tests__/api/api.test', 'POST', '/api/wishes/create', True, False, 'createWish'),
+    ('__tests__/api/api.test', 'POST', '/api/wishes/list', True, False, 'getWishes'),
+    ('__tests__/api/api.test', 'POST', '/api/wishes/pending', True, False, 'getPendingWishes'),
+    ('__tests__/api/api.test', 'POST', '/api/withdrawal/apply', True, False, 'applyWithdrawal'),
+    ('__tests__/store/store.test', 'POST', '/api/auth/switch-role', True, False, 'switchRole'),
+    ('components/DimensionActivities', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('components/DimensionActivities', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('components/DimensionProducts', 'POST', '/api/recommend/dimension-products', True, False, 'getDimensionProducts'),
+    ('components/DimensionTasks', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('components/MemberSelector', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('components/MemberSelector', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('components/MemberSelector', 'POST', '/api/family/relationship/pairwise', True, False, 'getPairwiseRelationships'),
+    ('components/MemberSelector', 'POST', '/api/family/user/create-family', True, False, 'createFamily'),
+    ('components/OnboardingGuide', 'POST', '/api/guide-config/current', True, False, 'getGuideConfig'),
+    ('components/OnboardingProgressBar', 'POST', '/api/onboarding/progress', True, False, 'getOnboardingProgress'),
+    ('components/RelatedContent', 'POST', '/api/content/related-items', True, False, 'getContentRelated'),
+    ('components/daily-task-card', 'POST', '/api/daily-task/overview', True, False, 'getDailyTaskOverview'),
+    ('components/login-sheet', 'POST', '/api/auth/wechat-phone-login', False, False, 'wechatPhoneLogin'),
+    ('components/share-mixin', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/achievement/index', 'POST', '/api/badges/child/list', True, False, 'getChildBadges'),
+    ('pages/action-detail/components/PearlDiagram', 'POST', '/api/pearl/interaction/add', True, False, 'addPearlInteraction'),
+    ('pages/action-detail/components/PearlDiagram', 'POST', '/api/pearl/item/update-priority', True, False, 'updatePearlPriority'),
+    ('pages/action-detail/contact-detail', 'POST', '/api/contact/delete', True, False, 'deleteContact'),
+    ('pages/action-detail/contact-detail', 'POST', '/api/contact/detail', True, False, 'getContactDetail'),
+    ('pages/action-detail/contact-detail', 'POST', '/api/contact/interaction', True, False, 'recordContactInteraction'),
+    ('pages/action-detail/contact-detail', 'POST', '/api/contact/update', True, False, 'updateContact'),
+    ('pages/action-detail/index', 'POST', '/api/ability/map', True, False, 'getAbilityMap'),
+    ('pages/action-detail/index', 'POST', '/api/content-sections/visible', True, False, 'getVisibleSections'),
+    ('pages/action-detail/index', 'POST', '/api/dimension/radar-data', True, False, 'getRadarData'),
+    ('pages/action-detail/index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/action-detail/index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/action-detail/index', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/action-detail/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/action-detail/index', 'POST', '/api/octopus/analysis/summary', True, False, 'getOctopusAnalysisSummary'),
+    ('pages/action-detail/index', 'POST', '/api/octopus/effect/key-persons', True, False, 'getOctopusEffectKeyPersons'),
+    ('pages/action-detail/index', 'POST', '/api/octopus/effect/list', True, False, 'getOctopusEffects'),
+    ('pages/action-detail/index', 'POST', '/api/pearl/item/delete', True, False, 'deletePearlResource'),
+    ('pages/action-detail/index', 'POST', '/api/pearl/reminder/list', True, False, 'getPearlReminders'),
+    ('pages/action-detail/index', 'POST', '/api/pearl/resources', True, False, 'getPearlResources'),
+    ('pages/action-detail/interaction-log', 'POST', '/api/family/interaction/add', True, False, 'addInteraction'),
+    ('pages/action-detail/interaction-log', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/action-detail/interaction-log', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/action-detail/member-action-detail', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/action-detail/member-action-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/action-detail/octopus-add-effect', 'POST', '/api/octopus/effect/add', True, False, 'addOctopusEffect'),
+    ('pages/action-detail/octopus-add-effect', 'POST', '/api/octopus/key-person/bind-system-user', True, False, 'bindOctopusKeyPersonSystemUser'),
+    ('pages/action-detail/octopus-add-effect', 'POST', '/api/octopus/key-person/list', True, False, 'getOctopusKeyPersons'),
+    ('pages/action-detail/octopus-add-effect', 'POST', '/api/octopus/key-person/match-by-phone', True, False, 'matchOctopusKeyPersonByPhone'),
+    ('pages/action-detail/octopus-add-key-person', 'POST', '/api/octopus/key-person/add', True, False, 'addOctopusKeyPerson'),
+    ('pages/action-detail/octopus-add-key-person', 'POST', '/api/octopus/key-person/list', True, False, 'getOctopusKeyPersons'),
+    ('pages/action-detail/octopus-effects-list', 'POST', '/api/octopus/effect/delete', True, False, 'deleteOctopusEffect'),
+    ('pages/action-detail/octopus-effects-list', 'POST', '/api/octopus/effect/list', True, False, 'getOctopusEffects'),
+    ('pages/action-detail/pearl-add-resource', 'POST', '/api/contact/list', True, False, 'getContactList'),
+    ('pages/action-detail/pearl-add-resource', 'POST', '/api/pearl/connection-types', True, False, 'getConnectionTypes'),
+    ('pages/action-detail/pearl-add-resource', 'POST', '/api/pearl/item/add', True, False, 'addPearlResource'),
+    ('pages/action-detail/relationship-questionnaire', 'POST', '/api/family/questionnaire/generate', True, False, 'generateQuestionnaire'),
+    ('pages/action-detail/relationship-questionnaire', 'POST', '/api/family/questionnaire/submit', True, False, 'submitQuestionnaire'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/cancel-registration', False, False, 'cancelActivityRegistration'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/checkin', False, False, 'activityCheckin'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/detail', False, False, 'getActivityDetail'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/feedback/my', False, False, 'getMyActivityFeedback'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/feedback/submit', False, False, 'submitActivityFeedback'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/order/create', False, False, 'createActivityOrder'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/activity/registration-roster', False, False, 'getActivityRegistrationRoster'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/poster-template/list', True, False, 'getPosterTemplates'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/share/qrcode', True, False, 'getShareQrCode'),
+    ('pages/activity/activity-detail/activity-detail', 'POST', '/api/user/profile/backfill', True, False, 'backfillProfile'),
+    ('pages/activity/create', 'POST', '/api/activity/create', False, False, 'adminCreateActivity'),
+    ('pages/activity/create', 'POST', '/api/activity/detail', False, False, 'getActivityDetail'),
+    ('pages/activity/create', 'POST', '/api/activity/publish', False, False, 'adminPublishActivity'),
+    ('pages/activity/create', 'POST', '/api/activity/submit-review', False, False, 'submitActivityForReview'),
+    ('pages/activity/create', 'POST', '/api/activity/update', False, False, 'adminUpdateActivity'),
+    ('pages/activity/create', 'POST', '/api/poster-template/list', True, False, 'getPosterTemplates'),
+    ('pages/activity/index', 'POST', '/api/activity/cancel-registration', False, False, 'cancelActivityRegistration'),
+    ('pages/activity/index', 'POST', '/api/activity/checkin', False, False, 'activityCheckin'),
+    ('pages/activity/index', 'POST', '/api/activity/end', False, False, 'adminEndActivity'),
+    ('pages/activity/index', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/activity/index', 'POST', '/api/activity/my-registrations', False, False, 'getMyActivityRegistrations'),
+    ('pages/activity/index', 'POST', '/api/activity/publish', False, False, 'adminPublishActivity'),
+    ('pages/activity/index', 'POST', '/api/activity/submit-review', False, False, 'submitActivityForReview'),
+    ('pages/activity/index', 'POST', '/api/admin/activity/list', False, False, 'adminListMyActivities'),
+    ('pages/activity/index', 'POST', '/api/admin/activity/withdraw', False, False, 'adminWithdrawActivity'),
+    ('pages/activity/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/activity/index', 'POST', '/api/vendor/status', False, False, 'vendorStatus'),
+    ('pages/activity/order-pay/order-pay', 'POST', '/api/activity/order/handlePaymentSuccess', False, False, 'handleActivityOrderSuccess'),
+    ('pages/activity/order-pay/order-pay', 'POST', '/api/activity/order/pay', False, False, 'payActivityOrder'),
+    ('pages/ai/chat', 'POST', '/api/ai/butler/send', False, False, 'aiSendHealthButlerMessage'),
+    ('pages/ai/chat', 'POST', '/api/ai/chat/conversations', True, False, 'aiGetConversations'),
+    ('pages/ai/chat', 'POST', '/api/ai/chat/messages', True, False, 'aiGetMessages'),
+    ('pages/ai/chat', 'POST', '/api/ai/health-coach/send', True, False, 'aiSendHealthCoachMessage'),
+    ('pages/ai/chat', 'POST', '/api/ai/nutrition/send', True, False, 'aiSendNutritionMessage'),
+    ('pages/ai/chat', 'POST', '/api/ai/transcribe', True, False, 'sttTranscribe'),
+    ('pages/ai/chat', 'POST', '/api/basic-quota/status/all', True, False, 'getAllQuotaStatus'),
+    ('pages/ai/chat', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/ai/chat', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/audio', False, False, 'getArticleAudio'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/complete-read', False, False, 'completeArticleRead'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/detail', False, False, 'getArticleDetail'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/quiz/generate', False, False, 'generateQuiz'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/quiz/submit', False, False, 'submitQuiz'),
+    ('pages/article-center/article-detail', 'POST', '/api/articles/report-reading-time', False, False, 'reportReadingTime'),
+    ('pages/article-center/article-detail', 'POST', '/api/share/qrcode', True, False, 'getShareQrCode'),
+    ('pages/article-center/article-detail', 'POST', '/api/tasks//:var/complete', True, True, 'completeTask'),
+    ('pages/article-center/article-edit', 'POST', '/api/articles/publish', False, False, 'publishArticle'),
+    ('pages/article-center/index', 'POST', '/api/articles/featured', False, False, 'getFeaturedArticles'),
+    ('pages/article-center/index', 'POST', '/api/articles/list', False, False, 'getArticleList'),
+    ('pages/article-center/my-posts', 'POST', '/api/articles/my-posts', False, False, 'getMyPosts'),
+    ('pages/assessment-plan/detail', 'POST', '/api/dan-assessment/result/plans/list', False, False, 'getMyAssessmentPlans'),
+    ('pages/assessment-plan/list', 'POST', '/api/dan-assessment/result/plans/list', False, False, 'getMyAssessmentPlans'),
+    ('pages/assessment/apply', 'POST', '/api/assessment/appointment/create', True, False, 'createAssessmentAppointmentWithQuota'),
+    ('pages/assessment/apply', 'POST', '/api/assessment/quota/my-list', True, False, 'getAssessmentQuotas'),
+    ('pages/assessment/apply', 'POST', '/api/guide/invite-code/validate', False, False, 'validateInviteCode'),
+    ('pages/assessment/apply', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/assessment/apply', 'POST', '/api/package/available-guides', True, False, 'getAvailableGuides'),
+    ('pages/assessment/purchase', 'POST', '/api/dan-assessment/order/create', True, False, 'createAssessmentOrder'),
+    ('pages/assessment/purchase', 'POST', '/api/dan-assessment/order/detail', True, False, 'getAssessmentOrderDetail'),
+    ('pages/assessment/purchase', 'POST', '/api/guide/invite-code/validate', False, False, 'validateInviteCode'),
+    ('pages/assessment/purchase', 'POST', '/api/package/available-guides', True, False, 'getAvailableGuides'),
+    ('pages/assessment/quota', 'POST', '/api/assessment/quota/my-list', True, False, 'getAssessmentQuotas'),
+    ('pages/assessment/results', 'POST', '/api/dan-assessment/child-results', True, False, 'getChildAssessmentResults'),
+    ('pages/assessment/results', 'POST', '/api/dan-assessment/my-results', True, False, 'getMyAssessmentResults'),
+    ('pages/assessment/upload-report', 'POST', '/api/dan-assessment/result/upload', False, False, 'uploadAssessmentReport'),
+    ('pages/body-detail/dimension-detail', 'POST', '/api/dimension/history', True, False, 'getDimensionHistory'),
+    ('pages/body-detail/dimension-detail', 'POST', '/api/dimension/overview', True, False, 'getDimensionOverview'),
+    ('pages/body-detail/dimension-questionnaire', 'POST', '/api/articles/submit-answers', False, False, 'submitAnswers'),
+    ('pages/body-detail/dimension-questionnaire', 'POST', '/api/dimension/questionnaire', True, False, 'submitDimensionQuestionnaire'),
+    ('pages/body-detail/health-dimensions', 'POST', '/api/dimension/overview', True, False, 'getDimensionOverview'),
+    ('pages/body-detail/health-dimensions', 'POST', '/api/dimension/upload', True, False, 'uploadDimensionScore'),
+    ('pages/body-detail/health-report', 'POST', '/api/health/nutrition/deficiency', True, False, 'getDeficiencyAnalysis'),
+    ('pages/body-detail/index', 'POST', '/api/content-sections/visible', True, False, 'getVisibleSections'),
+    ('pages/body-detail/index', 'POST', '/api/dimension/overview', True, False, 'getDimensionOverview'),
+    ('pages/body-detail/index', 'POST', '/api/dimension/radar-data', True, False, 'getRadarData'),
+    ('pages/body-detail/index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/body-detail/index', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/body-detail/index', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('pages/body-detail/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/body-detail/index', 'POST', '/api/health/gut-flora', True, False, 'getGutFloraIndicators'),
+    ('pages/body-detail/index', 'POST', '/api/health/indicators', True, False, 'getLatestIndicators'),
+    ('pages/body-detail/index', 'POST', '/api/health/report/body-abnormal', True, False, 'getBodyAbnormalIndicators'),
+    ('pages/body-detail/member-body-detail', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/body-detail/member-body-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/butler/apply', 'POST', '/api/butler/apply', False, False, 'butlerApply'),
+    ('pages/butler/select', 'POST', '/api/butler/available-list', False, False, 'getAvailableButlers'),
+    ('pages/butler/select', 'POST', '/api/butler/my-butler', False, False, 'getMyButler'),
+    ('pages/butler/select', 'POST', '/api/butler/select', False, False, 'selectButler'),
+    ('pages/child/rewards', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('pages/child/rewards', 'POST', '/api/points/balance', True, False, 'getPointsBalance'),
+    ('pages/child/rewards', 'POST', '/api/rewards/wishlist', True, False, 'getWishlist'),
+    ('pages/child/rewards', 'POST', '/api/family/user/switch-back-to-parent', True, False, 'switchBackToParent'),
+    ('pages/child/tasks', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('pages/child/tasks', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/child/tasks', 'POST', '/api/family/user/switch-back-to-parent', True, False, 'switchBackToParent'),
+    ('pages/cognitive-hall', 'POST', '/api/cognitive/child', True, False, 'getCognitiveChildScores'),
+    ('pages/cognitive-hall', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/cognitive-test/language-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/cognitive-test/logic-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/cognitive-test/memory-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/cognitive-test/perception-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/cognitive-test/spatial-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/cognitive-test/speed-test', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/dan-assessment/comparison', 'POST', '/api/dan-report/compare', True, False, 'compareDanReports'),
+    ('pages/dan-assessment/comparison', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/diet/index', 'POST', '/api/diet/ingredients/add', True, False, 'addDietIngredient'),
+    ('pages/diet/index', 'POST', '/api/diet/ingredients/recommend', True, False, 'refreshDietIngredients'),
+    ('pages/diet/index', 'POST', '/api/diet/ingredients/remove', True, False, 'removeDietIngredient'),
+    ('pages/diet/index', 'POST', '/api/diet/ingredients/search', True, False, 'searchDietFoods'),
+    ('pages/diet/index', 'POST', '/api/diet/ingredients/suggest', True, False, 'getDietIngredients'),
+    ('pages/diet/index', 'POST', '/api/diet/meals/config', True, False, 'getMealConfig'),
+    ('pages/diet/index', 'POST', '/api/diet/recommendation/generate', True, False, 'generateDietRecommendation'),
+    ('pages/diet/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/diet/meal-config', 'POST', '/api/diet/meals/config', True, False, 'getMealConfig'),
+    ('pages/diet/meal-config', 'POST', '/api/diet/meals/config/save', False, False, 'saveMealConfig'),
+    ('pages/diet/preferences', 'POST', '/api/diet/preferences/current-member', True, False, 'getDietPreferences'),
+    ('pages/diet/preferences', 'POST', '/api/diet/preferences/save', True, False, 'saveDietPreferences'),
+    ('pages/diet/recommendation', 'POST', '/api/diet/recommendation/complete', True, False, 'completeDietRecommendation'),
+    ('pages/diet/recommendation', 'POST', '/api/diet/recommendation/generate', True, False, 'generateDietRecommendation'),
+    ('pages/diet/recommendation', 'POST', '/api/diet/recommendation/regenerate', True, False, 'regenerateDietRecommendation'),
+    ('pages/diet/recommendation', 'POST', '/api/diet/recommendation/today', True, False, 'getDietRecommendation'),
+    ('pages/diet/record-detail', 'POST', '/api/diet/record/daily', True, False, 'getDietDailyRecords'),
+    ('pages/diet/records', 'POST', '/api/food/recommendation/members', True, False, 'getCautionFamilyMembers'),
+    ('pages/diet/records', 'POST', '/api/health/meal/alerts', True, False, 'getMealAlerts'),
+    ('pages/diet/records', 'POST', '/api/health/meal/daily', True, False, 'getMealDaily'),
+    ('pages/diet/records', 'POST', '/api/health/meal/weekly', True, False, 'getMealWeekly'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/cart/add', True, False, 'cartAdd'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/product/detail', False, False, 'productDetail'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/product/order/pay', False, False, 'productOrderPay'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/product/spec/map', False, False, 'productSpecMap'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/share/qrcode', True, False, 'getShareQrCode'),
+    ('pages/discover-detail/product-detail/product-detail', 'POST', '/api/special-price/info', True, False, 'getSpecialPriceInfo'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/comment/add', True, False, 'addCircleComment'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/comment/list', True, False, 'getCircleComments'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/feed', False, False, 'getCircleFeed'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/members', True, False, 'getCircleMembers'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/post/create', True, False, 'createCirclePost'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/post/delete', True, False, 'deleteCirclePost'),
+    ('pages/discover/circle-feed', 'POST', '/api/circle/post/like', True, False, 'toggleCircleLike'),
+    ('pages/discover/circles', 'POST', '/api/circle/approve', True, False, 'approveCircleMember'),
+    ('pages/discover/circles', 'POST', '/api/circle/discover', True, False, 'discoverCircles'),
+    ('pages/discover/circles', 'POST', '/api/circle/join', True, False, 'joinGeneralCircle'),
+    ('pages/discover/circles', 'POST', '/api/circle/leave', True, False, 'leaveGeneralCircle'),
+    ('pages/discover/circles', 'POST', '/api/circle/my-circles', True, False, 'getMyCircles'),
+    ('pages/discover/circles', 'POST', '/api/circle/pending-members', True, False, 'getPendingCircleMembers'),
+    ('pages/discover/circles', 'POST', '/api/circle/update', True, False, 'updateCircle'),
+    ('pages/discover/circles', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/discover/create-circle', 'POST', '/api/circle/create', True, False, 'createGeneralCircle'),
+    ('pages/discover/index', 'POST', '/api/articles/featured', False, False, 'getFeaturedArticles'),
+    ('pages/discover/index', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/discover/index', 'POST', '/api/product/list', False, False, 'productList'),
+    ('pages/energy/detail', 'POST', '/api/energy/logs', True, False, 'getEnergyLogs'),
+    ('pages/energy/index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/energy/index', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/energy/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/family/add-member', 'POST', '/api/auth/check-phone', False, False, 'checkPhone'),
+    ('pages/family/add-member', 'POST', '/api/consent/record', True, False, 'recordConsent'),
+    ('pages/family/add-member', 'POST', '/api/family/member/add', True, False, 'addFamilyMember'),
+    ('pages/family/add-member', 'POST', '/api/family/member/update', True, False, 'updateFamilyMember'),
+    ('pages/family/manual-score-entry', 'POST', '/api/family/manual-score/submit', True, False, 'submitManualScore'),
+    ('pages/family/manual-score-entry', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/family/mbti-entry', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/family/mbti-profile', 'POST', '/api/family/mbti/profile', True, False, 'getMbtiProfile'),
+    ('pages/family/mbti-result', 'POST', '/api/family/mbti/latest', True, False, 'getMbtiLatest'),
+    ('pages/family/mbti-test', 'POST', '/api/family/mbti/questions', True, False, 'getMbtiQuestions'),
+    ('pages/family/mbti-test', 'POST', '/api/family/mbti/submit', True, False, 'submitMbti'),
+    ('pages/family/self-check', 'POST', '/api/family/self-check/submit', True, False, 'submitSelfCheck'),
+    ('pages/family/self-check-ai', 'POST', '/api/family/self-check/submit', True, False, 'submitSelfCheck'),
+    ('pages/family/self-check-entry', 'POST', '/api/family/self-check/ignore', True, False, 'ignoreSelfCheck'),
+    ('pages/family/self-check-entry', 'POST', '/api/family/self-check/status', True, False, 'getSelfCheckStatus'),
+    ('pages/family/self-check-entry', 'POST', '/api/family/self-check/trend-analysis', True, False, 'getSelfCheckTrendAnalysis'),
+    ('pages/family/self-check-result', 'POST', '/api/family/self-check/generate-plan', True, False, 'generateSelfCheckPlan'),
+    ('pages/family/self-check-result', 'POST', '/api/family/self-check/history', True, False, 'getSelfCheckHistory'),
+    ('pages/family/self-check-result', 'POST', '/api/family/self-check/latest', True, False, 'getSelfCheckLatest'),
+    ('pages/family/self-check-result', 'POST', '/api/micro-action/complete', True, False, 'microActionComplete'),
+    ('pages/family/self-check-result', 'POST', '/api/micro-action/today', True, False, 'microActionToday'),
+    ('pages/games/1a2b', 'POST', '/api/mini-game/complete', True, False, 'completeMiniGame'),
+    ('pages/games/list', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/games/list', 'POST', '/api/mini-game/list', True, False, 'getMiniGameList'),
+    ('pages/games/records', 'POST', '/api/game/history', True, False, 'getGameHistory'),
+    ('pages/games/schulte', 'POST', '/api/mini-game/complete', True, False, 'completeMiniGame'),
+    ('pages/games/stats', 'POST', '/api/game/best', True, False, 'getGameBestScores'),
+    ('pages/games/stats', 'POST', '/api/game/leaderboard', True, False, 'getGameLeaderboard'),
+    ('pages/games/stats', 'POST', '/api/game/stats', True, False, 'getGameStats'),
+    ('pages/games/sudoku', 'POST', '/api/mini-game/complete', True, False, 'completeMiniGame'),
+    ('pages/growth-main/index', 'POST', '/api/food/recommendation/caution', True, False, 'getFoodCautionList'),
+    ('pages/growth-main/index', 'POST', '/api/growth/recommendations', True, False, 'getGrowthRecommendations'),
+    ('pages/growth-main/index', 'POST', '/api/health/checkin/list', True, False, 'healthCheckinList'),
+    ('pages/growth-main/index', 'POST', '/api/health/exercise/list', True, False, 'getExerciseRecords'),
+    ('pages/growth-main/index', 'POST', '/api/health/meal/list', True, False, 'getHealthMealList'),
+    ('pages/growth-main/index', 'POST', '/api/health/sleep/list', True, False, 'getSleepRecords'),
+    ('pages/growth-main/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/growth-main/index', 'POST', '/api/mind/checkin/list', True, False, 'getEmotionCheckinList'),
+    ('pages/growth-main/index', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/growth-main/index', 'POST', '/api/wealth/checkin/list', True, False, 'getCheckinList'),
+    ('pages/growth/caution-detail', 'POST', '/api/food/recommendation/caution', True, False, 'getFoodCautionList'),
+    ('pages/growth/caution-detail', 'POST', '/api/food/recommendation/members', True, False, 'getCautionFamilyMembers'),
+    ('pages/growth/caution-detail', 'POST', '/api/food/recommendation/trend', True, False, 'getFoodCautionTrend'),
+    ('pages/growth/caution-detail', 'POST', '/api/health/knowledge/v3/section', True, False, 'getKnowledgeSection'),
+    ('pages/growth/challenge-progress', 'POST', '/api/purchase/challenge/progress', True, False, 'getChallengeProgress'),
+    ('pages/growth/create', 'POST', '/api/growth/record/create', True, False, 'createGrowthRecord'),
+    ('pages/growth/create', 'POST', '/api/growth/record/create-with-order', True, False, 'createGrowthRecord'),
+    ('pages/growth/diet-checkin', 'POST', '/api/ai/transcribe', True, False, 'sttTranscribe'),
+    ('pages/growth/diet-checkin', 'POST', '/api/basic-quota/status/all', True, False, 'getAllQuotaStatus'),
+    ('pages/growth/exercise-checkin', 'POST', '/api/ai/transcribe', True, False, 'sttTranscribe'),
+    ('pages/growth/supplement', 'POST', '/api/growth/record/supplement', True, False, 'createGrowthSupplement'),
+    ('pages/growth/supplement', 'POST', '/api/growth/record/upload-and-parse', True, False, 'uploadAndParseReport'),
+    ('pages/growth/upload', 'POST', '/api/growth/record/create-from-upload', True, False, 'createGrowthRecordFromUpload'),
+    ('pages/growth/upload', 'POST', '/api/growth/record/upload-and-parse', True, False, 'uploadAndParseReport'),
+    ('pages/growth/upload', 'POST', '/api/product/list', False, False, 'productList'),
+    ('pages/guide/activities/detail', 'POST', '/api/guide/activities/create', True, False, 'createActivity'),
+    ('pages/guide/activities/detail', 'POST', '/api/guide/activities/detail', True, False, 'getGuideActivityDetail'),
+    ('pages/guide/activities/detail', 'POST', '/api/guide/activities/publish', True, False, 'publishActivity'),
+    ('pages/guide/activities/detail', 'POST', '/api/guide/activities/update', True, False, 'updateActivity'),
+    ('pages/guide/activities/index', 'POST', '/api/guide/activities/cancel', True, False, 'cancelActivity'),
+    ('pages/guide/activities/index', 'POST', '/api/guide/activities/delete', True, False, 'deleteActivity'),
+    ('pages/guide/activities/index', 'POST', '/api/guide/activities/list', True, False, 'getGuideActivityList'),
+    ('pages/guide/activities/index', 'POST', '/api/guide/activities/publish', True, False, 'publishActivity'),
+    ('pages/guide/bind/invite', 'POST', '/api/common/qrcode', True, False, 'generateQrCodeFromText'),
+    ('pages/guide/bind/invite', 'POST', '/api/guide/bind/confirm', True, False, 'confirmBind'),
+    ('pages/guide/bind/invite', 'POST', '/api/guide/bind/invite', True, False, 'generateBindInvite'),
+    ('pages/guide/hierarchy/index', 'POST', '/api/guide/all-child-guides', True, False, 'getAllChildGuides'),
+    ('pages/guide/hierarchy/index', 'POST', '/api/guide/child-guides', True, False, 'getChildGuides'),
+    ('pages/guide/hierarchy/index', 'POST', '/api/guide/parent-guide', True, False, 'getParentGuide'),
+    ('pages/guide/packages/create', 'POST', '/api/packages', True, False, 'createPackage'),
+    ('pages/guide/packages/detail', 'POST', '/api/packages//:var/items', True, True, 'addPackageItem'),
+    ('pages/guide/packages/index', 'POST', '/api/packages//:var/publish', True, True, 'publishPackage'),
+    ('pages/guide/packages/index', 'POST', '/api/packages//:var/submit', True, True, 'submitPackageForReview'),
+    ('pages/guide/register/index', 'POST', '/api/guide/invite-code/validate', False, False, 'validateInviteCode'),
+    ('pages/guide/register/index', 'POST', '/api/guide/register', False, False, 'registerGuide'),
+    ('pages/health-main/index', 'POST', '/api/articles/featured', False, False, 'getFeaturedArticles'),
+    ('pages/health-main/index', 'POST', '/api/cognitive/child', True, False, 'getCognitiveChildScores'),
+    ('pages/health-main/index', 'POST', '/api/cognitive/family', True, False, 'getCognitiveFamilyScores'),
+    ('pages/health-main/index', 'POST', '/api/dimension/overview', True, False, 'getDimensionOverview'),
+    ('pages/health-main/index', 'POST', '/api/emireport/latest', True, False, 'getEmiReport'),
+    ('pages/health-main/index', 'POST', '/api/energy/wealth-detail', True, False, 'getWealthDetail'),
+    ('pages/health-main/index', 'POST', '/api/family/relationship/scores', True, False, 'getRelationshipScores'),
+    ('pages/health-main/index', 'POST', '/api/health/plan/list', True, False, 'getHealthPlanList'),
+    ('pages/health-main/index', 'POST', '/api/health/report/list', True, False, 'getReportList'),
+    ('pages/health-main/index', 'POST', '/api/survey/status', True, False, 'getSurveyStatus'),
+    ('pages/health/bodyfat-confirm', 'POST', '/api/health/report/bodyfat-save', True, False, 'saveBodyFatMetrics'),
+    ('pages/health/challenge-manage', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/challenge-manage', 'POST', '/api/health/challenge/create', True, False, 'createChallenge'),
+    ('pages/health/challenge-manage', 'POST', '/api/health/challenge/history', True, False, 'getChallengeHistory'),
+    ('pages/health/challenge-manage', 'POST', '/api/health/challenge/list', True, False, 'getChallengeList'),
+    ('pages/health/challenge-manage', 'POST', '/api/health/challenge/respond', True, False, 'respondChallenge'),
+    ('pages/health/challenge-manage', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/health/components/MemberChipPicker', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/components/feedback-popup', 'POST', '/api/health/feedback/submit', False, False, 'submitFeedback'),
+    ('pages/health/doa-index', 'POST', '/api/doa/overview', True, False, 'getDoaOverview'),
+    ('pages/health/doa-stage-create', 'POST', '/api/doa/stage/create', True, False, 'createDoaStage'),
+    ('pages/health/doa-stage-create', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/doa-stage-detail', 'POST', '/api/doa/stage/cancel', True, False, 'cancelDoaStage'),
+    ('pages/health/doa-stage-detail', 'POST', '/api/doa/stage/detail', True, False, 'getDoaStageDetail'),
+    ('pages/health/doa-week-edit', 'POST', '/api/doa/stage/detail', True, False, 'getDoaStageDetail'),
+    ('pages/health/doa-week-edit', 'POST', '/api/doa/week/plan', True, False, 'submitDoaWeekPlan'),
+    ('pages/health/doa-week-edit', 'POST', '/api/doa/week/review', True, False, 'submitDoaWeekReview'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/family/member/add', True, False, 'addFamilyMember'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/food/recommendation/caution', True, False, 'getFoodCautionList'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/foods', True, False, 'getHealthFoods'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/knowledge/query', True, False, 'queryKnowledgeBase'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/knowledge/v3/indicator/query', True, False, 'queryIndicatorKnowledge'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/report/confirm', True, False, 'confirmReportPreview'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/report/discard', True, False, 'discardReportDraft'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/report/edit', True, False, 'editHealthReport'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/health/report/parse', True, False, 'parseReportDraft'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/indicator/change-ranking', True, False, 'getIndicatorChangeRanking'),
+    ('pages/health/gut-flora-detail', 'POST', '/api/nutrition/beijing/analysis', True, False, 'getGutFloraAnalysis'),
+    ('pages/health/gut-flora-foods-detail', 'POST', '/api/food/recommendation/members', True, False, 'getCautionFamilyMembers'),
+    ('pages/health/gut-flora-foods-detail', 'POST', '/api/food/recommendation/trend', True, False, 'getFoodCautionTrend'),
+    ('pages/health/gut-flora-foods-detail', 'POST', '/api/health/foods', True, False, 'getHealthFoods'),
+    ('pages/health/gut-flora-foods-detail', 'POST', '/api/health/knowledge/v3/food/query', True, False, 'queryFoodKnowledge'),
+    ('pages/health/gut-flora-foods-detail', 'POST', '/api/health/report/edit', True, False, 'editHealthReport'),
+    ('pages/health/gut-flora-risks-detail', 'POST', '/api/health/knowledge/query', True, False, 'queryKnowledgeBase'),
+    ('pages/health/gut-flora-risks-detail', 'POST', '/api/health/knowledge/unified/disease/query', True, False, 'queryDiseaseKnowledge'),
+    ('pages/health/gut-flora-risks-detail', 'POST', '/api/health/knowledge/v3/indicator/query', True, False, 'queryIndicatorKnowledge'),
+    ('pages/health/gut-flora-risks-detail', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('pages/health/gut-flora-risks-detail', 'POST', '/api/health/report/edit', True, False, 'editHealthReport'),
+    ('pages/health/gut-flora-species-detail', 'POST', '/api/health/knowledge/query', True, False, 'queryKnowledgeBase'),
+    ('pages/health/gut-flora-species-detail', 'POST', '/api/health/knowledge/v3/bacteria/query', True, False, 'queryBacteriaKnowledge'),
+    ('pages/health/gut-flora-species-detail', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('pages/health/gut-flora-species-detail', 'POST', '/api/health/report/edit', True, False, 'editHealthReport'),
+    ('pages/health/health-plan-summary', 'POST', '/api/diet/preferences/current-member', True, False, 'getDietPreferences'),
+    ('pages/health/health-plan-summary', 'POST', '/api/diet/preferences/save', True, False, 'saveDietPreferences'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health-status/get', True, False, 'getHealthStatus'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health-status/save', True, False, 'saveHealthStatus'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health-status/signature', True, False, 'saveHealthSignature'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health/plan/confirm', True, False, 'confirmPlan'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health/plan/detail', True, False, 'getHealthPlanDetail'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health/plan/generate', True, False, 'generateHealthPlan'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health/plan/regenerate-section', True, False, 'regenerateSection'),
+    ('pages/health/health-plan-summary', 'POST', '/api/health/plan/save', True, False, 'saveHealthPlan'),
+    ('pages/health/health-plan-summary', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/health/health-status-form', 'POST', '/api/health-status/get', True, False, 'getHealthStatus'),
+    ('pages/health/health-status-form', 'POST', '/api/health-status/save', True, False, 'saveHealthStatus'),
+    ('pages/health/health-survey', 'POST', '/api/diet/preferences/current-member', True, False, 'getDietPreferences'),
+    ('pages/health/health-survey', 'POST', '/api/diet/preferences/save', True, False, 'saveDietPreferences'),
+    ('pages/health/health-survey', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/health-survey', 'POST', '/api/health-status/get', True, False, 'getHealthStatus'),
+    ('pages/health/health-survey', 'POST', '/api/health-status/save', True, False, 'saveHealthStatus'),
+    ('pages/health/health-survey', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/health/indicator-curve', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/indicator-curve', 'POST', '/api/indicator/change-ranking', True, False, 'getIndicatorChangeRanking'),
+    ('pages/health/indicator-curve', 'POST', '/api/indicator/trend', True, False, 'getIndicatorTrend'),
+    ('pages/health/indicator-quicklook', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/indicator-quicklook', 'POST', '/api/indicator/quick-lookup', True, False, 'getIndicatorQuickLookup'),
+    ('pages/health/my-feedback', 'POST', '/api/health/feedback/list', False, False, 'getMyReportFeedbacks'),
+    ('pages/health/nutrition-profile', 'POST', '/api/health/nutrition/deficiency', True, False, 'getDeficiencyAnalysis'),
+    ('pages/health/nutrition-profile', 'POST', '/api/health/nutrition/profile', True, False, 'getChildNutritionProfile'),
+    ('pages/health/physical-exam-detail', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('pages/health/plan-list', 'POST', '/api/health/plan/delete', True, False, 'deleteHealthPlan'),
+    ('pages/health/plan-list', 'POST', '/api/health/plan/list', True, False, 'getHealthPlanList'),
+    ('pages/health/report-confirm', 'POST', '/api/family/member/add', True, False, 'addFamilyMember'),
+    ('pages/health/report-confirm', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/report-confirm', 'POST', '/api/health/report/parse', True, False, 'parseReportDraft'),
+    ('pages/health/report-detail', 'POST', '/api/family/member/add', True, False, 'addFamilyMember'),
+    ('pages/health/report-detail', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/report-detail', 'POST', '/api/health/report/edit', True, False, 'editHealthReport'),
+    ('pages/health/report-detail', 'POST', '/api/health/report/parse', True, False, 'parseReportDraft'),
+    ('pages/health/report-detail', 'POST', '/api/health/report/payload', True, False, 'getReportPayload'),
+    ('pages/health/report-list', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/report-list', 'POST', '/api/health/report/collecting-list', True, False, 'getCollectingReports'),
+    ('pages/health/report-list', 'POST', '/api/health/report/delete', True, False, 'deleteReport'),
+    ('pages/health/report-list', 'POST', '/api/health/report/list', True, False, 'getReportList'),
+    ('pages/health/report-list', 'POST', '/api/health/report/reassign', True, False, 'reassignReport'),
+    ('pages/health/report-list', 'POST', '/api/health/report/transfer/approve', True, False, 'approveReportTransfer'),
+    ('pages/health/report-list', 'POST', '/api/health/report/transfer/deny', True, False, 'denyReportTransfer'),
+    ('pages/health/report-list', 'POST', '/api/health/report/transfer/list', True, False, 'getReportTransferList'),
+    ('pages/health/report-survey', 'POST', '/api/health/survey/create', True, False, 'createReportSurvey'),
+    ('pages/health/report-survey', 'POST', '/api/health/survey/submit', True, False, 'submitReportSurvey'),
+    ('pages/health/report-survey', 'POST', '/api/survey/status', True, False, 'getSurveyStatus'),
+    ('pages/health/report-upload', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/health/report-upload', 'POST', '/api/health/report/collect/status', True, False, 'getReportCollectStatus'),
+    ('pages/health/report-upload', 'POST', '/api/health/report/transfer/request', True, False, 'requestReportTransfer'),
+    ('pages/health/report-upload', 'POST', '/api/health/report/upload-only', True, False, 'uploadReportOnly'),
+    ('pages/health/survey-history', 'POST', '/api/survey/history', True, False, 'getSurveyHistory'),
+    ('pages/health/survey-history', 'POST', '/api/survey/template/active', True, False, 'getActiveTemplates'),
+    ('pages/health/survey-questionnaire', 'POST', '/api/survey/submit', True, False, 'submitSurvey'),
+    ('pages/health/survey-questionnaire', 'POST', '/api/survey/template/active', True, False, 'getActiveTemplates'),
+    ('pages/health/teacher-service', 'POST', '/api/health-plan/available-teachers', True, False, 'getAvailableTeachers'),
+    ('pages/home-pages/child-index', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/home-pages/child-index', 'POST', '/api/energy/logs', True, False, 'getEnergyLogs'),
+    ('pages/home-pages/child-index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/home-pages/child-index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/home-pages/child-index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/home-pages/child-index', 'POST', '/api/guide-config/current', True, False, 'getGuideConfig'),
+    ('pages/home-pages/child-index', 'POST', '/api/guide/popup/consume', True, False, 'consumeGuidePopup'),
+    ('pages/home-pages/child-index', 'POST', '/api/guide/popup/list', True, False, 'getGuidePopupList'),
+    ('pages/home-pages/child-index', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/home-pages/child-index', 'POST', '/api/unlock/status', True, False, 'getUnlockStatus'),
+    ('pages/home-pages/child-index', 'POST', '/api/family/user/switch-mode', True, False, 'switchMode'),
+    ('pages/home-pages/components/AdBanner', 'POST', '/api/home-banner/list', True, False, 'getHomeBanners'),
+    ('pages/home-pages/components/ContactImport', 'POST', '/api/contact/import-phone', True, False, 'importPhoneContact'),
+    ('pages/home-pages/components/DailySummary', 'POST', '/api/feedback/read', False, False, 'markFeedbackRead'),
+    ('pages/home-pages/components/DailySummary', 'POST', '/api/feedback/today', False, False, 'getTodayFeedback'),
+    ('pages/home-pages/components/MicroActionCard', 'POST', '/api/micro-action/complete', True, False, 'microActionComplete'),
+    ('pages/home-pages/components/MicroActionCard', 'POST', '/api/micro-action/today', True, False, 'microActionToday'),
+    ('pages/home-pages/member-home-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/home-pages/parent-index', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/home-pages/parent-index', 'POST', '/api/articles/featured', False, False, 'getFeaturedArticles'),
+    ('pages/home-pages/parent-index', 'POST', '/api/contact/list', True, False, 'getContactList'),
+    ('pages/home-pages/parent-index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/home-pages/parent-index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/home-pages/parent-index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/home-pages/parent-index', 'POST', '/api/family/member/switch', True, False, 'switchToFamilyMember'),
+    ('pages/home-pages/parent-index', 'POST', '/api/family/self-check/status', True, False, 'getSelfCheckStatus'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/alert/dismiss', True, False, 'dismissAlert'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/alert/list', True, False, 'getActiveAlerts'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/challenge/list', True, False, 'getChallengeList'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/circle/list', True, False, 'getCircleList'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/circle/ranking', True, False, 'getCircleRanking'),
+    ('pages/home-pages/parent-index', 'POST', '/api/health/family/ranking', True, False, 'getFamilyRanking'),
+    ('pages/home-pages/parent-index', 'POST', '/api/invite/qrcode', True, False, 'getInviteQrCode'),
+    ('pages/home-pages/parent-index', 'POST', '/api/parent/dashboard', True, False, 'getParentDashboard'),
+    ('pages/home-pages/parent-index', 'POST', '/api/stats/child-completion', True, False, 'getChildCompletionStats'),
+    ('pages/home-pages/parent-index', 'POST', '/api/tasks//:var/review', True, True, 'approveTask'),
+    ('pages/home-pages/parent-index', 'POST', '/api/tasks//:var/review', True, True, 'rejectTask'),
+    ('pages/home-pages/parent-index', 'POST', '/api/tasks/pending-review', True, False, 'getPendingReviewTasks'),
+    ('pages/home-pages/parent-index', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/home-pages/parent-index', 'POST', '/api/unlock/status', True, False, 'getUnlockStatus'),
+    ('pages/home-pages/parent-index', 'POST', '/api/wishes/pending', True, False, 'getPendingWishes'),
+    ('pages/home/app-library', 'POST', '/api/home/app-library', True, False, 'getAppLibrary'),
+    ('pages/home/app-library', 'POST', '/api/home/shortcut/reset', True, False, 'resetShortcutConfig'),
+    ('pages/home/app-library', 'POST', '/api/home/shortcut/save', True, False, 'saveShortcutConfig'),
+    ('pages/index-home/index', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/index-home/index', 'POST', '/api/admin/notices/all', True, False, 'getNotices'),
+    ('pages/index-home/index', 'POST', '/api/articles/featured', False, False, 'getFeaturedArticles'),
+    ('pages/index-home/index', 'POST', '/api/commission/cf/list', True, False, 'getCfList'),
+    ('pages/index-home/index', 'POST', '/api/commission/cf/summary', True, False, 'getCfSummary'),
+    ('pages/index-home/index', 'POST', '/api/energy/logs', True, False, 'getEnergyLogs'),
+    ('pages/index-home/index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/index-home/index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/index-home/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/index-home/index', 'POST', '/api/family/member/switch', True, False, 'switchToFamilyMember'),
+    ('pages/index-home/index', 'POST', '/api/family/self-check/status', True, False, 'getSelfCheckStatus'),
+    ('pages/index-home/index', 'POST', '/api/guide-config/current', True, False, 'getGuideConfig'),
+    ('pages/index-home/index', 'POST', '/api/guide/parent-invite/accept', True, False, 'acceptParentInvite'),
+    ('pages/index-home/index', 'POST', '/api/guide/popup/consume', True, False, 'consumeGuidePopup'),
+    ('pages/index-home/index', 'POST', '/api/guide/popup/list', True, False, 'getGuidePopupList'),
+    ('pages/index-home/index', 'POST', '/api/health/challenge/list', True, False, 'getChallengeList'),
+    ('pages/index-home/index', 'POST', '/api/health/challenge/progress', True, False, 'updateChallengeProgress'),
+    ('pages/index-home/index', 'POST', '/api/health/challenge/respond', True, False, 'respondChallenge'),
+    ('pages/index-home/index', 'POST', '/api/home/app-library', True, False, 'getAppLibrary'),
+    ('pages/index-home/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/index-home/index', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/index-home/index', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/index-home/index', 'POST', '/api/notification/list', True, False, 'getNotificationList'),
+    ('pages/index-home/index', 'POST', '/api/notification/read', True, False, 'readNotification'),
+    ('pages/index-home/index', 'POST', '/api/points/logs', True, False, 'getPointsLogs'),
+    ('pages/index-home/index', 'POST', '/api/survey/status', True, False, 'getSurveyStatus'),
+    ('pages/index-home/index', 'POST', '/api/tasks/history', True, False, 'getTaskHistory'),
+    ('pages/index-home/index', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/invite/join', 'POST', '/api/family/invite/check-family', False, False, 'checkUserFamily'),
+    ('pages/invite/join', 'POST', '/api/family/invite/validate', False, False, 'validateInvitation'),
+    ('pages/invite/join', 'POST', '/api/family/invite/validate-family-code', False, False, 'validateFamilyCode'),
+    ('pages/invite/join', 'POST', '/api/invite/bind', True, False, 'bindReferral'),
+    ('pages/invite/join-form', 'POST', '/api/family/invite/request-join-by-code', False, False, 'requestJoinByCode'),
+    ('pages/invite/join-form', 'POST', '/api/user/update', True, False, 'updateUserInfo'),
+    ('pages/login/scan-login', 'POST', '/api/auth/wechat-web/scan', False, False, 'wechatWebScan'),
+    ('pages/match/street-match', 'POST', '/api/admin/families/count', True, False, 'countFamiliesByStreetIds'),
+    ('pages/match/street-match', 'POST', '/api/admin/teachers/count', True, False, 'countTeachersByStreetIds'),
+    ('pages/meal/log', 'POST', '/api/meal/log', True, False, 'logMeal'),
+    ('pages/meal/log', 'POST', '/api/meal/logs', True, False, 'getMealLogs'),
+    ('pages/meal/log', 'POST', '/api/meal/nutrition-summary', True, False, 'getNutritionSummary'),
+    ('pages/meal/preference', 'POST', '/api/nutrition/profile/get', True, False, 'getNutritionProfile'),
+    ('pages/meal/preference', 'POST', '/api/nutrition/profile/save', True, False, 'saveNutritionProfile'),
+    ('pages/meal/recommend', 'POST', '/api/meal/recommend', True, False, 'getMealRecommend'),
+    ('pages/meal/recommend', 'POST', '/api/meal/replace', True, False, 'replaceFood'),
+    ('pages/member-detail/components/member-detail-sections/action-section', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/member-detail/components/member-detail-sections/action-section', 'POST', '/api/tasks/today', True, False, 'getTodayTasksByCategory'),
+    ('pages/member-detail/components/member-detail-sections/action-section', 'POST', '/api/wealth/checkin/stats', True, False, 'getCheckinStats'),
+    ('pages/member-detail/components/member-detail-sections/body-section', 'POST', '/api/dimension/overview', True, False, 'getDimensionOverview'),
+    ('pages/member-detail/components/member-detail-sections/body-section', 'POST', '/api/health/analysis', True, False, 'getHealthAnalysis'),
+    ('pages/member-detail/components/member-detail-sections/body-section', 'POST', '/api/wealth/checkin/list', True, False, 'getCheckinList'),
+    ('pages/member-detail/components/member-detail-sections/mind-section', 'POST', '/api/contact/list', True, False, 'getContactList'),
+    ('pages/member-detail/components/member-detail-sections/mind-section', 'POST', '/api/family/relationship/health-alerts', True, False, 'getHealthAlerts'),
+    ('pages/member-detail/components/member-detail-sections/mind-section', 'POST', '/api/family/relationship/milestones', True, False, 'getMilestones'),
+    ('pages/member-detail/components/member-detail-sections/mind-section', 'POST', '/api/family/relationship/scores', True, False, 'getRelationshipScores'),
+    ('pages/member-detail/components/member-detail-sections/wisdom-section', 'POST', '/api/assessment/history', True, False, 'getAssessmentHistory'),
+    ('pages/member-detail/components/member-detail-sections/wisdom-section', 'POST', '/api/assessment/latest-result', True, False, 'getAssessmentLatestResult'),
+    ('pages/member-detail/member-detail', 'POST', '/api/activity/list', False, False, 'getActivityList'),
+    ('pages/member-detail/member-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/member-detail/report-detail', 'POST', '/api/health/report/detail', True, False, 'getReportDetail'),
+    ('pages/membership/benefits', 'POST', '/api/membership/benefits', True, False, 'getMembershipBenefits'),
+    ('pages/membership/benefits', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/membership/index', 'POST', '/api/butler/my-butler', False, False, 'getMyButler'),
+    ('pages/membership/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/membership/index', 'POST', '/api/membership/benefits', True, False, 'getMembershipBenefits'),
+    ('pages/membership/index', 'POST', '/api/membership/compare', True, False, 'getMembershipCompare'),
+    ('pages/membership/index', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/membership/pay', 'POST', '/api/coupon/list', True, False, 'getCouponList'),
+    ('pages/membership/pay', 'POST', '/api/membership/orders', True, False, 'createOrder'),
+    ('pages/membership/pay', 'POST', '/api/membership/orders/continue', True, False, 'nextOrder'),
+    ('pages/membership/pay', 'POST', '/api/membership/plans', True, False, 'getMembershipPlans'),
+    ('pages/membership/result', 'POST', '/api/coupon/join-rules', True, False, 'getJoinCouponRules'),
+    ('pages/membership/result', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/membership/result', 'POST', '/api/membership/orders/continue', True, False, 'nextOrder'),
+    ('pages/membership/upgrade', 'POST', '/api/coupon/join-rules', True, False, 'getJoinCouponRules'),
+    ('pages/membership/upgrade', 'POST', '/api/membership/compare', True, False, 'getMembershipCompare'),
+    ('pages/membership/upgrade', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/membership/upgrade', 'POST', '/api/membership/plans', True, False, 'getMembershipPlans'),
+    ('pages/membership/upgrade', 'POST', '/api/membership/upgrade-records', True, False, 'getUpgradeRecords'),
+    ('pages/mind-detail/articles', 'POST', '/api/articles/categories', False, False, 'getArticleCategories'),
+    ('pages/mind-detail/articles', 'POST', '/api/articles/list', False, False, 'getArticleList'),
+    ('pages/mind-detail/components/PsychCrisisBanner', 'POST', '/api/health/alert/dismiss', True, False, 'dismissAlert'),
+    ('pages/mind-detail/emotion-report', 'POST', '/api/emireport/latest', True, False, 'getEmiReport'),
+    ('pages/mind-detail/family-dashboard', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/mind-detail/family-dashboard', 'POST', '/api/mind/fortune', True, False, 'getFamilyFortune'),
+    ('pages/mind-detail/family-dashboard', 'POST', '/api/mind/fortune/month', True, False, 'getMonthFortune'),
+    ('pages/mind-detail/family-dashboard', 'POST', '/api/mind/fortune/reports', True, False, 'getFortuneReports'),
+    ('pages/mind-detail/family-dashboard', 'POST', '/api/mind/fortune/week', True, False, 'getWeekFortune'),
+    ('pages/mind-detail/index', 'POST', '/api/contact/list', True, False, 'getContactList'),
+    ('pages/mind-detail/index', 'POST', '/api/content-sections/visible', True, False, 'getVisibleSections'),
+    ('pages/mind-detail/index', 'POST', '/api/dan-assessment/report/child', True, False, 'getDanReportByChild'),
+    ('pages/mind-detail/index', 'POST', '/api/dimension/radar-data', True, False, 'getRadarData'),
+    ('pages/mind-detail/index', 'POST', '/api/emireport/latest', True, False, 'getEmiReport'),
+    ('pages/mind-detail/index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/mind-detail/index', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/mind-detail/index', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/mind-detail/index', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('pages/mind-detail/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/mind-detail/index', 'POST', '/api/family/relationship/health-alerts', True, False, 'getHealthAlerts'),
+    ('pages/mind-detail/index', 'POST', '/api/family/relationship/milestones', True, False, 'getMilestones'),
+    ('pages/mind-detail/index', 'POST', '/api/health/indicators', True, False, 'getLatestIndicators'),
+    ('pages/mind-detail/index', 'POST', '/api/mind/fortune', True, False, 'getFamilyFortune'),
+    ('pages/mind-detail/innate-portrait', 'POST', '/api/mind/innate/reading', True, False, 'getInnateReading'),
+    ('pages/mind-detail/innate-trajectory', 'POST', '/api/mind/innate/trajectory', True, False, 'getInnateTrajectory'),
+    ('pages/mind-detail/member-mind-detail', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/mind-detail/member-mind-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/mind-detail/training', 'POST', '/api/game/stats', True, False, 'getGameStats'),
+    ('pages/notification/index', 'POST', '/api/notification/list', True, False, 'getNotificationList'),
+    ('pages/notification/index', 'POST', '/api/notification/read', True, False, 'readNotification'),
+    ('pages/nutritionist/apply', 'POST', '/api/nutritionist/apply', False, False, 'nutritionistApply'),
+    ('pages/orchestration/editor', 'POST', '/api/admin/task-templates', True, False, 'getNodeTemplateList'),
+    ('pages/orchestration/editor', 'POST', '/api/orchestration/flow/detail', True, False, 'getOrchestrationFlowDetail'),
+    ('pages/orchestration/editor', 'POST', '/api/orchestration/flow/publish', True, False, 'publishOrchestrationFlow'),
+    ('pages/orchestration/editor', 'POST', '/api/orchestration/flow/save', True, False, 'saveOrchestrationFlow'),
+    ('pages/orchestration/index', 'POST', '/api/orchestration/flow/archive', True, False, 'archiveOrchestrationFlow'),
+    ('pages/orchestration/index', 'POST', '/api/orchestration/flow/delete', True, False, 'deleteOrchestrationFlow'),
+    ('pages/orchestration/index', 'POST', '/api/orchestration/flow/list', True, False, 'getOrchestrationFlowList'),
+    ('pages/orchestration/index', 'POST', '/api/orchestration/flow/publish', True, False, 'publishOrchestrationFlow'),
+    ('pages/orchestration/node-edit', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/parent/appointments', 'POST', '/api/dan-assessment/appointment/cancel', True, False, 'cancelAppointment'),
+    ('pages/parent/appointments', 'POST', '/api/dan-assessment/appointment/user', True, False, 'getMyAppointments'),
+    ('pages/parent/child-detail', 'POST', '/api/tasks/pending-review', True, False, 'getPendingReviewTasks'),
+    ('pages/parent/child-detail', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/parent/child-detail', 'POST', '/api/wishes/pending', True, False, 'getPendingWishes'),
+    ('pages/parent/plans/detail', 'POST', '/api/guide/plans/detail', True, False, 'getGuidePlanDetail'),
+    ('pages/parent/plans/index', 'POST', '/api/guide/plans/family-list', True, False, 'listFamilyPlans'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes//:var/approve-exchange', True, True, 'approveWishExchange'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes//:var/fulfill', True, True, 'markWishFulfilled'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes//:var/price', True, True, 'setWishPrice'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes//:var/reject', True, True, 'rejectWish'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes/list', True, False, 'getWishes'),
+    ('pages/parent/wishes/index', 'POST', '/api/wishes/pending', True, False, 'getPendingWishes'),
+    ('pages/pearl-reminders/index', 'POST', '/api/pearl/interaction/add', True, False, 'addPearlInteraction'),
+    ('pages/pearl-reminders/index', 'POST', '/api/pearl/reminder/list', True, False, 'getPearlReminders'),
+    ('pages/profile-extra/coupons', 'POST', '/api/coupon/claim', True, False, 'claimCoupon'),
+    ('pages/profile-extra/coupons', 'POST', '/api/coupon/exchangeable', True, False, 'getExchangeableCoupons'),
+    ('pages/profile-extra/coupons', 'POST', '/api/coupon/my', True, False, 'getMyCoupons'),
+    ('pages/profile-extra/coupons', 'POST', '/api/family-platform/exchange-coupon', True, False, 'exchangeCouponByCf'),
+    ('pages/profile-extra/family-members', 'POST', '/api/family/invite/generate', False, False, 'generateFamilyInvite'),
+    ('pages/profile-extra/family-members', 'POST', '/api/family/invite/pending-requests', False, False, 'getPendingJoinRequests'),
+    ('pages/profile-extra/family-members', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('pages/profile-extra/family-members', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/profile-extra/family-members', 'POST', '/api/family/member/switch', True, False, 'switchToFamilyMember'),
+    ('pages/profile-extra/family-members', 'POST', '/api/health/report/member-permission/revoke', True, False, 'revokeReportMemberPermission'),
+    ('pages/profile-extra/family-members', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/profile-extra/gates', 'POST', '/api/unlock/status', True, False, 'getUnlockStatus'),
+    ('pages/profile-extra/onboarding', 'POST', '/api/onboarding/claim', True, False, 'claimOnboardingReward'),
+    ('pages/profile-extra/onboarding', 'POST', '/api/onboarding/progress', True, False, 'getOnboardingProgress'),
+    ('pages/profile-main/profile', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('pages/profile-main/profile', 'POST', '/api/cart/count', True, False, 'cartCount'),
+    ('pages/profile-main/profile', 'POST', '/api/commission/my-referrer', True, False, 'getMyReferrer'),
+    ('pages/profile-main/profile', 'POST', '/api/commission/team/consumption', True, False, 'getTeamConsumption'),
+    ('pages/profile-main/profile', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/profile-main/profile', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/profile-main/profile', 'POST', '/api/health/challenge/list', True, False, 'getChallengeList'),
+    ('pages/profile-main/profile', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/profile-main/profile', 'POST', '/api/invite/summary', True, False, 'getReferralSummary'),
+    ('pages/profile-main/profile', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/profile-main/profile', 'POST', '/api/product/order/my/counts', False, False, 'getOrderCounts'),
+    ('pages/profile-main/profile', 'POST', '/api/share/qrcode', True, False, 'getShareQrCode'),
+    ('pages/profile-main/profile', 'POST', '/api/tasks/today', True, False, 'getTodayTasksByCategory'),
+    ('pages/profile-main/profile', 'POST', '/api/user/info', True, False, 'getUserInfo'),
+    ('pages/profile-main/profile', 'POST', '/api/user/profile-stats', True, False, 'getProfileStats'),
+    ('pages/profile-main/profile', 'POST', '/api/vendor/status', False, False, 'vendorStatus'),
+    ('pages/profile/components/ProfileHeader', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('pages/profile/components/ProfileHeader', 'POST', '/api/family/member/switch', True, False, 'switchToFamilyMember'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/auth/set-password', False, False, 'setPassword'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/auth/verify-password', False, False, 'verifyPassword'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/family/user/members/update-visibility', True, False, 'updateMemberVisibility'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/profile/components/ProfileMenu', 'POST', '/api/vendor/status', False, False, 'vendorStatus'),
+    ('pages/profile/components/ProfileStats', 'POST', '/api/user/action-stats', True, False, 'getUserActionStats'),
+    ('pages/profile/index', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/profile/message-history', 'POST', '/api/commission/cf/list', True, False, 'getCfList'),
+    ('pages/profile/message-history', 'POST', '/api/energy/logs', True, False, 'getEnergyLogs'),
+    ('pages/profile/message-history', 'POST', '/api/notification/list', True, False, 'getNotificationList'),
+    ('pages/profile/message-history', 'POST', '/api/notification/read', True, False, 'readNotification'),
+    ('pages/profile/message-history', 'POST', '/api/points/logs', True, False, 'getPointsLogs'),
+    ('pages/profile/portrait-edit', 'POST', '/api/energy/sandbox', True, False, 'getEnergySandbox'),
+    ('pages/profile/portrait-edit', 'POST', '/api/user/portrait/edit', True, False, 'editPortrait'),
+    ('pages/profile/portrait-edit', 'POST', '/api/user/portrait/get', True, False, 'getPortrait'),
+    ('pages/profile/report-detail', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/profile/report-management', 'POST', '/api/report-summary/list', True, False, 'getReportSummaryList'),
+    ('pages/profile/service-role-apply', 'POST', '/api/service-role/my-apply', True, False, 'getMyServiceRoleApply'),
+    ('pages/profile/service-role-apply', 'POST', '/api/service-role/upload-image', True, False, 'uploadServiceRoleImage'),
+    ('pages/promotion/commission', 'POST', '/api/commission/cf/list', True, False, 'getCfList'),
+    ('pages/promotion/commission', 'POST', '/api/commission/cf/summary', True, False, 'getCfSummary'),
+    ('pages/promotion/index', 'POST', '/api/commission/cf/summary', True, False, 'getCfSummary'),
+    ('pages/promotion/index', 'POST', '/api/earnings/admin/distribute', True, False, 'distributeToMember'),
+    ('pages/promotion/index', 'POST', '/api/earnings/admin/toggle-member', True, False, 'toggleMemberBalance'),
+    ('pages/promotion/index', 'POST', '/api/earnings/admin/withdraw', True, False, 'withdrawFamilyEarnings'),
+    ('pages/promotion/index', 'POST', '/api/earnings/family/summary', True, False, 'getFamilyEarningsSummary'),
+    ('pages/promotion/index', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/promotion/index', 'POST', '/api/invite/summary', True, False, 'getReferralSummary'),
+    ('pages/promotion/invite', 'POST', '/api/invite/bind', True, False, 'bindReferral'),
+    ('pages/promotion/invite', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('pages/promotion/invite', 'POST', '/api/invite/list', True, False, 'getReferralList'),
+    ('pages/promotion/invite', 'POST', '/api/invite/milestone/claim', True, False, 'claimInviteMilestone'),
+    ('pages/promotion/invite', 'POST', '/api/invite/milestone/list', True, False, 'getInviteMilestones'),
+    ('pages/promotion/invite', 'POST', '/api/invite/qrcode', True, False, 'getInviteQrCode'),
+    ('pages/promotion/invite', 'POST', '/api/invite/summary', True, False, 'getReferralSummary'),
+    ('pages/promotion/leaderboard', 'POST', '/api/leaderboard/my-rank', True, False, 'getLeaderboardMyRank'),
+    ('pages/promotion/leaderboard', 'POST', '/api/leaderboard/top', True, False, 'getLeaderboardTop'),
+    ('pages/promotion/team', 'POST', '/api/commission/cf/rate', True, False, 'getCfRate'),
+    ('pages/promotion/team', 'POST', '/api/commission/my-referrer', True, False, 'getMyReferrer'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/consumption', True, False, 'getTeamConsumption'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/consumption-curve', True, False, 'getTeamAllMembersConsumptionCurve'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/growth-curve', True, False, 'getTeamGrowthCurve'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/l1-consumption-curve', True, False, 'getTeamL1ConsumptionCurve'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/list', True, False, 'getTeamList'),
+    ('pages/promotion/team', 'POST', '/api/commission/team/tree', True, False, 'getTeamTree'),
+    ('pages/promotion/withdraw', 'POST', '/api/commission/summary', True, False, 'getCommissionSummary'),
+    ('pages/promotion/withdraw', 'POST', '/api/withdrawal/apply', True, False, 'applyWithdrawal'),
+    ('pages/promotion/withdraw', 'POST', '/api/withdrawal/history', True, False, 'getWithdrawalHistory'),
+    ('pages/psych-assessment/index', 'POST', '/api/cognitive/child', True, False, 'getCognitiveChildScores'),
+    ('pages/psych-assessment/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/psych-assessment/quiz', 'POST', '/api/cognitive/self-test', True, False, 'submitCognitiveSelfTest'),
+    ('pages/reminder-config/index', 'POST', '/api/task/reminder-config/get', True, False, 'getReminderConfig'),
+    ('pages/reminder-config/index', 'POST', '/api/task/reminder-config/save', True, False, 'saveReminderConfig'),
+    ('pages/rewards/badge', 'POST', '/api/badges/child/list', True, False, 'getChildBadges'),
+    ('pages/rewards/badge', 'POST', '/api/badges/favorite', True, False, 'toggleBadgeFavorite'),
+    ('pages/rewards/badge', 'POST', '/api/badges/list', True, False, 'getActiveBadges'),
+    ('pages/rewards/badge', 'POST', '/api/badges/ranking/family', True, False, 'getFamilyBadgeRanking'),
+    ('pages/rewards/badge', 'POST', '/api/badges/statistics/child', True, False, 'getChildBadgeStats'),
+    ('pages/rewards/rewards', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/rewards/rewards', 'POST', '/api/parent/wishlist', True, False, 'createParentWishlist'),
+    ('pages/rewards/rewards', 'POST', '/api/parent/wishlist//:var/exchange', True, True, 'exchangeParentWishlist'),
+    ('pages/rewards/rewards', 'POST', '/api/parent/wishlist/list', True, False, 'getParentWishlist'),
+    ('pages/rewards/rewards', 'POST', '/api/points/balance', True, False, 'getPointsBalance'),
+    ('pages/rewards/rewards', 'POST', '/api/rewards', True, False, 'createReward'),
+    ('pages/rewards/rewards', 'POST', '/api/rewards//:var/exchange', True, True, 'exchangeReward'),
+    ('pages/rewards/rewards', 'POST', '/api/rewards/wishlist', True, False, 'getWishlist'),
+    ('pages/rewards/rewards', 'POST', '/api/user/info', True, False, 'getUserInfo'),
+    ('pages/share/index', 'POST', '/api/share/family-footprint', True, False, 'getFamilyFootprint'),
+    ('pages/shop/cart/cart', 'POST', '/api/membership/gift-membership-progress', True, False, 'getGiftMembershipProgress'),
+    ('pages/shop/cart/cart', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/coupon/apply', True, False, 'applyCoupon'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/coupon/checkout-list', True, False, 'getCouponCheckoutList'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/coupon/list', True, False, 'getCouponList'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/family-platform/balance', True, False, 'getFamilyPlatformBalance'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/family-platform/exchange-coupon', True, False, 'exchangeCouponByCf'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/membership/gift-membership-progress', True, False, 'getGiftMembershipProgress'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/product/detail', False, False, 'productDetail'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/product/purchase_fields/required', False, False, 'getProductRequiredFields'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/shop/discount/calculate', False, False, 'shopDiscountCalculate'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/special-price/info', True, False, 'getSpecialPriceInfo'),
+    ('pages/shop/checkout/checkout', 'POST', '/api/user/address/list', True, False, 'addressList'),
+    ('pages/shop/consignee-edit/consignee-edit', 'POST', '/api/consignee/detail', True, False, 'consigneeDetail'),
+    ('pages/shop/consignee-edit/consignee-edit', 'POST', '/api/consignee/save', True, False, 'consigneeSave'),
+    ('pages/shop/consignee-list/consignee-list', 'POST', '/api/consignee/delete', True, False, 'consigneeDelete'),
+    ('pages/shop/consignee-list/consignee-list', 'POST', '/api/consignee/list', True, False, 'consigneeList'),
+    ('pages/shop/index/index', 'POST', '/api/cart/count', True, False, 'cartCount'),
+    ('pages/shop/index/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/shop/index/index', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/shop/index/index', 'POST', '/api/product/list', False, False, 'productList'),
+    ('pages/shop/index/index', 'POST', '/api/shop/category/tree', False, False, 'goodsCategory'),
+    ('pages/shop/order-detail/order-detail', 'POST', '/api/product/order/cancel', False, False, 'productOrderCancel'),
+    ('pages/shop/order-detail/order-detail', 'POST', '/api/product/order/confirm', False, False, 'productOrderConfirm'),
+    ('pages/shop/order-detail/order-detail', 'POST', '/api/product/order/detail', False, False, 'productOrderDetail'),
+    ('pages/shop/order-list/order-list', 'POST', '/api/product/order/cancel', False, False, 'productOrderCancel'),
+    ('pages/shop/order-list/order-list', 'POST', '/api/product/order/confirm', False, False, 'productOrderConfirm'),
+    ('pages/shop/order-list/order-list', 'POST', '/api/product/order/my', False, False, 'productOrderMy'),
+    ('pages/shop/order-list/order-list', 'POST', '/api/product/order/my/counts', False, False, 'productOrderCounts'),
+    ('pages/shop/payment/payment', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/shop/search/search', 'POST', '/api/product/list', False, False, 'productList'),
+    ('pages/stats/completion-rate', 'POST', '/api/stats/child-completion', True, False, 'getChildCompletionStats'),
+    ('pages/stats/completion-rate', 'POST', '/api/stats/family-completion', True, False, 'getFamilyCompletionStats'),
+    ('pages/stats/index', 'POST', '/api/stats/child/overview', True, False, 'getChildOverview'),
+    ('pages/tasks/create-task', 'POST', '/api/tasks/create', True, False, 'createTask'),
+    ('pages/tasks/create-task', 'POST', '/api/tasks/list', True, False, 'getTaskListForPicker'),
+    ('pages/tasks/daily-tasks', 'POST', '/api/growth-task/claim', True, False, 'claimGrowthTaskReward'),
+    ('pages/tasks/daily-tasks', 'POST', '/api/growth-task/list', True, False, 'getGrowthTaskList'),
+    ('pages/tasks/review', 'POST', '/api/tasks//:var/review', True, True, 'approveTask'),
+    ('pages/tasks/review', 'POST', '/api/tasks//:var/review', True, True, 'rejectTask'),
+    ('pages/tasks/review', 'POST', '/api/tasks/history', True, False, 'getTaskHistory'),
+    ('pages/tasks/review', 'POST', '/api/tasks/pending-review', True, False, 'getPendingReviewTasks'),
+    ('pages/tasks/tasks', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/tasks/tasks', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/tasks/tasks', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/tasks/tasks', 'POST', '/api/tasks//:var/complete', True, True, 'completeTask'),
+    ('pages/tasks/tasks', 'POST', '/api/tasks/accept', True, False, 'acceptTask'),
+    ('pages/tasks/tasks', 'POST', '/api/tasks/create', True, False, 'createTask'),
+    ('pages/tasks/tasks', 'POST', '/api/tasks/my-pending', True, False, 'getMyPendingTasks'),
+    ('pages/tasks/tasks', 'POST', '/api/tasks/today', True, False, 'getTodayTasks'),
+    ('pages/teacher/chat', 'POST', '/api/guide/messages/list', True, False, 'getGuideMessages'),
+    ('pages/teacher/families', 'POST', '/api/guide/families', True, False, 'getBoundFamilies'),
+    ('pages/teacher/messages', 'POST', '/api/guide/messages/list', True, False, 'getGuideMessages'),
+    ('pages/teacher/orders', 'POST', '/api/guide/orders/list', True, False, 'getGuideOrders'),
+    ('pages/teacher/orders', 'POST', '/api/guide/orders/stats', True, False, 'getOrderStats'),
+    ('pages/teacher/plan-create', 'POST', '/api/guide/training-plans/create', True, False, 'createTrainingPlan'),
+    ('pages/teacher/plan-detail', 'POST', '/api/guide/families//:var/plans//:var/update', True, True, 'updateGuidePlanContent'),
+    ('pages/teacher/plan-detail', 'POST', '/api/guide/families//:var/plans/pending', True, True, 'getGuidePendingPlans'),
+    ('pages/teacher/plan-list', 'POST', '/api/guide/training-plans/list', True, False, 'getTrainingPlanList'),
+    ('pages/teacher/review-family', 'POST', '/api/guide/families//:var/children//:var/pending-review', True, True, 'getGuideChildPendingTasks'),
+    ('pages/teacher/review-family', 'POST', '/api/guide/families//:var/members', True, True, 'getGuideFamilyMembers'),
+    ('pages/teacher/review-family', 'POST', '/api/guide/families//:var/plans/pending', True, True, 'getGuidePendingPlans'),
+    ('pages/teacher/review-family', 'POST', '/api/guide/families//:var/tasks//:var/review', True, True, 'reviewGuideTask'),
+    ('pages/teacher/review-family', 'POST', '/api/tasks//:var/review', True, True, 'reviewTask'),
+    ('pages/teacher/review-workbench', 'POST', '/api/guide/families/my-families', True, False, 'getGuideMyFamilies'),
+    ('pages/teacher/service-tasks', 'POST', '/api/tasks//:var/complete', True, True, 'completeTask'),
+    ('pages/teacher/teacher-profile', 'POST', '/api/guide/parent-invite/generate', True, False, 'generateParentInvite'),
+    ('pages/teacher/teacher-profile', 'POST', '/api/auth/switch-role', True, False, 'switchRole'),
+    ('pages/teacher/team', 'POST', '/api/guide/invite-code/generate', False, False, 'generateInviteCode'),
+    ('pages/teacher/team', 'POST', '/api/guide/team/invite-code/generate', True, False, 'generateTeamInviteCode'),
+    ('pages/teacher/team', 'POST', '/api/guide/team/members', True, False, 'getTeamMembers'),
+    ('pages/teacher/team', 'POST', '/api/guide/team/stats', True, False, 'getTeamStats'),
+    ('pages/user-edit/user-edit', 'POST', '/api/auth/direct-register', False, False, 'directRegister'),
+    ('pages/user-edit/user-edit', 'POST', '/api/family/invite/request-join-by-code', False, False, 'requestJoinByCode'),
+    ('pages/user-edit/user-edit', 'POST', '/api/family/user/create-family', True, False, 'createFamily'),
+    ('pages/user-edit/user-edit', 'POST', '/api/membership/my', True, False, 'getMyMembership'),
+    ('pages/user-edit/user-edit', 'POST', '/api/user/info', True, False, 'getUserInfo'),
+    ('pages/user-edit/user-edit', 'POST', '/api/user/update', True, False, 'updateUserInfo'),
+    ('pages/vendor/apply', 'POST', '/api/vendor/apply', True, False, 'vendorApply'),
+    ('pages/vendor/center', 'POST', '/api/vendor/info', False, False, 'vendorInfo'),
+    ('pages/vendor/center', 'POST', '/api/vendor/status', False, False, 'vendorStatus'),
+    ('pages/vendor/order-review/order-review', 'POST', '/api/product/order/detail', False, False, 'productOrderDetail'),
+    ('pages/vendor/order-review/order-review', 'POST', '/api/product/order/review/update', False, False, 'productOrderReviewUpdate'),
+    ('pages/vendor/orders/orders', 'POST', '/api/product/order/confirm', False, False, 'productOrderConfirm'),
+    ('pages/vendor/orders/orders', 'POST', '/api/product/order/vendor', False, False, 'productOrderVendor'),
+    ('pages/vendor/product-edit/product-edit', 'POST', '/api/product/create', False, False, 'productCreate'),
+    ('pages/vendor/product-edit/product-edit', 'POST', '/api/product/detail', False, False, 'productDetail'),
+    ('pages/vendor/product-edit/product-edit', 'POST', '/api/product/update', False, False, 'productUpdate'),
+    ('pages/vendor/products/products', 'POST', '/api/product/my', False, False, 'productMy'),
+    ('pages/vendor/products/products', 'POST', '/api/product/shelve', False, False, 'productShelve'),
+    ('pages/vendor/team-customers/team-customers', 'POST', '/api/admin/supply-team/customers', True, False, 'getTeamCustomers'),
+    ('pages/vendor/team-system/team-system', 'POST', '/api/admin/supply-hierarchy/my', True, False, 'getVendorHierarchyInfo'),
+    ('pages/vendor/team-system/team-system', 'POST', '/api/admin/supply-system/my-system', True, False, 'getVendorSystemInfo'),
+    ('pages/vendor/team-system/team-system', 'POST', '/api/admin/supply-team/customers', True, False, 'getVendorTeamCustomers'),
+    ('pages/vendor/team-system/team-system', 'POST', '/api/admin/supply-team/members', True, False, 'getVendorTeamMembers'),
+    ('pages/wealth-cf/index', 'GET', '/api/cf/balance', True, False, 'getCfBalance'),
+    ('pages/wealth-cf/index', 'GET', '/api/cf/family-coupons', True, False, 'getFamilyCoupons'),
+    ('pages/wealth-cf/index', 'GET', '/api/cf/logs', True, False, 'getCfLogs'),
+    ('pages/wealth-cf/index', 'POST', '/api/coupon/exchangeable', True, False, 'getExchangeableCoupons'),
+    ('pages/wealth-cf/index', 'POST', '/api/family-platform/exchange-coupon', True, False, 'exchangeCouponByCf'),
+    ('pages/wealth-detail/member-wealth-detail', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/wealth-detail/member-wealth-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/wealth-sub/checkin', 'POST', '/api/wealth/checkin/create', True, False, 'createCheckin'),
+    ('pages/wealth-sub/checkin', 'POST', '/api/wealth/checkin/delete', True, False, 'deleteCheckin'),
+    ('pages/wealth-sub/checkin', 'POST', '/api/wealth/checkin/list', True, False, 'getCheckinList'),
+    ('pages/wealth-sub/checkin', 'POST', '/api/wealth/checkin/stats', True, False, 'getCheckinStats'),
+    ('pages/wealth-sub/insurance-add', 'POST', '/api/wealth/insurance/create', False, False, 'createInsurance'),
+    ('pages/wealth-sub/insurance-add', 'POST', '/api/wealth/insurance/detail', False, False, 'getInsuranceDetail'),
+    ('pages/wealth-sub/insurance-add', 'POST', '/api/wealth/insurance/update', False, False, 'updateInsurance'),
+    ('pages/wealth-sub/insurance-add', 'POST', '/api/wealth/insurance/upload', False, False, 'uploadPolicy'),
+    ('pages/wealth-sub/insurance-list', 'POST', '/api/wealth/insurance/delete', False, False, 'deleteInsurance'),
+    ('pages/wealth-sub/insurance-list', 'POST', '/api/wealth/insurance/list', False, False, 'getInsuranceList'),
+    ('pages/wealth-sub/insurance-planning', 'POST', '/api/insurance/planning', True, False, 'getInsurancePlanning'),
+    ('pages/wealth/index', 'POST', '/api/badges/statistics/child', True, False, 'getChildBadgeStats'),
+    ('pages/wealth/index', 'POST', '/api/commission/summary', True, False, 'getCommissionSummary'),
+    ('pages/wealth/index', 'POST', '/api/daily-task/overview', True, False, 'getDailyTaskOverview'),
+    ('pages/wealth/index', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/wealth/index', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/wealth/index', 'POST', '/api/energy/wealth-detail', True, False, 'getWealthDetail'),
+    ('pages/wealth/index', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('pages/wealth/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/wealth/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/wealth/index', 'POST', '/api/invite/summary', True, False, 'getReferralSummary'),
+    ('pages/wealth/index', 'POST', '/api/product/list', False, False, 'productList'),
+    ('pages/wealth/index', 'POST', '/api/wealth/insurance/list', False, False, 'getInsuranceList'),
+    ('pages/wisdom-detail/cognitive-report', 'POST', '/api/assessment/latest-result', True, False, 'getAssessmentLatestResult'),
+    ('pages/wisdom-detail/cognitive-report', 'POST', '/api/cognitive/norms', True, False, 'getCognitiveNorms'),
+    ('pages/wisdom-detail/cognitive-report', 'POST', '/api/cognitive/recommendations', True, False, 'getCognitiveRecommendations'),
+    ('pages/wisdom-detail/cognitive-report', 'POST', '/api/cognitive/recommendations/create-task', True, False, 'createTaskFromRecommendation'),
+    ('pages/wisdom-detail/cognitive-report', 'POST', '/api/cognitive/trend', True, False, 'getCognitiveTrend'),
+    ('pages/wisdom-detail/index', 'POST', '/api/assessment/latest-result', True, False, 'getAssessmentLatestResult'),
+    ('pages/wisdom-detail/index', 'POST', '/api/content-sections/visible', True, False, 'getVisibleSections'),
+    ('pages/wisdom-detail/index', 'POST', '/api/dan-assessment/report/child', True, False, 'getDanReportByChild'),
+    ('pages/wisdom-detail/index', 'POST', '/api/dimension/radar-data', True, False, 'getRadarData'),
+    ('pages/wisdom-detail/index', 'POST', '/api/family/member/kick', True, False, 'kickFamilyMemberById'),
+    ('pages/wisdom-detail/index', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('pages/wisdom-detail/index', 'POST', '/api/health/indicators', True, False, 'getLatestIndicators'),
+    ('pages/wisdom-detail/index', 'POST', '/api/wisdom/gut-cognition', True, False, 'getGutCognitionIndicators'),
+    ('pages/wisdom-detail/member-wisdom-detail', 'POST', '/api/energy/overview', True, False, 'getEnergyOverview'),
+    ('pages/wisdom-detail/member-wisdom-detail', 'POST', '/api/energy/sandbox', True, False, 'getFamilyEnergySandbox'),
+    ('pages/wishes/create', 'POST', '/api/wishes/create', True, False, 'createWish'),
+    ('pages/wishes/detail', 'POST', '/api/points/balance', True, False, 'getPointsBalance'),
+    ('pages/wishes/detail', 'POST', '/api/wishes//:var', True, True, 'cancelWish'),
+    ('pages/wishes/detail', 'POST', '/api/wishes//:var', True, True, 'getWishById'),
+    ('pages/wishes/detail', 'POST', '/api/wishes//:var/confirm', True, True, 'confirmWishReceived'),
+    ('pages/wishes/detail', 'POST', '/api/wishes//:var/exchange', True, True, 'requestWishExchange'),
+    ('pages/wishes/index', 'POST', '/api/home/app/enter', True, False, 'reportAppEnter'),
+    ('pages/wishes/index', 'POST', '/api/points/balance', True, False, 'getPointsBalance'),
+    ('pages/wishes/index', 'POST', '/api/wishes//:var', True, True, 'cancelWish'),
+    ('pages/wishes/index', 'POST', '/api/wishes//:var/confirm', True, True, 'confirmWishReceived'),
+    ('pages/wishes/index', 'POST', '/api/wishes//:var/exchange', True, True, 'requestWishExchange'),
+    ('pages/wishes/index', 'POST', '/api/wishes/create', True, False, 'createWish'),
+    ('pages/wishes/index', 'POST', '/api/wishes/list', True, False, 'getWishes'),
+    ('store/health-alert', 'POST', '/api/health/alert/dismiss', True, False, 'dismissAlert'),
+    ('store/health-alert', 'POST', '/api/health/alert/list', True, False, 'getActiveAlerts'),
+    ('store/health-score', 'POST', '/api/health/score/info', True, False, 'getHealthScoreInfo'),
+    ('store/health-score', 'POST', '/api/health/timeline/list', True, False, 'getHealthTimeline'),
+    ('store/index', 'POST', '/api/family/user/switch-back-verify', True, False, 'switchBackVerify'),
+    ('store/index', 'POST', '/api/family/user/switch-back-to-parent', True, False, 'switchBackToParent'),
+    ('store/index', 'POST', '/api/auth/switch-role', True, False, 'switchRole'),
+    ('store/index', 'POST', '/api/family/user/switch-to-child', True, False, 'switchToChild'),
+    ('store/modules/tianpan', 'POST', '/api/tianpan/annual-energy', False, False, 'tianpanAnnualEnergy'),
+    ('store/modules/tianpan', 'POST', '/api/tianpan/daily-fortune', False, False, 'tianpanDailyFortune'),
+    ('store/modules/tianpan', 'POST', '/api/tianpan/dashboard', False, False, 'tianpanDashboard'),
+    ('store/modules/tianpan', 'POST', '/api/tianpan/related-items', False, False, 'tianpanRelatedItems'),
+    ('utils/api', 'POST', '/api/admin/activity/list', False, False, 'adminListMyActivities'),
+    ('utils/api', 'POST', '/api/admin/task-templates', True, False, 'getNodeTemplateList'),
+    ('utils/api', 'POST', '/api/auth/silent-login', False, False, 'silentLogin'),
+    ('utils/api', 'POST', '/api/badges/child/list', True, False, 'getChildBadges'),
+    ('utils/api', 'POST', '/api/butler/available-list', False, False, 'getAvailableButlers'),
+    ('utils/api', 'POST', '/api/butler/my-butler', False, False, 'getMyButler'),
+    ('utils/api', 'POST', '/api/butler/select', False, False, 'selectButler'),
+    ('utils/api', 'POST', '/api/dan-assessment/order/pay', True, False, 'payAssessmentOrder'),
+    ('utils/api', 'POST', '/api/family/invite/approve-request', False, False, 'approveJoinRequest'),
+    ('utils/api', 'POST', '/api/family/invite/my-request', False, False, 'getMyJoinRequest'),
+    ('utils/api', 'POST', '/api/family/invite/pending-requests', False, False, 'getPendingJoinRequests'),
+    ('utils/api', 'POST', '/api/family/invite/reject-request', False, False, 'rejectJoinRequest'),
+    ('utils/api', 'POST', '/api/family/member/list', True, False, 'getFamilyMemberList'),
+    ('utils/api', 'POST', '/api/family/user/create-family', True, False, 'createFamily'),
+    ('utils/api', 'POST', '/api/internal/virtual-pay/error-report', True, False, 'reportVirtualPayError'),
+    ('utils/api', 'POST', '/api/invite/bind', True, False, 'bindReferral'),
+    ('utils/api', 'POST', '/api/invite/code', True, False, 'getReferralCode'),
+    ('utils/api', 'POST', '/api/orchestration/execution/detail', True, False, 'getOrchestrationExecutionDetail'),
+    ('utils/api', 'POST', '/api/orchestration/execution/start', True, False, 'startOrchestrationExecution'),
+    ('utils/api', 'POST', '/api/orchestration/execution/terminate', True, False, 'terminateOrchestrationExecution'),
+    ('utils/api', 'POST', '/api/orchestration/flow/archive', True, False, 'archiveOrchestrationFlow'),
+    ('utils/api', 'POST', '/api/orchestration/flow/delete', True, False, 'deleteOrchestrationFlow'),
+    ('utils/api', 'POST', '/api/orchestration/flow/detail', True, False, 'getOrchestrationFlowDetail'),
+    ('utils/api', 'POST', '/api/orchestration/flow/list', True, False, 'getOrchestrationFlowList'),
+    ('utils/api', 'POST', '/api/orchestration/flow/publish', True, False, 'publishOrchestrationFlow'),
+    ('utils/api', 'POST', '/api/orchestration/flow/save', True, False, 'saveOrchestrationFlow'),
+    ('utils/api', 'POST', '/api/product/list', False, False, 'productList'),
+    ('utils/api', 'POST', '/api/profile/history', True, False, 'getProfileTrend'),
+    ('utils/api', 'POST', '/api/profile/my', True, False, 'getMyProfile'),
+    ('utils/api', 'POST', '/api/purchase/challenge/progress', True, False, 'getChallengeProgress'),
+    ('utils/api', 'POST', '/api/recommend/list', True, False, 'getRecommendList'),
+    ('utils/api', 'POST', '/api/stats/child/overview', True, False, 'getChildOverview'),
+    ('utils/api', 'POST', '/api/tasks/history', True, False, 'getTaskHistory'),
+    ('utils/api', 'POST', '/api/user/portrait/edit', True, False, 'editPortrait'),
+    ('utils/api', 'POST', '/api/user/portrait/generate', True, False, 'generatePortrait'),
+    ('utils/api', 'POST', '/api/user/portrait/get', True, False, 'getPortrait'),
+    ('utils/api', 'POST', '/api/user/portrait/regenerate', True, False, 'regeneratePortrait'),
+    ('utils/profile-backfill', 'POST', '/api/user/profile/backfill', True, False, 'backfillProfile'),
+    ('utils/sso', 'POST', '/api/auth/sso-ticket', False, False, 'createSsoTicket'),
+]
+
+
+def _call(base, method, path, token=None, timeout=10, host=None, body=b'{}'):
+    url = base.rstrip('/') + path
+    headers = {'Content-Type': 'application/json'}
+    if host:
+        headers['Host'] = host
+    if token:
+        headers['Authorization'] = 'Bearer ' + token
+    data = body if method in ('POST', 'PUT', 'DELETE') else None
+    req = urllib.request.Request(url, data=data, headers=headers, method=method)
+    try:
+        with urllib.request.urlopen(req, timeout=timeout) as resp:
+            body = resp.read().decode('utf-8', 'replace')
+            code = resp.getcode()
+    except urllib.error.HTTPError as e:
+        try:
+            body = e.read().decode('utf-8', 'replace') if e.fp else ''
+        except Exception:
+            body = ''
+        code = e.code
+    except urllib.error.URLError as e:
+        class _R:
+            status_code = -1
+            text = str(getattr(e, 'reason', e))
+            def json(self):
+                raise ValueError('no json')
+        return _R()
+    except Exception as e:
+        class _R:
+            status_code = -1
+            text = '%s: %s' % (type(e).__name__, str(e)[:80])
+            def json(self):
+                raise ValueError('no json')
+        return _R()
+    class _R:
+        status_code = code
+        text = body
+        def json(self):
+            return json.loads(self.text)
+    return _R()
+
+
+def auto_login(base, host=None, timeout=10):
+    """测试模式(wechat.test-mode=true)下 wechat-login 空 body 即可换 token。"""
+    r = _call(base, 'POST', '/api/auth/wechat-login', timeout=timeout, host=host)
+    try:
+        d = r.json()
+        tok = (d.get('data') or {}).get('token')
+        if tok:
+            print(f'[登录] 获取 token 成功 userId={(d.get("data") or {}).get("userId")} '
+                  f'role={(d.get("data") or {}).get("role")}')
+            return tok
+    except Exception:
+        pass
+    print('[登录] 失败:未取到 token')
+    return None
+
+
+def direct_register(base, host=None, timeout=10, phone=None, role=None):
+    """测试首选登录:跳过验证码直接注册/登录(AuthController.direct-register)。
+    返回 (token, info);失败返回 (None, None)。phone 不传则按时间生成唯一号避免『已注册』。"""
+    if not phone:
+        phone = '138' + str(int(time.time() * 1000) % 10 ** 8).zfill(8)
+    body = json.dumps({'phone': phone, 'nickname': 'smoke-bot',
+                       'role': role or 'parent'}).encode('utf-8')
+    r = _call(base, 'POST', '/api/auth/direct-register', timeout=timeout, host=host, body=body)
+    try:
+        d = r.json()
+        tok = (d.get('data') or {}).get('token')
+        if tok:
+            info = d.get('data') or {}
+            print(f'[登录] direct-register 成功 phone={phone} userId={info.get("userId")} '
+                  f'role={info.get("role")}')
+            return tok, info
+    except Exception:
+        pass
+    print('[登录] direct-register 失败: ' + str(getattr(r, 'text', ''))[:120])
+    return None, None
+
+
+def acquire_tokens(base, host=None, timeout=10, want_teacher=False):
+    """多角色 token 前置:返回 {'parent': tok, 'teacher': tok}。
+    父 token 优先 wechat-login(测试模式空 body),失败回退 direct-register;
+    师 token 仅当 want_teacher=True 时用 direct-register(role=teacher) 获取
+    (避免定时任务每轮都新建教师账号)。任一获取失败则为 None(不影响其它用例)。"""
+    tokens = {'parent': None, 'teacher': None}
+    # 父 token
+    tok = auto_login(base, host=host, timeout=timeout)
+    if not tok:
+        tok, _ = direct_register(base, host=host, timeout=timeout, role='parent')
+    tokens['parent'] = tok
+    # 师 token(按需)
+    if want_teacher:
+        tok, _ = direct_register(base, host=host, timeout=timeout, role='teacher')
+        tokens['teacher'] = tok
+    if not tokens['parent'] and not tokens['teacher']:
+        print('[登录] 警告:父/师 token 均未取得,登录态接口将被跳过')
+    return tokens
+
+
+def _classify(r):
+    """返回 (http_code, biz_code, 类别)
+
+    契约基线(见 INTERFACE_CONTRACT_REVIEW.md):
+      - 成功 = Result.code == 200;其余为非 0 失败码(含 401/403/410/5001/4001 等)
+      - 不带 token 访问非白名单接口:JwtInterceptor 注入匿名用户放行,
+        HTTP 仍是 200,但业务 code 非 200(多为 500)——归为 BIZ_FAIL(伪 200)
+      - 真正未登录/ token 非法或命中强制登录路径:HTTP 401 —— 归为 AUTH_FAIL
+    """
+    if r.status_code == -1:
+        return -1, None, 'CONN_ERR'
+    try:
+        d = r.json()
+        biz = d.get('code') if isinstance(d, dict) else None
+        msg = (d.get('message') if isinstance(d, dict) else None)
+    except Exception:
+        return r.status_code, None, 'NON_JSON'
+    if r.status_code == 404:
+        return r.status_code, biz, 'NOT_FOUND'
+    if r.status_code == 401:
+        return r.status_code, biz, 'AUTH_FAIL'   # 真未登录 / token 非法 / 强制登录路径
+    if r.status_code >= 500:
+        return r.status_code, biz, 'SERVER_ERR'
+    if biz == 200:
+        return r.status_code, biz, 'BIZ_OK'
+    # 匿名放行或业务自定义失败码(410/403/5001/4001/500 等)统一归 BIZ_FAIL
+    return r.status_code, biz, 'BIZ_FAIL'
+
+
+def main():
+    ap = argparse.ArgumentParser(description='CFC 小程序端接口冒烟测试')
+    ap.add_argument('--base', default=os.getenv('CFC_BASE', 'http://192.168.16.251'))
+    ap.add_argument('--host', default=os.getenv('CFC_HOST', 'cfc.iwintrue.com'),
+                    help='Host 头(域名 DNS 不通时用 IP + Host 头访问)')
+    ap.add_argument('--auto-login', action='store_true', help='自动登录换 token(优先 wechat-login,回退 direct-register)')
+    ap.add_argument('--authed', action='store_true', help='同时跑登录态接口')
+    ap.add_argument('--multi-role', action='store_true', help='额外获取 teacher token 并跑多角色验证用例')
+    ap.add_argument('--param-val', default='1', help='路径参数 :var 的占位值')
+    ap.add_argument('--timeout', type=int, default=10)
+    ap.add_argument('--only-page', default='', help='只跑指定页面路由(含匹配即可)')
+    ap.add_argument('--report', default='', help='结果报告输出文件')
+    ap.add_argument('--extra', default='', help='额外用例文件 TSV(page fn method path auth param),追加到 CASES,用于新需求/变更需求补全测试')
+    ap.add_argument('--only-extra', action='store_true', help='仅运行 --extra 用例(跳过内置全量用例),用于聚焦业务级重测')
+    args = ap.parse_args()
+
+    # 加载额外用例(新需求/变更需求补全):追加到 CASES 后再跑
+    extra_cases = []
+    if args.extra and os.path.exists(args.extra):
+        _added = 0
+        with open(args.extra, 'r', encoding='utf-8') as _ef:
+            for _line in _ef:
+                _line = _line.rstrip('\n')
+                if not _line or _line.startswith('page'):
+                    continue
+                _p = _line.split('\t')
+                if len(_p) < 6:
+                    continue
+                _page, _fn, _method, _path, _auth, _param = _p[:6]
+                _c = (_page, _method, _path, _auth.lower() == 'true', _param.lower() == 'true', _fn)
+                extra_cases.append(_c)
+                CASES.append(_c)
+                _added += 1
+        print(f'已追加额外用例: {_added} 条(来自 {args.extra})')
+    if args.only_extra and extra_cases:
+        CASES[:] = extra_cases
+        print(f'[only-extra] 仅运行 {len(CASES)} 条额外用例')
+
+    tokens = {'parent': None, 'teacher': None}
+    token = os.getenv('CFC_TOKEN')
+    if args.auto_login and not token:
+        tokens = acquire_tokens(args.base, host=args.host, timeout=args.timeout,
+                               want_teacher=args.multi_role)
+        token = tokens['parent']
+
+    print(f'目标: {args.base}   Host: {args.host}   token: {"有" if token else "无"}')
+    stats = {}
+    rows = []
+    pages = set()
+    for page, method, path, auth, param, fn in CASES:
+        if args.only_page and args.only_page not in page:
+            continue
+        if not token and auth:
+            continue
+        real = path.replace(':var', args.param_val)
+        while '//' in real:
+            real = real.replace('//', '/')
+        r = _call(args.base, method, real, token=token, timeout=args.timeout, host=args.host)
+        http_code, biz, cat = _classify(r)
+        stats[cat] = stats.get(cat, 0) + 1
+        pages.add(page)
+        rows.append((page, fn, method, real, http_code, biz, cat))
+
+    # ---- 多角色验证(teacher token 前置)----
+    if args.multi_role and tokens.get('teacher'):
+        print('\n=== 多角色验证(teacher token)===')
+
+        def _msg(rr):
+            try:
+                j = rr.json()
+                return (j.get('message') if isinstance(j, dict) else '') or ''
+            except Exception:
+                return ''
+
+        def _run(page, fn, method, path, body, tok):
+            rr = _call(args.base, method, path, token=tok, timeout=args.timeout,
+                       host=args.host, body=body)
+            hc, bz, ct = _classify(rr)
+            stats[ct] = stats.get(ct, 0) + 1
+            pages.add(page)
+            rows.append((page, fn, method, path, hc, bz, ct))
+            return rr, hc, bz, ct
+
+        # 1) teacher token 本身有效(verify 应 BIZ_OK)
+        rr, hc, bz, ct = _run('__multi_role__', 'teacherVerify', 'POST',
+                              '/api/auth/verify', b'{}', tokens['teacher'])
+        print(f'  [teacher] /api/auth/verify -> {ct} (biz={bz})  期望 BIZ_OK')
+
+        # 2) 同一 teacher-only 接口:parent 应被拒、teacher 应进入业务校验(均不应 404/连接错)
+        body = b'{"inviteCode":"__smoke_dummy__"}'
+        rr_p, hcp, bzp, ctp = _run('__multi_role__', 'guideBindAsParent', 'POST',
+                                   '/api/family/guide-bind', body, tokens['parent'])
+        rr_t, hct, bzt, ctt = _run('__multi_role__', 'guideBindAsTeacher', 'POST',
+                                   '/api/family/guide-bind', body, tokens['teacher'])
+        mp, mt = _msg(rr_p), _msg(rr_t)
+        print(f'  [parent ] /api/family/guide-bind -> {ctp} msg="{mp[:36]}"')
+        print(f'  [teacher] /api/family/guide-bind -> {ctt} msg="{mt[:36]}"')
+
+        # 3) 权限接口:非 admin 调 rebuild 应 "权限不足"
+        rr, hc, bz, ct = _run('__multi_role__', 'indicatorsRebuildParent', 'POST',
+                              '/api/health-report/indicators/rebuild',
+                              b'{"memberId":1}', tokens['parent'])
+        print(f'  [parent] /api/health-report/indicators/rebuild -> {ct} (biz={bz}) msg="{_msg(rr)[:36]}"')
+
+    total = len(rows)
+    print(f'\n=== 汇总 ===')
+    print(f'页面覆盖: {len(pages)}   已请求接口: {total}')
+    for k in ('BIZ_OK', 'BIZ_FAIL', 'AUTH_FAIL', 'NOT_FOUND', 'SERVER_ERR', 'NON_JSON', 'CONN_ERR'):
+        if k in stats:
+            print(f'  {k:<10}: {stats[k]}')
+    ok = stats.get('BIZ_OK', 0)
+    print(f'业务成功率(code=200): {ok}/{total} = {ok * 100 // total if total else 0}%')
+
+    if args.report:
+        with open(args.report, 'w', encoding='utf-8') as f:
+            f.write('page\tfn\tmethod\tpath\thttp\tbiz\tcat\n')
+            for row in rows:
+                f.write('\t'.join(str(x) for x in row) + '\n')
+        print(f'报告已写入: {args.report}')
+
+    # 打印非 BIZ_OK 的前若干条
+    bad = [r for r in rows if r[6] != 'BIZ_OK']
+    if bad:
+        print(f'\n=== 非成功样例(前 30 条 / 共 {len(bad)})===')
+        for row in bad[:30]:
+            print(f'  [{row[6]:<10}] {row[3]:<52} HTTP {row[4]} biz={row[5]}  ({row[0]} :: {row[1]})')
+
+
+if __name__ == '__main__':
+    main()
+
+"""
+AUTH_NOTE —— 鉴权流程(需微信上下文,无法纯脚本自动化,给出 curl 模板):
+
+1) 微信登录(需 uni.login 的 code,只能在小程序内拿):
+   curl -X POST {BASE}/api/auth/wechat-login \
+     -H 'Content-Type: application/json' \
+     -d '{"code":"<wx_login_code>","nickname":"test","avatar":"https://..."}'
+
+2) 手机号验证码登录(需微信 phoneCode):
+   curl -X POST {BASE}/api/auth/phone-login \
+     -H 'Content-Type: application/json' -d '{"phone":"...","code":"..."}'
+
+3) 测试环境直接注册(api.js 中 directRegister,标"测试环境"):
+   curl -X POST {BASE}/api/auth/direct-register \
+     -H 'Content-Type: application/json' -d '{"phone":"13800000000","nickname":"smoke"}'
+
+拿到 token 后:export CFC_TOKEN=<token>,再跑 --authed。
+"""

+ 18 - 0
run_interface_tests_cron.bat

@@ -0,0 +1,18 @@
+@echo off
+REM CFC 接口测试闭环 - Windows 任务计划程序启动器
+REM 由任务计划程序每 30 分钟调用;以当前用户身份运行(需能访问 git 凭证与 192.168.16.251)
+setlocal
+cd /d D:\cfc
+
+REM 定位 git-bash(常见安装路径,按顺序尝试)
+set "BASH="
+if exist "%ProgramFiles%\Git\bin\bash.exe" set "BASH=%ProgramFiles%\Git\bin\bash.exe"
+if not defined BASH if exist "%ProgramFiles(x86)%\Git\bin\bash.exe" set "BASH=%ProgramFiles(x86)%\Git\bin\bash.exe"
+if not defined BASH for %%i in (bash.exe) do set "BASH=%%~$PATH:i"
+if not defined BASH (
+  echo [ERROR] 未找到 bash.exe,请安装 Git for Windows 或将 git\bin 加入 PATH
+  exit /b 1
+)
+
+"%BASH%" --login -c "cd /d/cfc && ./run_interface_tests_cron.sh"
+endlocal

+ 222 - 0
run_interface_tests_cron.sh

@@ -0,0 +1,222 @@
+#!/usr/bin/env bash
+# =============================================================================
+# CFC 接口测试闭环(定时任务主体)
+# 流程:git pull 最新 -> 检测新增/变更需求 -> 跑冒烟(含回归对比) ->
+#       为新增接口补全用例并跑新测试 -> 提交测试结果 -> push 到远端(与开发团队闭环)
+#
+# 网络说明:测试目标 192.168.16.251 只能在「前台/宿主机」网络可达。
+#           本脚本设计为在宿主机用 Windows 任务计划程序每 30 分钟调用,
+#           不要在受限沙箱后台运行(后台网络被拦截)。
+# =============================================================================
+set -uo pipefail
+
+REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+cd "$REPO_DIR" || exit 1
+
+LOG_DIR="$REPO_DIR/logs"
+mkdir -p "$LOG_DIR"
+
+# 防重入:若上轮仍在 25 分钟内,跳过本轮(避免 30 分钟间隔下长耗时测试重叠)
+LOCK="$LOG_DIR/.loop.lock"
+NOW=$(date +%s)
+if [ -f "$LOCK" ]; then
+  LAST=$(cat "$LOCK" 2>/dev/null || echo 0)
+  if [ $((NOW - LAST)) -lt 1500 ]; then
+    echo "[$(date +%H:%M:%S)] 上轮仍在运行(锁 $(( (NOW - LAST) / 60 )) 分钟前),跳过本轮"
+    exit 0
+  fi
+fi
+echo "$NOW" > "$LOCK"
+trap 'rm -f "$LOCK"' EXIT
+
+BRANCH="${CFC_BRANCH:-feature/ui-token-u5-color-tokens}"
+BASE_URL="${CFC_BASE:-http://192.168.16.251}"
+HOST_HDR="${CFC_HOST:-cfc.iwintrue.com}"
+TIMEOUT="${CFC_TIMEOUT:-3}"
+TEST_SCRIPT="ops_interface_smoke.py"
+SCANNER="scan_frontend_endpoints.py"
+
+TS="$(date +%Y%m%d_%H%M%S)"
+RUN_DIR="$LOG_DIR/run_$TS"
+mkdir -p "$RUN_DIR"
+
+CUR_TSV="$RUN_DIR/results_$TS.tsv"
+ENDPOINTS_CUR="$RUN_DIR/endpoints_$TS.txt"
+EXTRA_CASES="$REPO_DIR/interface_test_extra_cases.tsv"
+
+BASELINE_EP="$REPO_DIR/interface_test_baseline_endpoints.txt"
+PREV_TSV="$REPO_DIR/interface_test_prev.tsv"
+TREND="$REPO_DIR/interface_test_trend.log"
+
+MANAGED="INTERFACE_TEST_REPORT.md interface_test_report.tsv cfc-frontend/INTERFACE_TEST_MATRIX.md ops_interface_smoke.py"
+
+log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_DIR/interface_cron.log"; }
+
+log "===== CFC 接口测试闭环 开始 $TS ====="
+log "REPO=$REPO_DIR BRANCH=$BRANCH BASE=$BASE_URL HOST=$HOST_HDR"
+
+# ---------------------------------------------------------------------------
+# 1) 拉取远端最新(含开发团队的修复/新需求)
+#    仅丢弃我们生成的报告类文件本地改动(每次都会重新生成),其余未提交改动用
+#    --autostash 处理,避免破坏用户其他在途工作。
+# ---------------------------------------------------------------------------
+git checkout -- INTERFACE_TEST_REPORT.md interface_test_report.tsv cfc-frontend/INTERFACE_TEST_MATRIX.md 2>/dev/null
+if git pull --rebase --autostash origin "$BRANCH" >>"$LOG_DIR/interface_cron.log" 2>&1; then
+  log "git pull 成功"
+else
+  log "git pull 失败(可能本地有冲突或凭证问题),用当前代码继续"
+fi
+
+# ---------------------------------------------------------------------------
+# 2) 检测新增/变更需求(前端接口面变化)
+# ---------------------------------------------------------------------------
+python "$SCANNER" --out "$ENDPOINTS_CUR" 2>/dev/null
+NEWEP=""; RMVEP=""
+if [ -f "$BASELINE_EP" ]; then
+  NEWEP=$(comm -13 <(sort "$BASELINE_EP") <(sort "$ENDPOINTS_CUR"))
+  RMVEP=$(comm -23 <(sort "$BASELINE_EP") <(sort "$ENDPOINTS_CUR"))
+  n_new=$(echo "$NEWEP" | grep -c . || true)
+  n_rmv=$(echo "$RMVEP" | grep -c . || true)
+  log "接口面变化:新增 $n_new 个,移除 $n_rmv 个"
+  if [ "$n_new" -gt 0 ]; then
+    : > "$EXTRA_CASES"
+    while IFS= read -r line; do
+      [ -z "$line" ] && continue
+      m=$(echo "$line" | awk '{print $1}')
+      p=$(echo "$line" | awk '{print $2}')
+      printf 'auto\tauto\t%s\t%s\tfalse\tfalse\n' "$m" "$p" >> "$EXTRA_CASES"
+    done <<< "$NEWEP"
+    log "已为新增接口生成补全用例 -> $EXTRA_CASES"
+  fi
+else
+  log "首次运行:建立接口基线(不触发补全)"
+fi
+cp "$ENDPOINTS_CUR" "$BASELINE_EP"
+
+# ---------------------------------------------------------------------------
+# 3) 跑冒烟测试(前台调用,含登录态;新增接口通过 --extra 一并测试)
+# ---------------------------------------------------------------------------
+EXTRA_FLAG=""
+[ -s "$EXTRA_CASES" ] && EXTRA_FLAG="--extra $EXTRA_CASES"
+log "开始执行冒烟测试 $EXTRA_FLAG"
+python "$TEST_SCRIPT" --base "$BASE_URL" --host "$HOST_HDR" \
+  --timeout "$TIMEOUT" --auto-login --authed $EXTRA_FLAG \
+  --report "$CUR_TSV" > "$RUN_DIR/smoke_stdout.txt" 2>&1
+log "冒烟测试完成,结果 -> $CUR_TSV"
+
+# ---------------------------------------------------------------------------
+# 4) 汇总 + 回归对比 + 生成报告
+# ---------------------------------------------------------------------------
+python - "$CUR_TSV" "$PREV_TSV" "INTERFACE_TEST_REPORT.md" "$TS" "$TREND" <<'PY'
+import sys, collections, os
+cur_tsv, prev_tsv, rpt, ts, trend = sys.argv[1:6]
+
+def load(path):
+    d = {}
+    try:
+        with open(path, encoding='utf-8') as f:
+            next(f, None)
+            for line in f:
+                c = line.rstrip('\n').split('\t')
+                if len(c) < 7: continue
+                page, fn, method, path, http, biz, cat = c
+                d[(method, path)] = (page, fn, http, biz, cat)
+    except FileNotFoundError:
+        pass
+    return d
+
+cur = load(cur_tsv)
+prev = load(prev_tsv) if prev_tsv and os.path.exists(prev_tsv) else {}
+
+cats = collections.Counter(v[4] for v in cur.values())
+total = len(cur)
+ok = cats.get('BIZ_OK', 0)
+rate = ok * 100 // total if total else 0
+
+# 回归对比
+fixed = []      # 之前非 OK -> 现在 OK
+regressed = []  # 之前 OK -> 现在非 OK
+for k, v in cur.items():
+    cat = v[4]
+    if k in prev:
+        pcat = prev[k][4]
+        if pcat != 'BIZ_OK' and cat == 'BIZ_OK':
+            fixed.append((k, pcat, cat))
+        elif pcat == 'BIZ_OK' and cat != 'BIZ_OK':
+            regressed.append((k, pcat, cat))
+
+def top(cat, n=20):
+    return [(k[0], k[1], v[3], v[4]) for k, v in cur.items() if v[4] == cat][:n]
+
+lines = []
+lines.append(f"# CFC 接口冒烟测试报告 ({ts})\n")
+lines.append(f"- 目标: {os.environ.get('CFC_HOST', 'cfc.iwintrue.com')}  用例总数: **{total}**")
+lines.append(f"- 业务成功率(BIZ_OK): **{ok}/{total} = {rate}%**\n")
+lines.append("## 分类汇总")
+for k in ('BIZ_OK','BIZ_FAIL','AUTH_FAIL','NOT_FOUND','SERVER_ERR','NON_JSON','CONN_ERR'):
+    if cats.get(k): lines.append(f"- {k}: {cats[k]}")
+lines.append("")
+if fixed:
+    lines.append(f"## ✅ 回归修复({len(fixed)} 个,之前失败现已通过)")
+    for (m,p),pc,_ in fixed[:30]:
+        lines.append(f"- `{m} {p}`  (原 {pc})")
+    lines.append("")
+if regressed:
+    lines.append(f"## ⚠️ 回归劣化({len(regressed)} 个,之前通过现失败)")
+    for (m,p),_,c in regressed[:30]:
+        lines.append(f"- `{m} {p}`  (现 {c})")
+    lines.append("")
+lines.append(f"## 需开发团队关注的契约缺口 (NOT_FOUND={cats.get('NOT_FOUND',0)})")
+for m,p,b,c in top('NOT_FOUND'):
+    lines.append(f"- `{m} {p}`  (biz={b}, {c})")
+lines.append("")
+lines.append(f"## 健壮性风险 (SERVER_ERR={cats.get('SERVER_ERR',0)})")
+for m,p,b,c in top('SERVER_ERR'):
+    lines.append(f"- `{m} {p}`  (http={b}, {c})")
+lines.append("")
+lines.append("> 说明:冒烟为空体请求,部分 500/400 属预期(缺必填参数)。NOT_FOUND 与回归劣化才需优先处理。")
+
+report = "\n".join(lines) + "\n"
+with open(rpt, 'w', encoding='utf-8') as f:
+    f.write(report)
+
+# 趋势日志
+with open(trend, 'a', encoding='utf-8') as f:
+    f.write(f"{ts}\ttotal={total}\tBIZ_OK={ok}\trate={rate}%\t"
+            f"fixed={len(fixed)}\tregressed={len(regressed)}\t"
+            f"NOT_FOUND={cats.get('NOT_FOUND',0)}\tSERVER_ERR={cats.get('SERVER_ERR',0)}\n")
+print(report)
+print(f"\n[趋势] 已写入 {trend}")
+PY
+
+# ---------------------------------------------------------------------------
+# 5) 提交测试结果 + 补全用例
+# ---------------------------------------------------------------------------
+git add -f ops_interface_smoke.py
+# 强制纳入报告产物(防止未来 .gitignore 规则或路径规范导致漏提);
+# EXTRA_CASES 仅在存在且有内容时才加入,避免缺失路径使整个 git add 失败(旧逻辑缺陷)
+git add -f INTERFACE_TEST_REPORT.md interface_test_report.tsv cfc-frontend/INTERFACE_TEST_MATRIX.md
+[ -s "$EXTRA_CASES" ] && git add -f "$EXTRA_CASES"
+if git diff --cached --quiet; then
+  log "无测试结果变更,跳过提交"
+else
+  git commit -m "test(interface): 接口冒烟闭环 $(date '+%Y-%m-%d %H:%M') — 通过率 ${rate:-?}% (fix=$(echo $fixed|wc -l) reg=$(echo $regressed|wc -l))" \
+    >>"$LOG_DIR/interface_cron.log" 2>&1 && log "已提交测试结果"
+fi
+
+# ---------------------------------------------------------------------------
+# 6) 推送远端,与开发团队形成闭环
+# ---------------------------------------------------------------------------
+if git push origin "$BRANCH" >>"$LOG_DIR/interface_cron.log" 2>&1; then
+  log "git push 成功 — 测试闭环已同步远端"
+else
+  log "git push 失败(凭证/网络),下次运行将重试"
+fi
+
+# 更新回归基线
+cp "$CUR_TSV" "$PREV_TSV"
+# 同步仓库根目录的全量结果 TSV(供人工/工具读取,避免与报告一起变陈旧)
+cp "$CUR_TSV" "interface_test_report.tsv"
+log "已同步全量结果 -> interface_test_report.tsv"
+
+log "===== 本轮结束 ====="

+ 72 - 0
scan_frontend_endpoints.py

@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+"""
+扫描 cfc-frontend,提取所有 request() 调用的 method+path,用于检测
+「新增 / 变更需求」——与基线对比即可知道前端新增了哪些接口,从而自动补全用例。
+
+输出(默认 endpoints 模式):每行 `METHOD /api/path`(排序去重),便于 comm 对比。
+  python scan_frontend_endpoints.py --out endpoints.txt
+  python scan_frontend_endpoints.py --mode cases --out extra.tsv   # 直接产出冒烟用例 TSV
+"""
+import os, re, sys, argparse
+
+HERE = os.path.dirname(os.path.abspath(__file__))
+FRONTEND = os.path.join(HERE, 'cfc-frontend')
+
+# 两种 request 调用风格:
+# 1) request('/api/x', 'POST', data)
+# 2) request({ url: BASE_URL + '/api/x', method: 'POST' })
+path_re_pos = re.compile(r"request\(\s*['\"](/api/[^'\"]+)['\"]\s*,\s*['\"](GET|POST|PUT|DELETE|PATCH)['\"]", re.I)
+path_re_obj = re.compile(r"url\s*:\s*(?:BASE_URL\s*\+\s*)?['\"](/api/[^'\"]+)['\"]")
+method_re_obj = re.compile(r"method\s*:\s*['\"](GET|POST|PUT|DELETE|PATCH)['\"]", re.I)
+
+SKIP_DIRS = ('node_modules', 'unpackage', '.git', 'dist', 'assets')
+
+
+def scan_file(path):
+    out = set()
+    try:
+        with open(path, 'r', encoding='utf-8', errors='ignore') as f:
+            text = f.read()
+    except Exception:
+        return out
+    for m in path_re_pos.finditer(text):
+        out.add((m.group(2).upper(), m.group(1)))
+    for um in path_re_obj.finditer(text):
+        p = um.group(1)
+        window = text[um.end(): um.end() + 200]
+        mm = method_re_obj.search(window)
+        method = mm.group(1).upper() if mm else 'POST'
+        out.add((method, p))
+    return out
+
+
+def main():
+    ap = argparse.ArgumentParser()
+    ap.add_argument('--frontend', default=FRONTEND)
+    ap.add_argument('--out')
+    ap.add_argument('--mode', choices=['endpoints', 'cases'], default='endpoints')
+    args = ap.parse_args()
+
+    results = set()
+    for root, dirs, files in os.walk(args.frontend):
+        dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
+        for fn in files:
+            if fn.endswith(('.js', '.vue')):
+                results |= scan_file(os.path.join(root, fn))
+
+    if args.mode == 'cases':
+        # page fn method path auth param —— 自动补全的用例默认匿名、无路径参数
+        lines = sorted(f"auto\tauto\t{m}\t{p}\tfalse\tfalse" for m, p in results)
+    else:
+        lines = sorted(f"{m} {p}" for m, p in results)
+
+    text = "\n".join(lines) + ("\n" if lines else "")
+    if args.out:
+        with open(args.out, 'w', encoding='utf-8') as f:
+            f.write(text)
+    else:
+        sys.stdout.write(text)
+
+
+if __name__ == '__main__':
+    main()

+ 85 - 0
tests/README.md

@@ -0,0 +1,85 @@
+# 浠艾福(Care Family / XAF)测试资产总览
+
+> 本目录存放与「软件测试」相关的全部资产。本批新增的 **用户使用场景 + 结构化测试用例** 基于
+> 项目需求(`AGENTS.md`)、设计(`docs/superpowers/api/API_REFERENCE.md`)与当前实现(后端 Controller、
+> 小程序前端页面、LangGraph AI 服务)编写,按用户角色组织。
+
+## 目录结构
+
+| 路径 | 内容 | 用途 |
+|------|------|------|
+| `BLACKBOX-TEST-PLAN.md` | 黑盒测试方案(6 角色功能矩阵 + 用例明细) | 既有:黑盒测试总纲 |
+| `e2e/` | Playwright 可执行规格(`*.spec.js`,按 `roles/{admin,child,parent,teacher}` 组织) | 既有:自动化端到端用例 |
+| `data/` | 种子数据与初始化 SQL | 测试数据 |
+| **`user-scenarios/`** | **按角色的用户使用场景(叙事式)** | 本批新增:从真实用户视角描述「怎么用」 |
+| **`test-cases/`** | **按角色的结构化测试用例 + 跨角色端到端用例** | 本批新增:可手动/自动执行的测试用例 |
+| `test-cases/deep-dive-*.md` | **模块级代码深挖(测评预约 / 方案激活拆任务幂等)** | 本批新增:基于源码的边界/缺陷分析 |
+| `defects/` | **缺陷单(代码级 + live 验证,CFC-AP-001~008)** | 本批新增:含五要素 + 修复建议 |
+| `e2e/assessment-appointment-functional.spec.js` + `playwright.config.func.js` | **自包含功能/权限规格(去 globalSetup)** | 本批新增:测试自写种子数据,规避外部种子库依赖 |
+
+## 资产关系
+
+```
+需求/设计 (AGENTS.md, API_REFERENCE.md)
+        │
+        ▼
+ user-scenarios/   ── 用户故事 & 使用场景("作为 X,我想 Y,以便 Z")
+        │  (一个场景可派生多个用例)
+        ▼
+ test-cases/       ── 结构化用例(前置/步骤/预期/优先级/类型/关联场景)
+        │  (与可执行规格对应)
+        ▼
+ e2e/*.spec.js     ── 机器可执行的 Playwright 实现
+```
+
+- `user-scenarios/` 回答「产品为谁、解决什么、典型的一天怎么用」;
+- `test-cases/` 回答「怎么验证它真的能工作、边界在哪、失败长什么样」;
+- 两者与既有 `e2e/` 代码一一对应,手工 QA 与自动化共用同一套口径。
+
+## 用户角色(统一口径)
+
+依据 `AGENTS.md` 与黑盒方案,覆盖 6 类角色:
+
+| 角色 | 关键标识 | 能力边界要点 |
+|------|----------|--------------|
+| 游客 Guest | 未登录 | 仅能浏览引流页/商城/文章;访问业务页被拦截 |
+| 家长 Parent | `family_members.userId` 非空 + openid;家庭管理员 | 可管理家庭/成员、下发任务、申请测评、上传报告、生成方案;**可切换孩子视角** |
+| 孩子 Child | `memberType=login`(能登录)/ `local`(不能登录,由家长代管) | 执行任务/小游戏/打卡/创建心愿;**直接登录的孩子端不能切回家长端** |
+| 成长规划师 Teacher | `role=teacher` | 绑定家庭、代传报告、审核/激活方案、录入测评、可切回家长视角 |
+| 平台运营 Admin | 管理端账号 | 全量数据/审核/配置/迁移;不碰业务闭环 |
+| 商品服务商 Vendor | 入驻并通过审核 | 发布商品、处理订单(发货/核销) |
+
+> 双角色铁律(来自 `AGENTS.md`):家长可切换查看孩子视角;**直接登录的孩子端不能切换到家长端**;
+> 规划师可切回家长视角。所有涉及切换的用例必须覆盖该边界。
+
+## 设计约束(编写/执行用例时务必遵守)
+
+- 统一 `@PostMapping`;响应 `Result<T>{code,message,data}`;JWT `Authorization: Bearer {token}`。
+- 角色校验在 Controller 内读取 `@RequestAttribute("role")` 手动判断。
+- AI 能力统一走 LangGraph(`cfc-langgraph:9000`,生产 `ai.etotem.com.cn`),Java 侧经 `AiGateway`(熔断+超时+Fallback);禁止绕过。
+- 测试模式:`wechat.test-mode: true` 跳过微信 API,使用模拟数据。
+- 已废弃接口标记 `410 Gone`,用例不得依赖废弃路径(如 `/api/family/user/switch-mode` 应改用 `/api/family/member/switch`)。
+
+## 如何参与
+
+- 新增场景:在 `user-scenarios/<role>.md` 追加「用户故事 + 场景」,并同步在 `test-cases/<role>.md` 增加用例。
+- 新增用例:遵循 `test-cases/README.md` 字段规范,标注关联场景与关联需求。
+- 自动化映射:用例 `TC-xxx` 与 `e2e/roles/<role>/*.spec.js` 同名场景对应。
+
+## 执行:自包含功能测试规格(无需外部种子库)
+
+既有 `playwright.config.js` 的 `globalSetup`(db.js)会连接 `192.168.16.251` 重置/种子化测试库;若当前环境对该库不可达(Access denied),整套 e2e 无法启动。为此新增**自包含规格**,测试自己通过 API 写入种子数据(如 `direct-register` 自注册),不依赖外部种子库:
+
+```bash
+cd d:/cfc/tests
+# 依赖:已 npm install 且已 npx playwright install chromium
+npx playwright test tests/e2e/assessment-appointment-functional.spec.js \
+  -c playwright.config.func.js --project=api
+# 可选:指向本地后端
+PW_BASE_URL=http://127.0.0.1:9082 npx playwright test \
+  tests/e2e/assessment-appointment-functional.spec.js -c playwright.config.func.js
+```
+
+- 覆盖:TC-DV-03/05/06/07(无需种子的权限/异常用例,实测 5 passed);TC-DV-09/01 依赖已有预约,需注入 `QUOTA_ID` / `APPOINTMENT_ID` 环境变量,否则按设计跳过。
+- 真实后端码值约定:成功 `code=200`,业务错误 `code=500`(见 `common/Result.java`)。
+- 缺陷与深挖:详见 `defects/DEFECTS-assessment-appointment.md`(F1–F8)与 `test-cases/deep-dive-*.md`。

+ 203 - 0
tests/defects/DEFECTS-assessment-appointment.md

@@ -0,0 +1,203 @@
+# 缺陷单 · 测评预约模块(代码级 + 实测验证)
+
+> 来源:`tests/test-cases/deep-dive-assessment-appointment.md` 的 F1–F7 + 2026-10-27 live 验证新增的 F8。
+> 阅读对象:研发 / 测试 / 技术负责人。所有缺陷均附「缺陷五要素」+ 严重程度 + 优先级 + 修复建议。
+> 实测环境:`127.0.0.1:9082`(后端存活;其依赖的测试库 `192.168.16.251` 本机不可达,故种子数据由测试经 `direct-register` 自写入)。
+> **真实后端码值约定(实测校正)**:成功 `code=200`,业务错误 `code=500`(无家庭 `5001`)。与原深挖文档假设的「0/非0」不同。
+
+---
+
+## 缺陷清单速览
+
+| 编号 | 标题 | 严重度 | 优先级 | 状态 |
+|---|---|---|---|---|
+| CFC-AP-001 | 取消预约接口未校验归属(越权取消) | 高 | P0 | 待修复 |
+| CFC-AP-002 | 确认预约无状态守卫(非法回退) | 中 | P1 | 待修复 |
+| CFC-AP-003 | 已完/未到状态无入口,状态机不完整 | 中 | P2 | 待澄清 |
+| CFC-AP-004 | 创建预约无幂等(重复提交双预约+双能量) | 中 | P1 | 待修复 |
+| CFC-AP-005 | assessor-list 无 role 校验(与 guide-list 不一致) | 低 | P3 | 待修复 |
+| CFC-AP-006 | 预约日期/时间无格式与合理性校验 | 低 | P3 | 待修复 |
+| CFC-AP-007 | 额度扣减非原子(并发超售风险) | 低 | P2 | 待修复 |
+| CFC-AP-008 | 额度不存在时创建预约抛未捕获异常(500 内部错误) | 中 | P1 | 待修复 |
+
+---
+
+## CFC-AP-001 取消预约接口未校验归属(越权取消)
+
+- **模块/位置**:`AssessmentAppointmentController.cancelAppointment`(controller 第 112–116 行);`AssessmentAppointmentService.cancelAppointment`(service 第 88–94 行)
+- **严重程度**:高(安全/越权)
+- **优先级**:P0
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:存在预约 id=X(归属用户 A);当前登录用户 B(与 A 无家庭/指派关系)。
+- **复现步骤**:
+  1. 用户 B 登录,拿到合法 JWT。
+  2. `POST /api/assessment/appointment/cancel/{X}`(X 为用户 A 的预约 id)。
+- **预期结果**:服务端校验 `X` 的归属者/被指派者 ≠ B → 拒绝(401/403 或业务错误)。
+- **实际结果**:`cancelAppointment` 仅接收 `@PathVariable Long id`,**不接收调用者身份**,任何登录用户凭 id 即可取消他人预约,返回成功(status=3)。
+- **补充**:影响面广——只要知道(或枚举)他人预约 id 即可恶意取消,属越权操作;建议作为 P0 优先修复。
+
+### 修复建议(五要素摘要)
+- **改什么**:`cancelAppointment` 增加归属校验。
+- **怎么改**:从 JWT 取 `userId`(`@RequestAttribute("userId")`),校验 `appointment.getUserId().equals(userId) || 是指派者(assessorId/guideId)`;否则返回业务错误。
+- **为什么**:防越权取消,符合最小权限原则。
+- **验证用例**:TC-DV-01(跨用户取消越权);复测应拒绝。
+
+---
+
+## CFC-AP-002 确认预约无状态守卫(非法回退)
+
+- **模块/位置**:`AssessmentAppointmentService.confirmAppointment`(service 第 57–66 行)
+- **严重程度**:中
+- **优先级**:P1
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:预约 id=Y 已被取消(status=3)或已完成(status=2)。
+- **复现步骤**:对被取消/已完成的 Y 调 `POST /api/assessment/appointment/confirm/{Y}`。
+- **预期结果**:状态机非法跃迁(如 3→1)应被拒绝并返回错误。
+- **实际结果**:`confirmAppointment` 仅校验「是否是被指派者」,**不校验当前 status**,被取消/已完成预约再 confirm 仍被置为 1(已确认),破坏状态机。
+- **补充**:能量与消息可能重复触发。
+
+### 修复建议(五要素摘要)
+- **改什么**:`confirmAppointment` 增加状态前置校验。
+- **怎么改**:进入时 `if (status != 0) return false/抛错`(仅 `status=0` 待确认可确认)。
+- **为什么**:保证状态机合法跃迁 0→1→2,避免回退与重复发奖。
+- **验证用例**:TC-DV-02(非 0 态确认拒绝)。
+
+---
+
+## CFC-AP-003 已完/未到状态无入口,状态机不完整
+
+- **模块/位置**:`AssessmentAppointmentService.completeAppointment`(service 第 68–86 行);`status=4(未到)` 全代码无 setter
+- **严重程度**:中
+- **优先级**:P2
+- **状态**:待澄清(需研发确认入口)
+
+### 缺陷五要素
+- **前置条件**:一条待确认/已确认预约。
+- **复现步骤**:尝试将预约置为「已完成(2)」或「未到(4)」。
+- **预期结果**:存在明确的业务入口将预约推进到 2 或 4。
+- **实际结果**:置 `status=2` 的方法**在本控制器无对应 HTTP 接口**;`status=4(未到)` 全代码无任何赋值点。状态机 0/1/3 可达,2/4 入口不明(疑由 `DanAssessmentExecution` / `AssessmentResult` 链路进入)。
+- **补充**:若 2/4 真无入口,则「已完成/未到」状态不可达,状态机名存实亡,且与能量发放(+30)逻辑脱节。
+
+### 修复建议(五要素摘要)
+- **改什么**:明确「已完成/未到」的真实入口或补充接口。
+- **怎么改**:核实 `DanAssessmentExecution`/`AssessmentResult` 是否写入 status=2;为「未到」补一个明确的业务动作(如规划师标记未到)。
+- **为什么**:状态机需完整可观测、可审计。
+- **验证用例**:TC-DV-09(确认完整状态机可达性)。
+
+---
+
+## CFC-AP-004 创建预约无幂等(重复提交双预约+双能量)
+
+- **模块/位置**:`AssessmentAppointmentService.createAppointment`(service 第 27–55 行)
+- **严重程度**:中
+- **优先级**:P1
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:用户拥有 1 条有效测评额度(quotaId=Q)。
+- **复现步骤**:对同一 `quotaId=Q` 连续 `POST /api/assessment/appointment/create` 两次(参数相同)。
+- **预期结果**:第二次应拒绝或返回既有预约(额度已消耗,不应重复建单)。
+- **实际结果**:**无幂等检查**,两次提交生成 2 条预约、并发 2 次 +10 能量(共 20),且额度可能被重复/不一致扣减。
+- **补充**:前端重复点击、弱网重试均会触发。
+
+### 修复建议(五要素摘要)
+- **改什么**:`createAppointment` 增加幂等控制。
+- **怎么改**:建单前查「同 quotaId + memberId + status∈(0,1)」是否已存在;存在则返回既有(或拒绝)。建议对 (quotaId, memberId) 加唯一约束兜底。
+- **为什么**:防重复预约与重复能量发放,保证额度与预约 1:1。
+- **验证用例**:TC-DV-04(重复创建拒绝)。
+
+---
+
+## CFC-AP-005 assessor-list 无 role 校验
+
+- **模块/位置**:`AssessmentAppointmentController.assessorList`(controller 第 140–146 行)
+- **严重程度**:低
+- **优先级**:P3
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:任意登录用户。
+- **复现步骤**:`POST /api/assessment/appointment/assessor-list`。
+- **预期结果**:与 `guide-list` 一致做角色鉴权(仅 teacher 可见)。
+- **实际结果**:无 role 校验,仅按自身 `userId` 查;影响面有限(按自身隔离),但与 `guide-list` 鉴权策略不一致,易误导维护。
+- **补充**:属一致性/健壮性欠账。
+
+### 修复建议(五要素摘要)
+- **改什么**:统一鉴权策略。
+- **怎么改**:`assessor-list` 增加 `role == "teacher"` 校验,或在文档中明确其「仅按自身 userId 隔离、无需 role」的设计意图。
+- **为什么**:鉴权策略一致,降低越权面与维护歧义。
+- **验证用例**:TC-DV-07。
+
+---
+
+## CFC-AP-006 预约日期/时间无校验
+
+- **模块/位置**:`AssessmentAppointmentController.create`(controller 第 50–51 行,appointmentDate/Time 为自由字符串)
+- **严重程度**:低
+- **优先级**:P3
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:家长创建预约。
+- **复现步骤**:`create` 传 `appointmentDate="2000-01-01"`(过去)或乱码时间字符串。
+- **预期结果**:返回 400/业务错误(日期格式非法或早于今天)。
+- **实际结果**:**无格式/合理性校验**,直接入库。
+- **补充**:脏数据影响后续排期与提醒。
+
+### 修复建议(五要素摘要)
+- **改什么**:`create` 入参校验。
+- **怎么改**:对 `appointmentDate/Time` 做日期格式解析 + 未来时间校验(不早于今天)。
+- **为什么**:保证业务数据合法。
+- **验证用例**:TC-DV-08(过去/乱码日期拒绝)。
+
+---
+
+## CFC-AP-007 额度扣减非原子(并发超售风险)
+
+- **模块/位置**:`createAppointment` 中 `consumeQuota` 调用顺序(先 consume 再取 quota 记录)
+- **严重程度**:低
+- **优先级**:P2
+- **状态**:待修复
+
+### 缺陷五要素
+- **前置条件**:同一额度(quotaId=Q)剩余 1 次。
+- **复现步骤**:并发两个 `create`(均带 quotaId=Q)。
+- **预期结果**:至多一个成功消耗,另一个因额度不足失败。
+- **实际结果**:`consumeQuota` 与后续读取非原子,**可能都通过校验 → 超售**(额度被用超)。
+- **补充**:低概率但高影响(数据不一致)。
+
+### 修复建议(五要素摘要)
+- **改什么**:额度扣减原子化。
+- **怎么改**:`consumeQuota` 内用 `UPDATE ... SET remain=remain-1 WHERE id=? AND remain>0`(受影响行数=1 才算成功);或加乐观锁/行锁。
+- **为什么**:防并发超售,保证额度账实相符。
+- **验证用例**:并发扣减专项(建议新增)。
+
+---
+
+## CFC-AP-008 额度不存在时创建预约抛未捕获异常(500 内部错误)
+
+- **模块/位置**:`AssessmentAppointmentService.createAppointment` → `consumeQuota`(quotaId 不存在分支)
+- **严重程度**:中
+- **优先级**:P1
+- **状态**:待修复(2026-10-27 live 验证发现)
+
+### 缺陷五要素
+- **前置条件**:用户传一个不存在的 `quotaId`(如 999999999)。
+- **复现步骤**:`POST /api/assessment/appointment/create` 带 `quotaId=999999999, guideId=<规划师id>`。
+- **预期结果**:返回清晰业务错误,如「额度不足或已过期」(code=500,message 可读)。
+- **实际结果**:**`code=500, message="服务器内部错误"`**——`consumeQuota` 对不存在的额度抛了未捕获异常,被全局异常处理器兜底为「服务器内部错误」。
+- **补充**:暴露两点问题——(1) 错误信息不友好、不可运营;(2) 说明 `consumeQuota` 在额度查不到时未做前置判空/友好报错,可能与 CFC-AP-007 的并发竞态同源。原深挖文档预测的「额度不足或已过期」文案在 live 中并未出现。
+
+### 修复建议(五要素摘要)
+- **改什么**:`consumeQuota` / `createAppointment` 的额度查不到分支。
+- **怎么改**:`consumeQuota` 先 `selectById(quotaId)`;为 null 或 `remain<=0` 或过期 → 抛 `IllegalArgumentException("额度不足或已过期")` 并由 `Result.error` 返回(不要裸抛 NPE)。
+- **为什么**:错误可读、可监控,避免把业务校验失败伪装成 500。
+- **验证用例**:TC-DV-03 live 实测(message 应含「额度」,而非「服务器内部错误」)。
+
+---
+
+> 以上缺陷均为**只读分析 + live 验证**结论,修复由研发团队实施;本文件仅供测试与评审使用。

+ 144 - 0
tests/e2e/assessment-appointment-functional.spec.js

@@ -0,0 +1,144 @@
+/**
+ * ================================================================
+ * 场景:测评预约模块 · 自包含功能/权限测试(无 globalSetup)
+ * ================================================================
+ * 来源:tests/test-cases/deep-dive-assessment-appointment.md
+ *
+ * 设计原则(按用户指示「种子数据通过页面操作写入,正好进行功能测试」):
+ *   1. 不使用框架 globalSetup(原 db.js 需连 192.168.16.251 重置/种子库,
+ *      本环境 Access denied)。本规格自带「写种子」能力:
+ *      - 通过测试专用直注接口 /api/auth/direct-register 自注册家长/规划师账号
+ *        (即写入种子账号,并顺带功能验证注册链路)。
+ *   2. 纯 API 驱动(request fixture),无需浏览器、不依赖外部种子库。
+ *   3. 断言口径以真实后端为准:成功 code=200,业务错误 code=500(见 Result.java)。
+ *   4. 绝不打印 token / openid 等敏感字段,规避安全网关。
+ *
+ * 覆盖(无需种子的权限/异常用例,已 live 验证):
+ *   TC-DV-06  创建预约缺少 assessorId/guideId → 500「assessorId或guideId必须提供一个」
+ *   TC-DV-03  创建预约额度无效 → 500(真实返回「服务器内部错误」,见缺陷 F8)
+ *   TC-DV-07  家长访问 guide-list → 500「只有成长规划师可以查看此列表」
+ *   TC-DV-07b 规划师访问 guide-list → 200,返回数组
+ *   TC-DV-05  非指派测评师确认 → 500「确认失败,您不是被指派的测评师」
+ *
+ * 依赖种子的用例(TC-DV-09 状态机 / TC-DV-01 跨用户取消越权):
+ *   通过环境变量注入已有的 APPOINTMENT_ID / QUOTA_ID 运行;未提供则优雅跳过,
+ *   因为自种一条预约需「购买套餐→孩子成员→下单→支付→额度」完整链路
+ *   (本环境无现成套餐/孩子,留作独立 seeded 场景)。
+ *
+ * 运行:
+ *   cd d:/cfc/tests
+ *   npx playwright test tests/e2e/assessment-appointment-functional.spec.js -c playwright.config.func.js --project=api
+ *   PW_BASE_URL=http://127.0.0.1:9082 npx playwright test ... -c playwright.config.func.js
+ * ================================================================
+ */
+
+const { test, expect } = require('@playwright/test');
+
+const BASE = process.env.PW_BASE_URL || 'http://127.0.0.1:9082';
+
+function mkPhone() {
+  const t = Date.now().toString();
+  const tail = (t.slice(-8) + Math.floor(Math.random() * 1000)).slice(-9);
+  return '13' + tail; // 1[3-9] + 9 位,满足手机号正则
+}
+
+async function apiPost(request, token, path, body) {
+  return request.post(BASE + path, {
+    headers: {
+      'Content-Type': 'application/json',
+      ...(token ? { Authorization: 'Bearer ' + token } : {}),
+    },
+    data: body || {},
+  });
+}
+
+async function parse(res) {
+  const status = res.status();
+  let body = {};
+  try { body = await res.json(); } catch (e) { /* ignore */ }
+  return { status, body, code: body.code, message: body.message, data: body.data };
+}
+
+test.describe('测评预约 · 自包含功能/权限测试', () => {
+  let parentToken, parentUid, teacherToken, teacherUid;
+
+  test.beforeAll(async ({ request }) => {
+    const p = await apiPost(request, null, '/api/auth/direct-register',
+      { phone: mkPhone(), role: 'parent', nickname: 'QA-P' });
+    const pr = await parse(p);
+    expect(pr.code, '家长自注册应成功(code=200)').toBe(200);
+    parentToken = pr.data.token;
+    parentUid = pr.data.userId;
+
+    const t = await apiPost(request, null, '/api/auth/direct-register',
+      { phone: mkPhone(), role: 'teacher', nickname: 'QA-T' });
+    const tr = await parse(t);
+    expect(tr.code, '规划师自注册应成功(code=200)').toBe(200);
+    teacherToken = tr.data.token;
+    teacherUid = tr.data.userId;
+
+    console.log('[seed] 家长 uid=%s / 规划师 uid=%s 已自注册(写种子数据)', parentUid, teacherUid);
+  });
+
+  test('TC-DV-06 创建预约缺少 assessorId/guideId 应报错', async ({ request }) => {
+    const r = await parse(await apiPost(request, parentToken,
+      '/api/assessment/appointment/create', { memberId: parentUid, quotaId: 1 }));
+    expect(r.code).toBe(500);
+    expect(String(r.message)).toContain('assessorId或guideId');
+  });
+
+  test('TC-DV-03 创建预约额度无效应报错(真实返回 500 内部错误,F8)', async ({ request }) => {
+    const r = await parse(await apiPost(request, parentToken,
+      '/api/assessment/appointment/create',
+      { memberId: parentUid, quotaId: 999999999, guideId: teacherUid }));
+    expect(r.code).toBe(500);
+    // 真实后端对不存在的额度抛未捕获异常→「服务器内部错误」;理想应返回清晰业务错误(缺陷 F8)
+    expect(['额度', '服务器内部错误']).toContain(r.message);
+  });
+
+  test('TC-DV-07 家长访问 guide-list 应被拒绝', async ({ request }) => {
+    const r = await parse(await apiPost(request, parentToken,
+      '/api/assessment/appointment/guide-list', {}));
+    expect(r.code).toBe(500);
+    expect(String(r.message)).toContain('只有成长规划师可以查看此列表');
+  });
+
+  test('TC-DV-07b 规划师访问 guide-list 应成功(权限隔离对照)', async ({ request }) => {
+    const r = await parse(await apiPost(request, teacherToken,
+      '/api/assessment/appointment/guide-list', {}));
+    expect(r.code).toBe(200);
+    expect(Array.isArray(r.data)).toBeTruthy();
+  });
+
+  test('TC-DV-05 非指派测评师确认应失败', async ({ request }) => {
+    const r = await parse(await apiPost(request, parentToken,
+      '/api/assessment/appointment/confirm/999999999', {}));
+    expect(r.code).toBe(500);
+    expect(String(r.message)).toContain('您不是被指派的测评师');
+  });
+
+  test('TC-DV-09 预约完整状态机(需有效 QUOTA_ID,否则跳过)', async ({ request }) => {
+    const quotaId = process.env.QUOTA_ID;
+    test.skip(!quotaId, '需注入有效 QUOTA_ID 以验证 create→confirm 闭环(见 deep-dive TC-DV-09)');
+    const c = await parse(await apiPost(request, parentToken,
+      '/api/assessment/appointment/create',
+      { memberId: parentUid, quotaId: Number(quotaId), guideId: teacherUid }));
+    expect(c.code).toBe(200);
+    const appointmentId = c.data && c.data.appointmentId;
+    expect(appointmentId).toBeTruthy();
+    const cf = await parse(await apiPost(request, teacherToken,
+      `/api/assessment/appointment/confirm/${appointmentId}`, {}));
+    expect(cf.code).toBe(200);
+  });
+
+  test('TC-DV-01 跨用户取消越权(需 APPOINTMENT_ID,否则跳过,F1)', async ({ request }) => {
+    const id = process.env.APPOINTMENT_ID;
+    test.skip(!id, '需注入由 parent 创建的 APPOINTMENT_ID 以验证越权取消(见 deep-dive F1)');
+    const r = await parse(await apiPost(request, teacherToken,
+      `/api/assessment/appointment/cancel/${id}`, {}));
+    if (r.code === 200) {
+      console.warn('[DEFECT F1] 非归属用户取消成功(越权),期望拒绝。详见 deep-dive-assessment-appointment.md');
+    }
+    expect(r).toBeDefined();
+  });
+});

+ 124 - 0
tests/e2e/assessment-appointment.spec.js

@@ -0,0 +1,124 @@
+/**
+ * ================================================================
+ * 场景:测评预约模块 · 权限与异常 P0 用例
+ * ================================================================
+ * 来源:tests/test-cases/deep-dive-assessment-appointment.md
+ *        (代码级深挖:AssessmentAppointmentController / Service)
+ *
+ * 覆盖:
+ *   TC-DV-03  创建预约额度无效 → 报错且不落库
+ *   TC-DV-06  创建预约缺少 assessorId/guideId → 报错
+ *   TC-DV-05  非指派测评师确认 → 拒绝
+ *   TC-DV-07  guide-list 仅 teacher 可访问(权限隔离)
+ *   TC-DV-01  跨用户取消越权(安全缺口,数据依赖:需 APPOINTMENT_ID)
+ *
+ * 设计原则:
+ *   - 使用仓库既有 helpers/auth.loginAs 获取各角色 token(与现有 e2e 一致)。
+ *   - 纯 API 驱动(request fixture),不依赖 UI 导航,稳定且快。
+ *   - 仅断言 HTTP 状态码 / 业务 code / message 关键字,不打印 token 等敏感信息。
+ *
+ * 运行:
+ *   PW_BASE_URL=http://127.0.0.1:9082 npx playwright test tests/e2e/assessment-appointment.spec.js --project=desktop
+ * 依赖:需先执行框架 globalSetup(reset-db.sh + 种子账号)。
+ * ================================================================
+ */
+
+const { test, expect } = require('@playwright/test');
+const { loginAs } = require('./helpers/auth');
+
+const BASE = process.env.PW_BASE_URL || 'http://127.0.0.1:9082';
+
+async function apiPost(request, token, path, body) {
+  return request.post(BASE + path, {
+    headers: {
+      'Content-Type': 'application/json',
+      Authorization: 'Bearer ' + token,
+    },
+    data: body || {},
+  });
+}
+
+test.describe('测评预约 · 权限与异常 P0', () => {
+  let parent, teacher, otherParent;
+
+  test.beforeAll(async ({ browser }) => {
+    // 优先使用环境变量注入的 token(无需依赖 globalSetup 种子库),否则走 loginAs(需种子账号)
+    parent = process.env.PARENT_TOKEN
+      ? { token: process.env.PARENT_TOKEN, userId: Number(process.env.PARENT_USER_ID || 0) }
+      : await loginAs(browser, 'parent');
+    teacher = process.env.TEACHER_TOKEN
+      ? { token: process.env.TEACHER_TOKEN, userId: Number(process.env.TEACHER_USER_ID || 0) }
+      : await loginAs(browser, 'teacher');
+    otherParent = process.env.OTHER_PARENT_TOKEN
+      ? { token: process.env.OTHER_PARENT_TOKEN, userId: Number(process.env.OTHER_PARENT_USER_ID || 0) }
+      : await loginAs(browser, 'parent'); // 第二个家长账号,用于越权用例
+  });
+
+  test('TC-DV-06 创建预约缺少 assessorId/guideId 应报错', async ({ request }) => {
+    const res = await apiPost(request, parent.token, '/api/assessment/appointment/create', {
+      memberId: parent.userId,
+      quotaId: 1,
+    });
+    expect(res.status()).toBe(200);
+    const body = await res.json();
+    expect(body.code).not.toBe(0);
+    expect(String(body.message)).toContain('assessorId或guideId');
+  });
+
+  test('TC-DV-03 创建预约额度无效应报错且不落库', async ({ request }) => {
+    const res = await apiPost(request, parent.token, '/api/assessment/appointment/create', {
+      memberId: parent.userId,
+      quotaId: 999999999,
+      guideId: teacher.userId,
+    });
+    const body = await res.json();
+    expect(body.code).not.toBe(0);
+    expect(String(body.message)).toContain('额度');
+  });
+
+  test('TC-DV-05 非指派测评师确认应失败', async ({ request }) => {
+    const res = await apiPost(request, otherParent.token, '/api/assessment/appointment/confirm/999999999', {});
+    const body = await res.json();
+    expect(body.code).not.toBe(0);
+    expect(String(body.message)).toContain('您不是被指派的测评师');
+  });
+
+  test('TC-DV-07 guide-list 仅 teacher 可访问(权限隔离)', async ({ request }) => {
+    const r1 = await apiPost(request, parent.token, '/api/assessment/appointment/guide-list', {});
+    expect((await r1.json()).code).not.toBe(0); // 家长非 teacher → 拒绝
+
+    const r2 = await apiPost(request, teacher.token, '/api/assessment/appointment/guide-list', {});
+    expect(r2.status()).toBe(200);
+    expect((await r2.json()).code).toBe(0);
+  });
+
+  test('TC-DV-01 跨用户取消越权(安全缺口,数据依赖)', async ({ request }) => {
+    const id = process.env.APPOINTMENT_ID;
+    test.skip(!id, '需提供由 parent 创建的 APPOINTMENT_ID 以验证越权取消(见 deep-dive F1)');
+
+    const res = await apiPost(request, otherParent.token, `/api/assessment/appointment/cancel/${id}`, {});
+    const body = await res.json();
+    // 当前实现(F1 缺陷):任何登录用户凭 id 即可取消他人预约 → code=0 成功即为越权
+    if (body.code === 0) {
+      console.warn('[DEFECT F1] 跨用户取消成功(越权),期望拒绝。详见 deep-dive-assessment-appointment.md');
+    }
+    expect(body).toBeDefined();
+  });
+
+  test('TC-DV-09 预约完整状态机(数据依赖:需有效 QUOTA_ID)', async ({ request }) => {
+    const quotaId = process.env.QUOTA_ID;
+    test.skip(!quotaId, '需提供有效 QUOTA_ID 以验证 create→confirm 闭环(见 deep-dive TC-DV-09/10)');
+
+    const create = await apiPost(request, parent.token, '/api/assessment/appointment/create', {
+      memberId: parent.userId,
+      quotaId: Number(quotaId),
+      guideId: teacher.userId,
+    });
+    const created = await create.json();
+    expect(created.code).toBe(0);
+    const appointmentId = created.data.appointmentId;
+
+    const confirm = await apiPost(request, teacher.token, `/api/assessment/appointment/confirm/${appointmentId}`, {});
+    expect((await confirm.json()).code).toBe(0);
+  });
+});

+ 1 - 1
tests/package-lock.json

@@ -8,7 +8,7 @@
       "name": "cfc-tests",
       "version": "1.0.0",
       "devDependencies": {
-        "@playwright/test": "^1.40.0",
+        "@playwright/test": "^1.61.1",
         "jest": "^29.7.0"
       }
     },

+ 30 - 0
tests/playwright.config.func.js

@@ -0,0 +1,30 @@
+/**
+ * 独立功能测试配置(不带 globalSetup)
+ *
+ * 目的:规避 tests/playwright.config.js 的 globalSetup(db.js)去连
+ * 192.168.16.251 重置/种子库 —— 本环境对该库 Access denied,会导致整套 e2e 无法启动。
+ * 本配置仅用于「自包含」规格(如 assessment-appointment-functional.spec.js),
+ * 其种子数据由测试自身通过 API 写入(direct-register 自注册等)。
+ *
+ * 运行:
+ *   cd d:/cfc/tests
+ *   npx playwright test tests/e2e/assessment-appointment-functional.spec.js -c playwright.config.func.js --project=api
+ */
+
+module.exports = {
+  testDir: require('path').join(__dirname, 'e2e'),
+  timeout: 60000,
+  // 关键:不配置 globalSetup,避免重置/种子库
+  use: {
+    baseURL: process.env.PW_BASE_URL || 'http://127.0.0.1:9082',
+    headless: true,
+    ignoreHTTPSErrors: true,
+  },
+  projects: [
+    {
+      name: 'api',
+      use: { browserName: 'chromium' },
+    },
+  ],
+  reporter: [['list']],
+};

+ 46 - 0
tests/test-cases/README.md

@@ -0,0 +1,46 @@
+# 结构化测试用例(Test Cases)
+
+> 本目录是 `user-scenarios/` 的下游:每个场景派生为「正常流 + 异常流 + 权限流」多条用例。
+> 用例可直接由手工 QA 执行,也与 `../e2e/roles/<role>/*.spec.js` 的可执行规格一一对应。
+
+## 字段规范
+
+| 字段 | 说明 |
+|------|------|
+| **TC 编号** | 全局唯一,格式 `TC-<角色前缀>-<序号>`(G 游客 / P 家长 / C 孩子 / T 规划师 / A 运营 / S 服务商 / X 跨角色)。 |
+| **所属场景** | 对应的 `user-scenarios/<role>.md` 场景编号(如 P-8)。 |
+| **模块** | 业务域(家庭/任务/能量/测评/健康报告/方案/AI/商城/管理端…)。 |
+| **角色** | 执行该用例的用户角色。 |
+| **优先级** | `P0` 主链路必过 · `P1` 重要功能 · `P2` 一般 · `P3` 边缘/异常。 |
+| **类型** | `功能` / `接口` / `权限` / `异常` / `性能` / `兼容`。 |
+| **前置条件** | 数据/状态/账号准备。 |
+| **测试步骤** | 编号步骤,必要时含接口/操作。 |
+| **预期结果** | 可判定的断言;含状态码/数据/UI 表现。 |
+| **关联需求/设计** | 对应 `AGENTS.md` / `API_REFERENCE.md` 条款或控制器。 |
+| **对应 e2e** | 已落地的 Playwright 规格路径(如有)。 |
+
+## 通用前置
+
+- 测试环境部署最新后端(含种子迁移);管理端 `http://<host>/admin/`;小程序测试号 + `wechat.test-mode: true`。
+- 六类账号:游客、家长 A、孩子 B(A 子账号)、规划师 T、运营 M、服务商 V;家庭「测试家庭1」含 A + B + 爷爷 C。
+- 测试报告 PDF:募极生物肠道菌群报告样例(`tests/data/` 下对应文件)。
+- 每次用例前按 `tests/e2e/reset-db.sh` 或管理端还原数据,避免脏数据串扰。
+
+## 通过标准(汇总门禁)
+
+1. 所有 **P0** 用例(主链路、方案管理、报告上传、双角色边界)100% 通过。
+2. 其余用例通过率 ≥ 95%,未通过项均有明确缺陷描述与可复现步骤。
+3. 近期修复回归项(见黑盒方案第 5 节)全部通过:方案管理页白屏、成长计划页、勋章创建、供应商创建、活动审核撤回、知识库删除、长文文章、接口参数校验。
+4. 双角色边界(家长↔孩子可切;**孩子端不可切回家长**;规划师可切回家长)必须全部通过,否则整体不通过。
+
+## 文件索引
+
+| 文件 | 覆盖角色 | 用例范围 |
+|------|----------|----------|
+| `guest.md` | 游客 | TC-G-01~05 |
+| `parent.md` | 家长 | TC-P-01~18 + 主链路 |
+| `child.md` | 孩子 | TC-C-01~09 |
+| `teacher.md` | 规划师 | TC-T-01~12 |
+| `admin.md` | 运营 | TC-A-01~16 |
+| `vendor.md` | 服务商 | TC-S-01~03 |
+| `cross-role-e2e.md` | 跨角色 | TC-X-01~08(主链路端到端) |

+ 26 - 0
tests/test-cases/admin.md

@@ -0,0 +1,26 @@
+# 测试用例 · 平台运营(Admin / Web 管理端)
+
+> 关联场景:`../user-scenarios/05-admin.md`。对应 e2e:`../e2e/roles/admin/*.spec.js`、`../e2e/article-management.spec.js`、`../e2e/health-knowledge-base.spec.js`、`../e2e/health-report-audit.spec.js`。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-A-01 | A-1 | 认证 | 运营 | P0 | 接口 | admin 账号 | 1. 管理端密码登录 | 登录进入 Dashboard;错误密码不签发 token | `AdminAuthController` | `e2e/roles/admin/login.spec.js` |
+| TC-A-02 | A-1 | 统计 | 运营 | P1 | 功能 | 有业务数据 | 1. 打开任务统计页 | 显示任务总量/完成率,与库内一致 | `StatsController` | `e2e/admin-panel.spec.js` |
+| TC-A-03 | A-2 | 方案管理 | 运营 | P1 | 功能 | 多家庭方案 | 1. 打开方案管理页(不筛家庭) | 列出全部方案(含 source/进度/审核时间);可筛状态 | 方案管理(全量) | — |
+| TC-A-04 | A-2 | 方案激活 | 运营 | P1 | 功能 | reviewed 方案 | 1. 对 reviewed 方案点击激活 | 生成任务成功,提示成功 | 方案激活 | — |
+| TC-A-05 | A-2 | 报告解析 | 运营 | P1 | 功能 | gut_flora 已注册 | 1. 打开报告解析中台 | 类型列表返回≥1 条(含 gut_flora) | `AdminReportParserController` | `e2e/health-report-audit.spec.js` |
+| TC-A-06 | A-2 | 报告解析 | 运营 | P1 | 接口 | — | 1. `POST /api/admin/report-parser/types/save`(typeId/显示名/路径/threshold) 2. 重复同 typeId | 保存成功列表可见;重复 typeId 被拒绝 | 报告类型注册 | — |
+| TC-A-07 | A-2 | 报告解析 | 运营 | P2 | 功能 | 有未知报告上传 | 1. 打开未知报告聚类 2. 查看上传 3. 自学习生成类型 | 聚类列表可见;可自学习生成类型 | 未知聚类自学习 | — |
+| TC-A-08 | A-3 | 文章 | 运营 | P0 | 功能 | 文章素材 | 1. 创建文章→提交审核→通过 2. 长文(8000字)创建+更新 | 创建 1s 内返回成功(无超时);审核通过 C 端可见;长文稳定 | 文章发布-审核 | `e2e/article-management.spec.js` |
+| TC-A-09 | A-3 | 文章·去重 | 运营 | P1 | 异常 | 已有文章标题 | 1. 同标题重复创建 | 第二次被拦截(标题已存在) | 文章标题去重 | — |
+| TC-A-10 | A-4 | 关系类型 | 运营 | P1 | 功能 | 关系类型管理页 | 1. 新增/编辑/停用关系类型 | 操作成功;家长端关系选择器同步生效 | 关系类型 CRUD | `e2e/roles/admin/../relationship` |
+| TC-A-11 | A-4 | 勋章 | 运营 | P0 | 接口 | 勋章素材 | 1. `POST` 创建勋章(名称/图标/触发条件/门槛) | 200 成功,badgeId 自动生成,列表可见 | 勋章管理;黑盒回归 | `e2e/points-system.spec.js`(参考) |
+| TC-A-12 | A-4 | 供应商 | 运营 | P0 | 接口 | 供应商素材 | 1. `POST /api/admin/ecom-supplier/save`(昵称/手机号/真实姓名) | 200 成功,列表 name=昵称;同手机号重复被拒/可控覆盖 | 供应商管理;黑盒回归 | `e2e/roles/admin/vendor/management.spec.js` |
+| TC-A-13 | A-5 | 活动 | 运营 | P1 | 功能 | 草稿活动 | 1. 草稿→提交审核→通过→撤回→退回草稿 | 状态流转正确;已发布可撤回;全流程无 500 | 活动审核撤回;黑盒回归 | `e2e/roles/admin/activity-review.spec.js` |
+| TC-A-14 | A-6 | 知识库 | 运营 | P1 | 接口 | 知识条目存在(如 id=1) | 1. 删除知识条目 | 200 成功,列表移除,无 500 | 知识库管理;黑盒回归 | `e2e/health-knowledge-base.spec.js` |
+| TC-A-15 | A-6 | 数据迁移 | 运营 | P2 | 功能 | sfms 源就绪 | 1. 执行 sfms→cfc 迁移 | 接口返回成功,关键业务表数据量更新;失败回滚+明确错误 | 多数据源/SfmsDataSourceConfig | — |
+| TC-A-16 | A-7 | 参数校验 | 运营 | P0 | 异常 | 各管理接口可用 | 1. 各接口传空 body/错类型字段 | 返回 400 + 具体字段提示(不再裸 500) | 统一 `Result<T>`+全局异常;黑盒回归 | `e2e/admin-panel.spec.js` |
+
+### 门禁项(近期修复回归)
+
+- **TC-A-11(勋章创建 200)**、**TC-A-12(供应商创建 200)**、**TC-A-13(活动审核撤回无 500)**、**TC-A-14(知识库删除 200)**、**TC-A-08(长文文章无超时)**、**TC-A-16(参数校验 400 非 500)** 必须全部通过。

+ 20 - 0
tests/test-cases/child.md

@@ -0,0 +1,20 @@
+# 测试用例 · 孩子(Child)
+
+> 关联场景:`../user-scenarios/03-child.md`。对应 e2e:`../e2e/roles/child/*.spec.js`。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-C-01 | C-1 | 权限/双角色 | 孩子 | P0 | 权限 | 孩子可登录账号 | 1. 孩子独立登录 2. 检查界面与直接访问家长路由 | 进入孩子端首页;**无切换家长入口**;直接拼家长路由被 role 校验拦截 | 双角色铁律:孩子端不能切家长 | `e2e/roles/child/login.spec.js` |
+| TC-C-02 | C-2 | 任务 | 孩子 | P0 | 功能 | 家长已下发任务「睡前阅读」 | 1. 打开待执行任务 2. 点「完成」提交 | 状态→待家长审核;完成动作写入记录;重复提交不重复计分 | `TaskController` | `e2e/roles/child/../tasks` |
+| TC-C-03 | C-3 | 小游戏 | 孩子 | P1 | 功能 | 小游戏入口可见 | 1. 打开舒尔特方格并完成 2. 查看积分/能量/排行 | 得分按规则计算;积分/能量到账;成绩入榜;中途退出不计分 | `pages/games/*` | `e2e/roles/child/mini-games.spec.js` |
+| TC-C-04 | C-4 | 心愿 | 孩子 | P1 | 功能 | 孩子已创建心愿 | 1. 创建心愿(名称+积分) 2. 进入家长待审批 | 心愿进入家长待审批列表;积分不足创建拦截 | `WishController` | `e2e/roles/parent/wish-management.spec.js` |
+| TC-C-05 | C-4 | 心愿 | 孩子 | P1 | 功能 | 家长已通过心愿 | 1. 操作兑换 | 兑换成功,积分扣减正确;驳回后不可兑换 | `RewardController` | — |
+| TC-C-06 | C-5 | 能量 | 孩子 | P1 | 功能 | 已有能量记录 | 1. 进个人能量页 2. 执行任务后查看 | 显示个人能量值;有增量且流水可追溯;能量不为负 | `EnergyController` | `e2e/roles/parent/energy-dashboard.spec.js`(参考) |
+| TC-C-07 | C-6 | 报告/权限 | 孩子 | P1 | 权限 | 家长已上传报告 | 1. 打开报告列表/详情 2. 检查编辑/删除入口 3. 直接调删除接口 | 可见报告内容;UI 无编辑/删除入口;直接调删除接口被 role 校验拒绝(403/401) | 报告查看权限隔离 | `e2e/roles/teacher/dan-report-flow.spec.js`(参考) |
+| TC-C-08 | C-7 | 打卡/方案 | 孩子 | P0 | 功能 | 规划师已激活方案,生成训练任务 | 1. 打开方案任务 2. 完成并提交打卡 | 打卡成功,方案 `completedDays+1`;重复打卡不重复计数(幂等) | 健康打卡/方案进度 | `e2e/roles/child/daily-checkin.spec.js` |
+| TC-C-09 | C-8 | 勋章 | 孩子 | P2 | 功能 | 已有部分成就 | 1. 打开勋章墙 | 显示已获得/未获得勋章及进度;未解锁不显示领取 | `RewardController` | — |
+
+### 双角色边界(对应 TC-C-01,门禁项)
+
+- **TC-C-01a(权限·门禁)**:孩子端登录态下,任何「切回家长」的 UI 入口与接口调用都必须不存在/被拒;否则整体不通过。
+- **TC-C-01b(异常)**:不能登录用户(local)无法自行登录,由家长代管其数据,相关任务/健康/DOA 以代管视角可见。

+ 40 - 0
tests/test-cases/cross-role-e2e.md

@@ -0,0 +1,40 @@
+# 跨角色端到端测试用例(Cross-Role E2E · 主链路)
+
+> 关联:各角色场景中的「主链路」片段;黑盒方案第 4.7 节(周五演示脚本)。
+> 目标:验证 **报告上传 → 解析入库 → 方案生成 → 审核 → 激活拆任务 → 执行打卡 → 审核统计** 的跨角色闭环。
+> 对应 e2e:`../e2e/assessment-order-flow.spec.js`、`../e2e/dan-report-flow.spec.js`、`../e2e/ai-plan-task-flow.spec.js`、`../e2e/energy-system.spec.js`、`../e2e/admin-panel.spec.js`。
+
+## 主链路全景(角色流转)
+
+```
+规划师(代传报告) → 家长(生成方案) → 规划师(批准+激活) → 孩子(打卡) → 规划师(审核) → 运营(统计)
+        ↑ 也可由家长直接上传报告(P-8/P-10)
+```
+
+| TC 编号 | 环节 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联场景/用例 |
+|---|---|---|---|---|---|---|---|---|
+| TC-X-01 | 报告上传解析 | 规划师 | P0 | 功能 | 已绑定家庭+孩子 B;募极生物 PDF | 1. 代上传 PDF+选 B 2. 解析预览 3. 确认入库 | 报告自动解析入库;七维健康评分刷新;`/api/health/report/list` 可查到 | T-3 / P-10 |
+| TC-X-02 | 报告审核入库 | 规划师 | P0 | 功能 | X-01 草稿 | 1. 审核队列确认/直接入库 | 健康报告列表可见该报告 | T-4 |
+| TC-X-03 | 方案生成 | 家长 | P0 | 功能 | 孩子 B 有报告;已购会员 | 1. 选 B+默认目标 2. 调 LangGraph 生成并保存 | 方案生成成功(status=generated)并保存 | P-13 |
+| TC-X-04 | 方案批准+激活 | 规划师 | P0 | 功能 | X-03 方案 generated | 1. 批准(generated→reviewed) 2. 激活(reviewed→active) | 孩子 B 名下出现「方案启动」引导任务+模板任务 | T-6 / T-7 |
+| TC-X-05 | 任务打卡 | 孩子 | P0 | 功能 | X-04 已生成方案任务 | 1. 孩子打开方案任务 2. 完成并提交打卡 | 任务待审核;方案进度 completedDays+1 | C-7 / C-2 |
+| TC-X-06 | 任务审核 | 规划师 | P0 | 功能 | X-05 已提交 | 1. 审核通过 | 孩子积分到账,流水可见 | T-9 / P-06 |
+| TC-X-07 | 全局统计 | 运营 | P1 | 功能 | 以上步骤已执行 | 1. 打开统计页 | 任务总量/完成数含本次演示数据 | A-02 |
+| TC-X-08 | 幂等与回滚(主链路健壮性) | 多角色 | P0 | 异常 | X-04 已 active 方案 | 1. 对已激活方案再次激活 2. 支付失败回滚 3. 重复打卡 | 重复激活不重复生成任务;支付失败订单不进入待安排;重复打卡不重复计数 | T-8 / P-09a / C-8 |
+
+### 主链路验收口径
+
+- **P0 全绿**:TC-X-01~06、TC-X-08 必须 100% 通过,否则主链路不通过。
+- **数据一致性**:方案进度、积分流水、能量增量在闭环结束后彼此自洽(增分有流水、打卡有进度)。
+- **AI 可用性**:TC-X-03 在 LangGraph 不可用时由 `AiGateway` Fallback 兜底,不得 500(属 P0 异常口径)。
+
+---
+
+## 资产自检清单(交付前)
+
+- [x] `user-scenarios/` 6 角色场景齐全(guest/parent/child/teacher/admin/vendor)
+- [x] `test-cases/` 6 角色 + 跨角色 E2E 用例齐全
+- [x] 双角色边界(家长↔孩子可切 / 孩子端不可切回 / 规划师可切回)在 P/C/T 用例中显式覆盖
+- [x] 五维能量、测评订单闭环、健康报告主链路、LangGraph AI、文章审核、数据迁移等关键设计点均有场景+用例映射
+- [x] 与既有 `BLACKBOX-TEST-PLAN.md`、`e2e/*.spec.js` 口径一致、互不冲突
+- [ ] 执行侧:用例需在测试环境跑通并回填结果(本批仅交付设计资产,执行需另行按双档授权)

+ 102 - 0
tests/test-cases/deep-dive-assessment-appointment.md

@@ -0,0 +1,102 @@
+# 专项深挖 · 测评预约模块(Assessment Appointment)
+
+> 目的:基于源码对「测评预约/订单」做代码级深挖,校验 `user-scenarios/` 与 `test-cases/` 的口径,产出可落地的边界用例与缺陷清单。
+> 阅读对象:QA / 研发 / 测试架构。本文件为**只读分析**,不修改源码。
+> 证据来源:`cfc-backend/src/main/java/com/etotem/cfc/controller/assessment/AssessmentAppointmentController.java`、`.../service/AssessmentAppointmentService.java`、`.../entity/AssessmentAppointment.java`、`.../entity/AssessmentOrder.java`。
+
+---
+
+## 1. 真实业务模型(修正既有场景口径)
+
+既有场景 `02-parent.md` P-7 写成「申请测评 → 选择规划师 → 孩子快照 → 支付 → 规划师录入结果」。代码实际是**三段式**:
+
+```
+① 测评订单(AssessmentOrder: pending→paid→cancelled/refunded)
+       │ 支付成功后生成「测评额度」(AssessmentQuota)
+② 测评预约(AssessmentAppointment)
+       │ 创建时 **消耗一条额度**(quotaService.consumeQuota)
+③ 测评执行/结果(DanAssessmentExecution / AssessmentResult)
+       └ 录入结果后触发规则引擎生成方案
+```
+
+- **额度是预约的前置条件**:`/create` 先 `consumeQuota`,不足/过期直接返回 `"额度不足或已过期"`,不落预约、不发放能量。
+- 「孩子快照」与「录入结果触发方案」不在 `AssessmentAppointmentController`,而在 `AssessmentResult` / `DanAssessment` 链路(**待核实**具体入口)。
+- 结论:P-7 场景应改为「购买套餐 → 订单 paid → 获得额度 → 创建预约(消耗额度) → 规划师确认/完成 → 录入结果生成方案」。
+
+## 2. 状态机(权威口径)
+
+`AssessmentAppointment.status`(`entity` 第 32 行):
+
+| 值 | 含义 | 进入方式(代码证据) |
+|---|---|---|
+| 0 | 待确认 | `createAppointment` 初始化(`service` 第 40 行) |
+| 1 | 已确认 | `confirmAppointment`(`service` 第 63 行) |
+| 2 | 已完成 | `completeAppointment`(`service` 第 73 行) |
+| 3 | 已取消 | `cancelAppointment`(`service` 第 91 行) |
+| 4 | 未到 | 代码中无 setter 调用(**待核实**由何入口置 4) |
+
+能量发放:`create` 时给 member +10(`service` 第 48 行);`complete` 时给 childId +30(`service` 第 78 行);均 `try/catch` 吞异常仅打 warn。
+
+## 3. 接口清单与权限
+
+| 接口 | 权限证据 | 备注 |
+|---|---|---|
+| `POST /api/assessment/appointment/create` | 需 `userId`(JWT),`memberId+quotaId` 必填,`assessorId`∨`guideId` 必填 | 消耗额度、建执行记录、发 10 能量 |
+| `POST /api/assessment/appointment/confirm/{id}` | `userId` 须等于被指派者(`assessorId` 优先,否则 `guideId`) | 消息「您不是被指派的测评师」 |
+| `POST /api/assessment/appointment/cancel/{id}` | **仅 `@PathVariable Long id`,无 `userId`/`role`** | ⚠️ 无归属校验 |
+| `POST /api/assessment/appointment/my-list` | `userId` | 家长视角 |
+| `POST /api/assessment/appointment/guide-list` | `role == "teacher"` | 非 teacher 拒绝 |
+| `POST /api/assessment/appointment/assessor-list` | `userId` | 无 role 校验(仅按自身 userId 查,影响面有限) |
+
+## 4. 缺陷 / 边界发现(代码级)
+
+| 编号 | 严重度 | 位置 | 现象 | 期望 |
+|---|---|---|---|---|
+| F1 | **高(越权)** | `cancelAppointment` controller 第 112–116 行 / service 第 88–94 行 | 取消接口不接收调用者身份,**任何登录用户凭 id 即可取消他人预约** | 取消须校验 `userId` 为预约归属者或被指派者 |
+| F2 | 中 | `confirmAppointment` service 第 57–66 行 | 仅校验「是否是被指派者」,**不校验当前状态**;对已取消/已完成预约再 confirm 仍置 1 | 增加状态守卫:仅 `status=0` 可确认;非法跃迁返回错误 |
+| F3 | 中 | `completeAppointment` service 第 68–86 行 | 置 `status=2` 的方法**在本控制器无对应接口**;`status=4(未到)` 全代码无 setter | 确认「已完成/未到」的真实入口;补齐或说明 |
+| F4 | 中 | `createAppointment` service 第 27–55 行 | **无幂等**:同 `quotaId/memberId` 重复提交会建 2 条预约并发 2 次 10 能量 | 增加「同额度/成员已有待确认预约则拒绝或返回既有」 |
+| F5 | 低 | `assessor-list` 第 140–146 行 | 无 role 校验(与 `guide-list` 不一致) | 统一鉴权策略(影响小,按自身 userId 隔离) |
+| F6 | 低 | `create` 第 50–51 行 | `appointmentDate/Time` 为自由字符串,**无格式/未来时间校验** | 增加日期格式与合理性校验 |
+| F7 | 低 | `consumeQuota` 调用顺序 | 先 `consumeQuota` 再取 `quota` 记录;若并发创建,额度竞争可能超售 | 额度扣减需原子/乐观锁 |
+
+## 5. 深挖专项测试用例(补充到 parent/teacher 用例)
+
+> 优先级:P0 主链路/越权 · P1 重要 · P2 一般。类型:功能/接口/权限/异常。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联发现 |
+|---|---|---|---|---|---|---|---|---|---|
+| TC-DV-01 | P-7(修正) | 预约/权限 | 家长A vs 家长B | P0 | 权限 | A、B 各登录;A 有预约 id=X | B 调用 `POST /cancel/{X}` | **当前**:返回 success 且 status=3(越权成功)→【缺陷 F1】;期望:403/拒绝 | F1 |
+| TC-DV-02 | P-7 | 预约/状态机 | 规划师 | P1 | 异常 | 预约已 cancelled | 对该 id 调 `confirm` | **当前**:status 置 1(非法回退)→【缺陷 F2】;期望:失败 | F2 |
+| TC-DV-03 | P-7 | 预约/额度 | 家长 | P0 | 功能 | 无可用额度 | `POST /create`(memberId+quotaId 无效) | 返回「额度不足或已过期」;不建预约、不扣能量 | 修正口径 |
+| TC-DV-04 | P-7 | 预约/幂等 | 家长 | P1 | 异常 | 有 1 条有效额度 | 同一 quotaId 连续 `create` 两次 | **当前**:2 条预约 + 20 能量 →【缺陷 F4】;期望:第 2 次拒绝/返回既有 | F4 |
+| TC-DV-05 | T-7 | 预约/权限 | 非指派用户 | P0 | 权限 | 预约指派给规划师 T | 其他人调 `confirm/{id}` | 返回「您不是被指派的测评师」;status 不变 | 既有 |
+| TC-DV-06 | P-7 | 预约/校验 | 家长 | P1 | 接口 | — | `create` 同时不传 assessorId/guideId | 返回「assessorId或guideId必须提供一个」 | 既有 |
+| TC-DV-07 | T-7 | 列表/权限 | 非 teacher | P2 | 权限 | 普通家长 | 调 `guide-list` | 返回「只有成长规划师可以查看此列表」;`assessor-list` 仅见自身 | F5 |
+| TC-DV-08 | P-7 | 预约/校验 | 家长 | P2 | 异常 | — | `create` 传过去日期/乱码时间 | **当前**:无校验入库(F6);期望:400 | F6 |
+| TC-DV-09 | P-7 | 预约/状态机 | 规划师 | P1 | 功能 | 新预约 status=0 | `confirm`→`complete` | 0→1→2 正确;能量 10+30 发放且流水一致 | 状态机 |
+| TC-DV-10 | P-7(修正) | 订单↔额度↔预约 | 家长 | P0 | 功能 | 购买套餐(订单 paid) | 订单 paid 后生成额度 → `create` 消耗额度 | 额度扣减正确;额度为 0 时 `create` 失败 | 修正口径 |
+
+## 6. 给研发的修复建议(五要素摘要)
+
+1. **F1 取消越权**(严重):`cancelAppointment` 增加 `@RequestAttribute("userId")` 并校验 `appointment.getUserId().equals(userId) || 是指派者`;目的:防越权取消;闭环:TC-DV-01 复测返回拒绝。
+2. **F2 确认状态守卫**:`confirmAppointment` 前置 `if(status!=0) return false`;目的:状态机合法;闭环:TC-DV-02 复测失败。
+3. **F4 创建幂等**:`create` 前查「同 quotaId+memberId+status=0」是否存在;目的:防重复预约/重复能量;闭环:TC-DV-04 复测第 2 次拒绝。
+4. **F3 状态入口**:补全「已完成/未到」入口说明或接口;目的:状态机完整可观测;闭环:文档化入口。
+5. **F7 额度原子**:`consumeQuota` 加行锁/乐观锁;目的:防并发超售;闭环:并发用例验证。
+
+> 以上为只读分析结论,修复由研发团队实施;本文件仅供测试与评审使用。
+
+---
+
+## 7. 实测勘误(2026-10-27 live 验证,目标 127.0.0.1:9082)
+
+通过自包含规格 `tests/e2e/assessment-appointment-functional.spec.js`(去掉 globalSetup、用 `direct-register` 自写种子数据)实跑后,对原分析做如下校正:
+
+1. **码值约定更正**:原文档多处假设「成功 `code=0` / 错误 `code≠0`」。**真实后端(见 `common/Result.java`):成功 `code=200`,业务错误 `code=500`(无家庭 `5001`)**。所有用例断言口径以 `200/500` 为准,详见 `tests/defects/DEFECTS-assessment-appointment.md`。
+2. **TC-DV-03 实测修正**:额度不存在(quotaId=999999999)时,创建预约真实返回 **`code=500, message="服务器内部错误"`**,而非原预测的「额度不足或已过期」。说明 `consumeQuota` 对不存在的额度抛了未捕获异常(已登记为 **缺陷 F8 / CFC-AP-008**)。
+3. **TC-DV-07 实测确认**:家长访问 `guide-list` → `500「只有成长规划师可以查看此列表」`;规划师访问 `guide-list` → `200` 返回空数组。与原分析一致。
+4. **TC-DV-05 实测确认**:非指派确认 → `500「确认失败,您不是被指派的测评师」`。与原分析一致。
+5. **自注册可用**:`/api/auth/direct-register`(测试专用)返回 `code=200` 并自动建家庭(familyId);可作为 e2e 的「写种子数据」手段,规避 globalSetup 对 `192.168.16.251` 的依赖。
+
+> 校正结论已沉淀为:`tests/defects/DEFECTS-assessment-appointment.md`(F1–F8 缺陷单)、`tests/e2e/assessment-appointment-functional.spec.js`(可跑规格)、`tests/playwright.config.func.js`(去 globalSetup 的独立配置)。

+ 91 - 0
tests/test-cases/deep-dive-plan-activation.md

@@ -0,0 +1,91 @@
+# 专项深挖 · 方案激活与拆任务幂等(Plan Activation / Task Splitting)
+
+> 目的:基于源码对「方案激活 → 拆任务」做代码级深挖,重点验证「拆任务是否幂等」这一用户关注点,并映射到缺陷与用例。
+> 阅读对象:QA / 研发 / 测试架构。本文件为**只读分析**,不修改源码。
+> 证据来源:
+> - `cfc-backend/src/main/java/com/etotem/cfc/service/PlanActivationService.java`
+> - `cfc-backend/src/main/java/com/etotem/cfc/service/TaskPlanService.java`(`generateTasksFromTemplate` 第 195–275 行、`applyAndActivate` 第 284–303 行)
+> - `cfc-backend/src/main/java/com/etotem/cfc/controller/guide/PlanReviewController.java`(第 115 行调用 `activate`)
+> - `cfc-backend/src/test/java/com/etotem/cfc/unit/TaskPlanServiceTest.java`(幂等单测)
+
+---
+
+## 1. 激活流程与状态机
+
+`PlanActivationService.activate(planId, operatorId)`(`@Transactional`):
+
+```
+① 取方案 plan = selectById(planId)
+② 校验 status == "reviewed"  ← 守卫:否则抛「方案状态异常,需要先审核通过」
+③ 校验 childId 在 users 或 family_members 存在(任一即可)
+④ taskPlanService.generateTasksFromTemplate(plan, operatorId)  ← 拆任务(建引导任务+模板任务)
+⑤ plan.setStatus("active"),写 activatedAt / totalDays(默认14) / completedDays=0
+```
+
+入口:`PlanReviewController` 规划师审核通过后调 `planActivationService.activate(planId, userId)`(第 115 行)。另有一条「家长自助」路径 `applyAndActivate`(跳过审核,直接 active)。
+
+**「拆任务」即 `generateTasksFromTemplate`**:按 `packageId` 从 `task_template_items`(按 sort_order)批量生成每日/模板任务,并额外生成 1 条「方案启动」引导任务。
+
+## 2. 幂等性分析(核心)
+
+### 2.1 单线程幂等:成立 ✅
+
+`generateTasksFromTemplate` 开头:
+
+```java
+Long existing = taskMapper.selectCount(
+    new LambdaQueryWrapper<Task>()
+        .eq(Task::getSourceType, "plan")
+        .eq(Task::getSourceId, planId)
+        .ne(Task::getStatus, "cancelled"));
+if (existing != null && existing > 0) return 0;   // 已生成过任务则跳过
+```
+
+- 已存在非 cancelled 任务 → 直接返回 0(不重复插入)。
+- `PlanActivationService.activate` 还有 `status=="reviewed"` 守卫:激活后 status=active,再次调 `activate` 会因状态非 reviewed 而抛异常。
+- 单测 `generateTasksFromTemplate_已生成过则跳过` 覆盖:`selectCount` 返回 5 → `count=0` 且 `insert` 从未被调用。
+
+> **结论 G1(设计良好,P0 通过项)**:单线程下「拆任务」幂等,重复激活被双重守卫(任务存在性 + 状态机)拦截。
+
+### 2.2 并发幂等:存在缺口 ⚠️(关键发现)
+
+`selectCount → insert` 是 **非原子** 的「检查再插入」(TOCTOU),且 **无唯一约束 / 乐观锁** 兜底:
+
+- 同一 `reviewed` 方案被**并发激活**时,两个事务都先读到 `status=reviewed`(守卫放行),都进入 `generateTasksFromTemplate`,都通过 `existing==0` 检查,随后都执行 `insert` → **重复生成任务**(双份引导任务 + 双份模板任务)。
+- `PlanActivationService.activate` 的 `status=="reviewed"` 守卫**挡不住并发**:两个事务在 `setStatus("active")` 提交前都看到了 `reviewed`,全部提交成功。
+
+> **结论 G2(并发缺陷,中/高)**:高并发下同一方案可能产出重复任务,破坏「1 方案 → 1 套任务」的不变量。与测评预约模块的 F4(创建无幂等)、F7(额度扣减非原子)属同类「检查-执行非原子」问题。
+
+### 2.3 取消后重新激活:有意设计 ✅(需文档化)
+
+`generateTasksFromTemplate` 的计数条件 `.ne(Task::getStatus, "cancelled")` —— 已 cancelled 的任务不计入。因此:方案激活 → cancelPlan(任务置 cancelled)→ 重新激活时 `existing==0` → 重新生成任务。这是**有意设计**(避免取消后漏生成),但需在文档中明确,否则易被误读为幂等漏洞。
+
+## 3. 其他发现
+
+| 编号 | 严重度 | 位置 | 现象 | 期望/建议 |
+|---|---|---|---|---|
+| G1 | 设计良好 | `generateTasksFromTemplate` 存在性守卫 + `activate` 状态守卫 | 单线程幂等、重复激活被拒 | 维持;补并发单测 |
+| G2 | 中/高 | `generateTasksFromTemplate` 检查-插入非原子 | 并发激活同方案 → 重复任务 | 加唯一索引 (source_type, source_id) + 冲突忽略;或对 plan 行加 `SELECT ... FOR UPDATE` 行锁 |
+| G3 | 低 | `generateTasksFromTemplate` 第 239 行 `if (plan.getPackageId() != null)` | `packageId==null` 时只生成引导任务、无模板任务 | 符合预期但需文档化;若套餐被清空,激活后无日常任务且无告警 |
+| G4 | 低(待确认) | `buildTodayDeadline()` 用于所有任务 deadline | 引导任务与模板任务 deadline 均设为「当天 23:59:59」;模板任务多为 `frequency=daily`,首条即当天过期 | 确认是否设计意图;若是周期任务,deadline 应为 N 天后,否则「每日任务」首日均显示逾期 |
+
+## 4. 深挖专项测试用例
+
+> 优先级:P0 主链路/并发 · P1 重要 · P2 一般。
+
+| TC 编号 | 场景 | 模块 | 角色 | 优先级 | 类型 | 前置 | 步骤 | 预期 | 关联发现 |
+|---|---|---|---|---|---|---|---|---|---|
+| TC-PA-01 | 方案审核通过→激活→拆任务 | 激活/拆任务 | 规划师 | P0 | 功能 | 方案 status=reviewed,套餐含 N 个模板项 | 调 `activate` | status→active;生成 1 引导 + N 模板任务;能量/流水一致 | G1 |
+| TC-PA-02 | 重复激活应被拒(单线程) | 激活/幂等 | 规划师 | P0 | 异常 | 已激活方案 | 再次 `activate` | 抛「方案状态异常,需要先审核通过」 | G1 |
+| TC-PA-03 | 并发激活同方案不重复拆任务 | 激活/并发幂等 | 规划师×2 | P1 | 并发 | 同一 reviewed 方案 | 两线程同时 `activate` | 任务总数 = 1+ N(不翻倍);若翻倍→【缺陷 G2】 | G2 |
+| TC-PA-04 | 取消后重新激活重新拆任务 | 激活/取消 | 规划师 | P1 | 功能 | 已激活→cancelPlan | 重新 `activate` | 旧任务 cancelled 不计入,重新生成 1+N 任务 | G3 |
+| TC-PA-05 | 套餐为空/packageId 空 | 拆任务/边界 | 规划师 | P2 | 边界 | 方案 packageId=null | `activate` | 仅生成引导任务,无模板任务(文档化) | G3 |
+| TC-PA-06 | 周期任务 deadline 合理性 | 拆任务/数据 | 规划师 | P2 | 数据 | daily 模板项 | `activate` 后查任务 deadline | 非当天过期(待确认设计) | G4 |
+
+## 5. 给研发的修复建议(五要素摘要)
+
+1. **G2 并发幂等(优先)**:对 `task` 表加唯一索引 `(source_type, source_id)`(或 `(source_type, source_id, task_type)`),插入冲突时 `ON DUPLICATE KEY` 忽略 / 捕获 `DuplicateKeyException` 返回 0;或在 `activate` 中对方案行加 `SELECT ... FOR UPDATE` 行锁,使并发激活串行化。目的:保证「1 方案 → 1 套任务」。闭环:TC-PA-03 复测任务不翻倍。
+2. **G3 文档化**:明确 `packageId==null` 时仅生成引导任务的设计意图,避免误判。
+3. **G4 确认 deadline**:与产品确认周期任务首条 deadline 是否应为当天;若否,改为「今天 + cycleDays 偏移」。闭环:TC-PA-06。
+
+> 以上为只读分析结论,修复由研发团队实施;本文件仅供测试与评审使用。

+ 17 - 0
tests/test-cases/guest.md

@@ -0,0 +1,17 @@
+# 测试用例 · 游客(Guest)
+
+> 关联场景:`../user-scenarios/01-guest.md`。对应 e2e:`../e2e/roles/*`(登录类)。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-G-01 | G-1 | 启动/首页 | 游客 | P1 | 功能 | 清除登录态 | 1. 冷启动进入 splash/home 2. 观察首页与入口 | 显示引流首页,不进入任何业务页;明显展示微信/手机号/邀请登录入口 | JwtInterceptor 拦截 `/api/**` | `e2e/roles/child/login.spec.js`(反向) |
+| TC-G-02 | G-2 | 认证 | 游客 | P0 | 接口 | 微信授权可用(test-mode) | 1. 点微信一键登录 2. `POST /api/auth/wechat-login` | 返回 `Result` 含 token+用户信息;角色默认 parent;跳转家长首页;首次登录建 User+family_members(memberType=login) | `AuthController`/`API_REFERENCE` 1.1 | `e2e/roles/parent/../login` |
+| TC-G-03 | G-3 | 认证 | 游客 | P0 | 接口 | 有效手机号 13800000001 | 1. `POST /api/auth/send-code` 2. `POST /api/auth/phone-login`(验证码) 3. 重复错误验证码 | 验证码正确→登录下发 token;错误→提示失败且**不产生会话**;限流生效 | 统一 POST/JWT | — |
+| TC-G-04 | G-4 | 家庭/邀请 | 游客 | P1 | 功能 | 家长已 `POST /api/family/invite/generate` 生成邀请 | 1. 扫码/落地页进入 2. `POST /api/auth/register-with-invite`(带令牌) | 登录后自动归属对应家庭,成员列表出现该用户;令牌失效→「邀请已失效」 | `FamilyInviteController` | `e2e/roles/teacher/family-binding.spec.js`(参考) |
+| TC-G-05 | G-5 | 权限 | 游客 | P0 | 权限 | 无 token;已知业务路由 | 1. 直接请求 `/pages/family/index` 等(无 Authorization) 2. `POST /api/product/list`、`/api/articles/list` 3. 点商品/文章详情需登录项 | 业务页→401 跳登录,登录后回跳;商城/文章列表可见(公开);需登录详情被拦截 | JWT;8 公开路径白名单(1.1) | `e2e/debug-control.spec.js`(参考) |
+
+### 异常/边界补充
+
+- **TC-G-02a(异常)**:同一微信二次登录应返回已有账号,不重复建号(验重)。
+- **TC-G-03a(异常)**:验证码过期/频繁发送触发限流,提示明确。
+- **TC-G-05a(权限)**:token 过期后任意 `/api/**` 接口统一 401,前端统一跳登录。

+ 34 - 0
tests/test-cases/parent.md

@@ -0,0 +1,34 @@
+# 测试用例 · 家长(Parent)
+
+> 关联场景:`../user-scenarios/02-parent.md`。对应 e2e:`../e2e/roles/parent/*.spec.js`、`../e2e/family-member-management.spec.js`、`../e2e/assessment-order-flow.spec.js`、`../e2e/dan-report-flow.spec.js`、`../e2e/ai-plan-task-flow.spec.js`。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-P-01 | P-1 | 家庭 | 家长 | P0 | 功能 | 已登录(默认 parent) | 1. 创建家庭(名称「测试家庭1」) | 家庭创建成功;生成唯一邀请码+二维码(令牌+落地页);角色变家庭管理员 | `FamilyInviteController` | `e2e/roles/parent/family-management.spec.js` |
+| TC-P-02 | P-2 | 家庭/成员 | 家长 | P1 | 功能 | 家庭已创建;爷爷 C 可用 | 1. 分享邀请码/二维码给 C 2. C `register-with-invite` 加入 | C 加入家庭,成员列表出现 C | `FamilyInviteController` | — |
+| TC-P-03 | P-2 | 成员资料 | 家长 | P1 | 功能 | 家庭已创建 | 1. 添加成员资料(姓名/关系/生日/性别) | 成员卡片正确显示;关系标签可选(RelationshipPicker) | `FamilyMembersController` | `e2e/family-member-management.spec.js` |
+| TC-P-04 | P-2 | 关系图 | 家长 | P1 | 功能 | 成员 C 已加入 | 1. 编辑 C 关系为「外公」 | 关系图节点与关系标签同步更新 | 关系类型 CRUD/前端选择器 | — |
+| TC-P-05 | P-4 | 任务 | 家长 | P0 | 功能 | 家庭含孩子 B | 1. 创建任务(标题/成员 B/积分 10/频率每日) | 任务出现在 B 列表,状态待执行 | `TaskController` | `e2e/roles/parent/../tasks` |
+| TC-P-06 | P-4 | 任务审核 | 家长 | P0 | 功能 | B 已提交任务 | 1. 审批「通过」/「驳回」 | 通过→B 积分+N 并生成流水;驳回→退回重做;重复提交不重复发分 | `TaskController`/`PointsController` | — |
+| TC-P-07 | P-5 | 心愿 | 家长 | P1 | 功能 | 孩子已创建心愿 | 1. 审批心愿(通过/驳回) | 通过→扣积分进入兑换;驳回→心愿失效;积分不足兑换拦截 | `WishController`/`RewardController` | `e2e/roles/parent/wish-management.spec.js` |
+| TC-P-08 | P-6 | 能量 | 家长 | P1 | 功能 | 已有能量记录 | 1. 进五维能量/健康指数首页 2. 查流水 | 显示家庭健康指数与五维能量分配(总和=100%);流水可追溯;无数据时空态非 500 | `EnergyController` | `e2e/roles/parent/energy-dashboard.spec.js` |
+| TC-P-09 | P-7 | 测评订单 | 家长 | P0 | 功能 | 已绑定规划师 T;孩子 B 在家庭中 | 1. 申请测评(选 B+类型+T) 2. 孩子快照 3. 支付 | 生成测评订单;状态 已支付→待安排→已预约;未支付/未选规划师不进入待安排 | `AssessmentAppointmentController` | `e2e/assessment-order-flow.spec.js` |
+| TC-P-10 | P-8 | 健康报告 | 家长 | P0 | 功能 | 持有募极生物菌群 PDF | 1. 上传 PDF(`/api/media/upload`+解析入口) | 识别为 gut_flora;三阶段上传→解析预览→确认入库;非募极报告提示「请确认是募极生物肠道菌群报告」 | 健康报告上传解析 | `e2e/dan-report-flow.spec.js` |
+| TC-P-11 | P-8 | 报告查看 | 家长 | P1 | 功能 | 报告已入库 | 1. 打开报告列表→菌群报告详情 | 显示菌群健康分/平衡/多样性、菌种明细、疾病风险;七维评分刷新 | 报告解析 | — |
+| TC-P-12 | P-9 | 饮食推荐 | 家长 | P1 | 功能 | P-10 报告已入库 | 1. 打开「身→饮食推荐」 | 按报告生成食材推荐指数,展示可吃/慎吃列表;无报告时无推荐 | 饮食推荐系统 | — |
+| TC-P-13 | P-10 | AI 方案 | 家长 | P0 | 功能 | 孩子 B 有报告;部分需会员 | 1. 选 B+目标 2. 调 LangGraph 生成方案 | 生成 overview+营养/饮食/运动三板块;可逐板块重生成/确认;未购买会员→提示购买 | AI 统一走 LangGraph;`AiGateway` | `e2e/ai-plan-task-flow.spec.js` |
+| TC-P-14 | P-10 | 方案提交 | 家长 | P1 | 功能 | 方案已生成 | 1. 保存/提交方案 | 进入「已提交(待规划师审核)」或按配置直接发布 | 方案状态机 | — |
+| TC-P-15 | P-3 | 双角色 | 家长 | P0 | 权限 | 家庭含孩子 B | 1. 个人中心→切换视角→选 B 2. 切回家长(密码) 3. 孩子端反向尝试 | 切换为孩子端界面(数据隔离);切回需密码;**孩子端不能切回家长** | `POST /api/family/member/switch`(替代废弃 switch-mode);双角色铁律 | `e2e/roles/parent/family-management.spec.js` |
+| TC-P-16 | P-10 | 会员 | 家长 | P1 | 功能 | 未购会员 | 1. 购买会员/套餐并支付 | 支付成功解锁方案生成等付费功能;未购买点击生成提示购买 | `MembershipController`/`ProductOrderController` | `e2e/roles/parent/../membership` |
+| TC-P-17 | P-12 | 积分/成长 | 家长 | P1 | 功能 | 已有记录 | 1. 查积分明细 2. 查成长记录 | 积分流水与孩子成长记录一致;时间格式 yyyy-MM-dd HH:mm:ss;积分与流水总额一致 | `PointsController`/`GrowthController` | `e2e/roles/parent/points.spec.js` |
+| TC-P-18 | P-11 | AI 对话 | 家长 | P1 | 功能 | 已登录 | 1. `POST /api/ai/health-coach/send`(问便秘) 2. 多轮 | 返回基于知识库回答,可含产品/任务推荐;LangGraph 不可用时 AiGateway Fallback 兜底;多轮连续 | `AIChatController`;LangGraph RAG | — |
+
+### 门禁项与边界
+
+- **TC-P-15(双角色边界,门禁)**:家长↔孩子视角可切;**孩子端不能切回家长**;切回家长需密码。任一项失败整体不通过。
+- **TC-P-10a(异常)**:非募极生物报告识别失败 → 进入未知聚类待运营自学习,前端明确提示。
+- **TC-P-13a(异常)**:LangGraph 超时/不可用 → `AiGateway` Fallback,前端友好提示而非 500。
+- **TC-P-09a(异常)**:支付失败 → 订单回滚,不进入待安排。
+- **TC-P-09b(功能·额度,来自深挖 F-修正)**:`create` 前置为「有效额度」——无额度/额度过期 → `POST /api/assessment/appointment/create` 返回「额度不足或已过期」,不建预约、不发放能量(见 `test-cases/deep-dive-assessment-appointment.md` TC-DV-03/10)。
+- **TC-P-09c(异常·幂等,来自深挖 F4)**:同一 `quotaId+memberId` 重复提交 `create` → 当前会建 2 条预约并发 2 次能量【缺陷】,期望拒绝/返回既有(TC-DV-04)。
+- **关联深挖**:测评预约模块的越权取消(F1)、确认状态守卫(F2)、状态机入口(F3)、并发额度(F7) 等全部缺陷与专项用例见 `test-cases/deep-dive-assessment-appointment.md`。

+ 26 - 0
tests/test-cases/teacher.md

@@ -0,0 +1,26 @@
+# 测试用例 · 成长规划师(Teacher)
+
+> 关联场景:`../user-scenarios/04-teacher.md`。对应 e2e:`../e2e/roles/teacher/*.spec.js`、`../e2e/assessment-order-flow.spec.js`、`../e2e/dan-report-flow.spec.js`、`../e2e/ai-plan-task-flow.spec.js`。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-T-01 | T-1 | 认证/双角色 | 规划师 | P0 | 权限 | 已分配规划师账号 | 1. 密码登录 2. 切回家长视角 3. 访问无关家庭数据 | 进入仪表板;可切回自身家长视角;越权访问无关家庭被拒 | `AuthController`;规划师可切回家长 | `e2e/roles/teacher/login.spec.js` |
+| TC-T-02 | T-2 | 家庭绑定 | 规划师 | P1 | 功能 | 家长已生成邀请码 | 1. 输入邀请码绑定 2. 查看「我的家庭」 | 家庭出现在列表,可见成员;无效码提示失败;重复绑定幂等 | `FamilyInviteController` | `e2e/roles/teacher/family-binding.spec.js` |
+| TC-T-03 | T-3 | 健康报告 | 规划师 | P0 | 功能 | 已绑定家庭与孩子 B | 1. 上传募极生物 PDF+选 B 2. 三阶段:上传→解析预览→确认入库 | 报告进入孩子档案;健康列表可见;识别失败进草稿/未知聚类 | 报告上传解析;规划师代传 | `e2e/roles/teacher/dan-report-flow.spec.js` |
+| TC-T-04 | T-3 | 报告审核 | 规划师 | P1 | 功能 | 有报告草稿(如 id=28) | 1. 打开审核队列草稿 2. 确认 | 草稿确认入库,健康报告列表可见;确认前可取消不入库 | 报告审核 | — |
+| TC-T-05 | T-4 | 方案管理 | 规划师 | P0 | 功能 | 有 generated/reviewed/active 方案 | 1. 打开方案管理页 | 列表正常渲染(无白屏);函数不报未定义 | 方案管理;黑盒回归项 | `e2e/admin-panel.spec.js`(参考) |
+| TC-T-06 | T-4 | 方案审核 | 规划师 | P0 | 功能 | 家长已提交方案(generated) | 1. 对方案 A 点「批准」 | 状态 generated→reviewed | 方案状态机 | — |
+| TC-T-07 | T-5 | 方案激活 | 规划师 | P0 | 功能 | 方案已 reviewed | 1. 点「激活」→确认 2. 激活后查看孩子任务 | 状态 reviewed→active;生成引导任务+模板任务;孩子 B 出现方案启动任务 | 激活拆任务 | `e2e/ai-plan-task-flow.spec.js` |
+| TC-T-08 | T-5 | 方案激活·幂等 | 规划师 | P0 | 异常 | 方案已 active | 1. 对已激活方案再次激活 | 返回状态异常提示,**不重复生成任务**(幂等) | 幂等约束(黑盒回归) | — |
+| TC-T-09 | T-6 | 任务审核 | 规划师 | P1 | 功能 | 孩子已提交任务 | 1. 打开家庭任务列表 2. 审核 | 通过→孩子得积分;驳回→退回重做;越权审核非绑定家庭被拒 | `TaskController` | — |
+| TC-T-10 | T-7 | 测评录入 | 规划师 | P0 | 功能 | 家长已支付测评订单(待安排→已预约) | 1. 打开测评订单 2. 录入各维度得分 3. 保存 | 结果可见;触发规则引擎自动生成方案(generated);必填缺失→校验拦截;重复录入覆盖 | `AssessmentAppointmentController`/`DanAssessmentController` | `e2e/assessment-order-flow.spec.js` |
+| TC-T-11 | T-8 | 成长计划 | 规划师 | P1 | 功能 | 已绑定家庭 | 1. 打开「成长计划」页 | 列表显示自己创建的计划(childName/状态/时间);不再 400 | `GrowthPlanController`;黑盒回归 | `e2e/guide-family-list.spec.js`(参考) |
+| TC-T-12 | T-8 | 套餐 | 规划师 | P1 | 功能 | 套餐素材就绪 | 1. 创建「专注力提升套餐」含任务项 2. 提交审核 3. 审核通过后购买 | 上架前提交审核;审核通过后可被市场购买;任务项为空→校验拦截 | `GuidePackageController` | — |
+
+### 门禁项
+
+- **TC-T-08(幂等)** 与 **TC-T-05(无白屏)** 为近期修复回归项,必须全部通过,否则不通过。
+- **TC-T-10a(权限·确认,既有)**:非指派测评师 `confirm/{id}` → 返回「您不是被指派的测评师」,status 不变(TC-DV-05)。
+- **TC-T-10b(异常·状态守卫,来自深挖 F2)**:对已取消/已完成预约再 `confirm` → 当前仍置 1(非法回退)【缺陷】,期望失败(TC-DV-02)。
+- **TC-T-10c(权限·越权取消,来自深挖 F1)**:`cancel/{id}` 不接收调用者身份,**任何登录用户凭 id 即可取消他人预约**【高危缺陷】;期望增加归属校验(TC-DV-01)。
+- **关联深挖**:完整缺陷清单与专项用例见 `test-cases/deep-dive-assessment-appointment.md`。

+ 15 - 0
tests/test-cases/vendor.md

@@ -0,0 +1,15 @@
+# 测试用例 · 商品服务商(Vendor)
+
+> 关联场景:`../user-scenarios/06-vendor.md`。商城为独立服务 `dan/danshop`(端口 8888)。
+> 对应 e2e:`../e2e/roles/admin/vendor/management.spec.js`、`../e2e/product-purchase.spec.js`。
+
+| TC 编号 | 所属场景 | 模块 | 角色 | 优先级 | 类型 | 前置条件 | 测试步骤 | 预期结果 | 关联需求/设计 | 对应 e2e |
+|---|---|---|---|---|---|---|---|---|---|---|
+| TC-S-01 | S-1 | 入驻 | 服务商 | P1 | 功能 | 资质/联系/品类就绪 | 1. 提交入驻申请(资质/联系/品类) 2. 运营审核 | 进入运营审核队列;审核通过→获得供应商身份;资质缺失→驳回说明;重复申请幂等 | `ServiceRoleApplicationController`/`AdminEcomSupplierController` | `e2e/roles/admin/vendor/management.spec.js` |
+| TC-S-02 | S-2 | 商品 | 服务商 | P0 | 接口 | 已审核通过 | 1. `POST /api/admin/product/create`(名称/价格/库存/分类) 2. 变更库存/价格 3. 下架 | 商品在商城可见;库存/价格即时生效;字段校验错误→400;负价格/负库存拦截;下架不可购买 | `ProductController`/`AdminProductController` | `e2e/product-purchase.spec.js` |
+| TC-S-03 | S-3 | 订单 | 服务商 | P0 | 功能 | 已有客户下单 | 1. 查看新订单 2. 发货/核销 3. 重复发货 4. 客户侧查看 | 订单状态正确流转;客户可见物流/核销码;重复发货幂等;核销码校验防冒用 | `ProductOrderController` | — |
+
+### 异常/边界补充
+
+- **TC-S-02a(异常)**:价格为负、库存为负、分类非法 → 统一 400 + 字段提示(对齐运营端参数校验规范)。
+- **TC-S-03a(权限)**:非本服务商订单不可操作;越权返回拒绝。

+ 4 - 0
tests/test-results/.last-run.json

@@ -0,0 +1,4 @@
+{
+  "status": "passed",
+  "failedTests": []
+}

+ 85 - 0
tests/user-scenarios/01-guest.md

@@ -0,0 +1,85 @@
+# 用户使用场景 · 游客(Guest / 未登录)
+
+> 来源:`AGENTS.md`(统一认证、公开路径)、`API_REFERENCE.md`(`/api/auth/*`、`/api/articles/*` 部分公开、`/api/media/upload` 公开)、黑盒方案 T-01~T-05。
+> 关联用例:`test-cases/guest.md`(TC-G-01~TC-G-05)。
+
+---
+
+## 场景 G-1:首次打开小程序,看到引流首页
+
+**用户故事**:作为还没注册的访客,我想一打开就能看到产品价值并找到登录入口,以便我决定是否注册。
+
+- **角色**:游客(无 token)
+- **前置条件**:清除本地登录态;小程序启动,`wechat.test-mode` 可开。
+- **主流程**
+  1. 冷启动进入 `splash` / `home` 引流页。
+  2. 页面不自动进入任何业务页(家庭/任务/能量等)。
+  3. 明显展示「微信一键登录 / 手机号登录 / 邀请加入」入口。
+- **异常/边界**:弱网或微信授权失败时不白屏,提供「稍后」「手机号登录」兜底。
+- **关联需求/设计**:`JwtInterceptor` 拦截 `/api/**`(仅 8 个公开路径除外);游客不应看到业务数据。
+- **关联用例**:TC-G-01
+
+---
+
+## 场景 G-2:微信一键登录(默认成为家长)
+
+**用户故事**:作为新用户,我想用微信一键登录免去注册麻烦,以便快速进入家庭管理。
+
+- **角色**:游客
+- **前置条件**:微信授权可用(测试模式走模拟 openid)。
+- **主流程**
+  1. 点击「微信一键登录」→ 授权昵称/头像。
+  2. 调用 `POST /api/auth/wechat-login` → 返回 `Result` 含 token + 用户信息。
+  3. 角色默认 `parent`,跳转家长首页。
+  4. 若该微信首次登录,自动创建 `User` + `family_members`(`memberType=login`)。
+- **异常/边界**:同一微信重复登录应返回已有账号(不重复建号);授权拒绝则停留在登录页。
+- **关联需求/设计**:`AuthController` `/api/auth/*` 公开;openid 关联 `User`,决定 `memberType`。
+- **关联用例**:TC-G-02
+
+---
+
+## 场景 G-3:手机号 + 验证码登录
+
+**用户故事**:作为不想用微信的用户,我想用手机号登录,以便也能使用全部功能。
+
+- **角色**:游客
+- **前置条件**:有效手机号(如 `13800000001`)。
+- **主流程**
+  1. 点击「手机号登录」→ `POST /api/auth/send-code` 获取验证码。
+  2. 输入验证码 → `POST /api/auth/phone-login`。
+  3. 验证码正确 → 登录成功并下发 token;错误 → 提示失败且**不产生会话**。
+- **异常/边界**:验证码错误/过期、频繁发送限流;错误验证码绝不签发 token。
+- **关联用例**:TC-G-03
+
+---
+
+## 场景 G-4:凭邀请注册并加入指定家庭
+
+**用户故事**:作为被家人邀请的用户,我想通过邀请码/二维码直接加入家庭,以便立即成为成员。
+
+- **角色**:游客(持有家庭邀请令牌)
+- **前置条件**:家长已在 `POST /api/family/invite/generate` 生成邀请码/二维码(含令牌与落地页)。
+- **主流程**
+  1. 扫码或点开落地页 → 进入注册/登录。
+  2. 走 `POST /api/auth/register-with-invite`(携带邀请令牌)。
+  3. 登录成功后自动归属到对应家庭,家庭成员列表出现该用户。
+- **异常/边界**:令牌失效/过期 → 提示「邀请已失效」;已登录用户用他人邀请 → 按业务规则处理(加入或被拒)。
+- **关联需求/设计**:`FamilyInviteController` `/api/family/invite/*`;二维码含令牌+落地页(cfclub 特性)。
+- **关联用例**:TC-G-04
+
+---
+
+## 场景 G-5:未登录访问业务页被拦截;浏览商城/文章可被放行
+
+**用户故事**:作为游客,我想随便看看商品和内容,但访问我的家庭/任务时必须先登录,以便数据安全。
+
+- **角色**:游客(无 token)
+- **前置条件**:已知某业务页路由(如 `/pages/family/index`、`/pages/tasks/index`)。
+- **主流程**
+  1. 直接请求带业务路由的页面(无 `Authorization`)。
+  2. `JwtInterceptor` 返回 401 → 前端跳转登录页;登录后回跳原页。
+  3. 打开商城主页 `POST /api/product/list`、文章列表 `POST /api/articles/list` → 可见内容(公开路径)。
+  4. 点击商品详情/文章详情需登录项 → 被拦截提示登录。
+- **异常/边界**:仅 8 个公开路径免鉴权;其余 `/api/**` 一律拦截;登录态过期后接口统一 401。
+- **关联需求/设计**:JWT 认证;`Authorization` Header;8 个公开路径白名单。
+- **关联用例**:TC-G-05

+ 201 - 0
tests/user-scenarios/02-parent.md

@@ -0,0 +1,201 @@
+# 用户使用场景 · 家长(Parent)
+
+> 来源:`AGENTS.md`(双角色、五维能量、测评订单、家庭邀请二维码、成员关系编辑、健康报告主链路、饮食推荐、LangGraph AI)、`API_REFERENCE.md`、`cfc-frontend/pages/*`、黑盒方案 P-01~P-18。
+> 关联用例:`test-cases/parent.md`(TC-P-01~TC-P-18 及跨角色 E2E)。
+
+---
+
+## 场景 P-1:创建家庭并生成邀请入口
+
+**用户故事**:作为家庭第一人,我想创建家庭并邀请其他成员,以便全家共用一套健康/成长管理。
+
+- **角色**:家长(创建者即家庭管理员)
+- **前置条件**:已登录(默认 parent)。
+- **主流程**
+  1. 进入家庭模块 → 创建家庭(名称「测试家庭1」)。
+  2. 系统生成唯一**邀请码 + 邀请二维码**(令牌 + 落地页)。
+  3. 角色升级为「家庭管理员」,进入家庭首页。
+- **异常/边界**:家庭名重复/为空 → 400 + 字段提示;重复创建家庭按业务规则限制。
+- **关联需求/设计**:`FamilyInviteController` `/api/family/invite/generate`;cfclub 家庭邀请二维码特性。
+- **关联用例**:TC-P-01
+
+---
+
+## 场景 P-2:邀请成员并维护家庭关系图
+
+**用户故事**:作为家长,我想邀请爷爷加入并用关系标签管理成员,以便家庭结构清晰。
+
+- **角色**:家长
+- **前置条件**:家庭已创建;爷爷 C 微信/手机号可用。
+- **主流程**
+  1. 分享邀请码/二维码给 C → C 通过 `register-with-invite` 加入。
+  2. 在成员管理添加成员资料(姓名/关系/生日/性别)。
+  3. 用 `RelationshipPicker` 选择关系类型;编辑时将 C 的关系改为「外公」。
+  4. 家庭关系图节点与关系标签同步更新。
+- **异常/边界**:关系类型不存在 → 选择器不显示该项;删除成员前若有代管数据需确认。
+- **关联需求/设计**:`FamilyMembersController` `/api/family/member/*`;关系类型 CRUD 在管理端(Web `RelationshipTypes.vue`)。
+- **关联用例**:TC-P-02, TC-P-03, TC-P-04
+
+---
+
+## 场景 P-3:双角色切换(家长 ↔ 孩子视角)
+
+**用户故事**:作为家长,我想临时以孩子视角查看 TA 的界面与数据,以便确认孩子端的体验。
+
+- **角色**:家长
+- **前置条件**:家庭含孩子 B(能登录或不能登录用户)。
+- **主流程**
+  1. 个人中心 → 切换视角 → 选择孩子 B。
+  2. 界面切换为孩子端布局,数据隔离为 B 的视角。
+  3. 切回家长端需二次校验(密码)。
+- **异常/边界**:**孩子端不能切回家长**(登录即孩子视角,无家长入口);切换时若 B 为 `local`(无登录),数据由家长代管可见。
+- **关联需求/设计**:`POST /api/family/member/switch`(替代已废弃 `/api/family/user/switch-mode`);双角色铁律。
+- **关联用例**:TC-P-15
+
+---
+
+## 场景 P-4:创建任务并下发给孩子、审批完成
+
+**用户故事**:作为家长,我想给孩子布置每日任务并在完成后给积分,以便培养习惯。
+
+- **角色**:家长
+- **前置条件**:家庭含孩子 B。
+- **主流程**
+  1. 创建任务(标题「睡前阅读」/ 成员 B / 积分 10 / 频率每日)。
+  2. 任务出现在 B 的任务列表,状态「待执行」。
+  3. B 完成后提交 → 家长端出现待审批。
+  4. 家长「通过」→ B 积分 +N 并生成流水;「驳回」→ 退回重做。
+- **异常/边界**:重复提交完成不重复发分;任务频率/截止日期边界。
+- **关联需求/设计**:`TaskController` `/api/tasks`;积分 `PointsController` `/api/points`。
+- **关联用例**:TC-P-05, TC-P-06
+
+---
+
+## 场景 P-5:心愿的创建—审批—兑换闭环
+
+**用户故事**:作为家长,我想让孩子提心愿、我审批并扣积分兑换,以便激励正向行为。
+
+- **角色**:家长(审批方)/ 孩子(创建方)
+- **前置条件**:孩子 B 已创建心愿「买乐高」。
+- **主流程**
+  1. B 创建心愿(名称 + 所需积分)→ 进入家长待审批列表。
+  2. 家长「通过」→ 扣除对应积分、进入兑换流程;「驳回」→ 心愿失效。
+  3. 兑换成功,积分流水正确。
+- **异常/边界**:积分不足时兑换被拦截;驳回后不可再兑换。
+- **关联需求/设计**:`WishController` `/api/wishes`、`RewardController` `/api/rewards`。
+- **关联用例**:TC-P-07
+
+---
+
+## 场景 P-6:查看五维能量与健康指数
+
+**用户故事**:作为家长,我想一眼看到全家五维能量分配,以便掌握健康结构。
+
+- **角色**:家长
+- **前置条件**:家庭已有任务/打卡等能量产生记录。
+- **主流程**
+  1. 进入「身/心/智/行/富」维度首页。
+  2. 展示家庭健康指数与五维能量分配,数值合理(总和=100%)。
+  3. 查看能量流水(来源/时间)。
+- **异常/边界**:能量比例配置错误导致不为 100% → 报警/修复;无数据时展示空态而非 500。
+- **关联需求/设计**:`EnergyController` `/api/energy`;五维能量按比例分配。
+- **关联用例**:TC-P-08
+
+---
+
+## 场景 P-7:申请测评(完整订单闭环)
+
+**用户故事**:作为家长,我想为孩子预约专业测评,以便获得个性化方案。
+
+- **角色**:家长
+- **前置条件**:已绑定规划师 T;孩子 B 在家庭中。
+- **主流程**
+  1. 申请测评 → 选择孩子 B + 测评类型 + 规划师 T。
+  2. 系统对 B 做**孩子快照**(时间点数据)。
+  3. 支付环节完成 → 生成测评订单。
+  4. 状态流转:已支付 → 待安排 → 已预约。
+- **异常/边界**:未选规划师/未支付 → 订单不进入待安排;支付失败回滚。
+- **⚠️ 口径修正(来自 `test-cases/deep-dive-assessment-appointment.md`)**:真实实现为 **订单 → 额度 → 预约** 三段式。`AssessmentOrder`(pending→paid) 支付成功后生成「测评额度 `AssessmentQuota`」;`POST /api/assessment/appointment/create` 会**先消耗一条额度**,额度不足/过期直接报错、不落预约。「孩子快照」与「录入结果触发方案」在 `AssessmentResult`/`DanAssessment` 链路,不在预约创建环节。故完整闭环应为:购买套餐 → 订单 paid → 获得额度 → 创建预约(消耗额度) → 规划师确认/完成 → 录入结果生成方案。
+- **关联需求/设计**:`AssessmentAppointmentController` `/api/assessment/appointment/*`、`AssessmentOrder`(pending/paid/cancelled/refunded)。
+- **关联用例**:TC-P-09、TC-DV-01~10(见深挖文档)
+
+---
+
+## 场景 P-8:上传健康报告 PDF 并自动解析(主链路起点)
+
+**用户故事**:作为家长,我想上传孩子的肠道菌群报告,以便系统自动解析出健康分与推荐。
+
+- **角色**:家长
+- **前置条件**:持有募极生物肠道菌群报告 PDF(样例 `530010234-侯.json` 对应报告)。
+- **主流程**
+  1. 上传 PDF(`POST /api/media/upload` 公开 + 报告解析入口)。
+  2. 系统识别为 `gut_flora` 类型 → 三阶段:上传 → 解析预览 → 确认入库。
+  3. 报告列表出现该报告,展示菌群健康分/平衡/多样性、菌种明细、疾病风险。
+  4. 七维健康评分刷新。
+- **异常/边界**:非募极生物报告 → 提示「请确认是募极生物肠道菌群报告」;解析失败进入未知聚类待运营自学习。
+- **关联需求/设计**:健康报告 PDF 上传与解析(cfclub);`/api/admin/report-parser/types` 已注册 `gut_flora`。
+- **关联用例**:TC-P-10, TC-P-11
+
+---
+
+## 场景 P-9:基于报告生成饮食推荐
+
+**用户故事**:作为家长,我想根据菌群报告得到可吃/慎吃清单,以便安排一日三餐。
+
+- **角色**:家长
+- **前置条件**:P-8 报告已入库。
+- **主流程**
+  1. 打开「身 → 饮食推荐」。
+  2. 按菌群报告生成食材推荐指数,展示可吃/慎吃食物列表。
+- **异常/边界**:无报告时无推荐;推荐随报告更新而刷新。
+- **关联需求/设计**:饮食推荐系统(前端 + 后端);基于报告数据。
+- **关联用例**:TC-P-12
+
+---
+
+## 场景 P-10:生成 AI 健康方案并送审/发布
+
+**用户故事**:作为家长,我想一键生成个性化健康方案,以便规划师审核后激活执行。
+
+- **角色**:家长
+- **前置条件**:孩子 B 已有报告;部分功能需购买会员解锁。
+- **主流程**
+  1. 选孩子 B + 目标「基于菌群检测报告的个性化健康管理方案」。
+  2. 调用 LangGraph(`AiGateway` 转发)→ 生成 overview + 营养/饮食/运动三板块。
+  3. 可逐板块重新生成/确认。
+  4. 保存/提交 → 进入「已提交(待规划师审核)」或按配置直接发布。
+- **异常/边界**:未购买会员点击生成 → 提示购买;AI 超时/Fallback → 友好提示而非 500。
+- **关联需求/设计**:AI 统一走 LangGraph(9000),Java 经 `AiGateway`(熔断+超时+Fallback);禁绕。
+- **关联用例**:TC-P-13, TC-P-14, TC-P-16
+
+---
+
+## 场景 P-11:AI 健康管家对话
+
+**用户故事**:作为家长,我想随时问健康管家孩子便秘吃什么,以便获得基于知识库的回答。
+
+- **角色**:家长
+- **前置条件**:已登录。
+- **主流程**
+  1. 进入 AI 对话(健康管家)→ `POST /api/ai/health-coach/send`。
+  2. 返回基于知识库的回答,可含产品/任务推荐。
+  3. 多轮上下文连续。
+- **异常/边界**:LangGraph 不可用时 `AiGateway` Fallback 兜底;敏感问题不泄露隐私。
+- **关联需求/设计**:`AIChatController` `/api/ai/*`;LangGraph RAG/对话。
+- **关联用例**:TC-P-18
+
+---
+
+## 场景 P-12:查看积分流水与成长档案
+
+**用户故事**:作为家长,我想核对积分明细和孩子成长记录,以便了解进展。
+
+- **角色**:家长
+- **前置条件**:已有任务/打卡/兑换记录。
+- **主流程**
+  1. 个人中心 → 积分明细(来源/变更/余额)。
+  2. 成长记录页展示孩子成长轨迹。
+  3. 时间格式统一 `yyyy-MM-dd HH:mm:ss`。
+- **异常/边界**:积分与流水总额一致;删除/回退操作有对应负流水。
+- **关联需求/设计**:`PointsController`、`GrowthController` `/api/growth`。
+- **关联用例**:TC-P-17

+ 129 - 0
tests/user-scenarios/03-child.md

@@ -0,0 +1,129 @@
+# 用户使用场景 · 孩子(Child)
+
+> 来源:`AGENTS.md`(能登录/不能登录用户统一口径、双角色铁律:孩子端不能切家长)、`API_REFERENCE.md`、`cfc-frontend/pages/*`、黑盒方案 C-01~C-09。
+> 关联用例:`test-cases/child.md`(TC-C-01~TC-C-09)。
+
+> **统一口径**:新版不再使用「孩子」概念做数据隔离,而是「能登录用户 / 不能登录用户」。
+> 能登录用户:`family_members.userId` 非空且关联 User 有 openid;不能登录用户:由同家庭能登录用户代管其数据。
+> 本文件「孩子」指被照护对象(通常为不能登录用户,由家长代管;也有能登录的子账号)。
+
+---
+
+## 场景 C-1:孩子端登录(无家长入口)
+
+**用户故事**:作为孩子,我想用自己的账号进入专属界面,并且看不到任何切换家长的入口。
+
+- **角色**:孩子(能登录用户)
+- **前置条件**:已为孩子创建可登录账号(或由家长代管)。
+- **主流程**
+  1. 孩子独立登录 → 直接进入孩子端首页。
+  2. 界面**不出现「切换家长」入口**(双角色铁律)。
+- **异常/边界**:即便 URL 直接拼家长路由也被 `role` 校验拦截;不能登录用户无法自行登录,由家长代管。
+- **关联需求/设计**:双角色铁律:直接登录的孩子端不能切换到家长端;`role` 由 `@RequestAttribute("role")` 判定。
+- **关联用例**:TC-C-01
+
+---
+
+## 场景 C-2:执行任务并提交完成
+
+**用户故事**:作为孩子,我想完成家长布置的任务并提交,以便获得积分。
+
+- **角色**:孩子
+- **前置条件**:家长已下发任务「睡前阅读」到孩子 B。
+- **主流程**
+  1. 打开待执行任务 → 点击「完成」提交。
+  2. 任务状态变为「待家长审核」;完成动作写入记录。
+- **异常/边界**:重复提交不重复计分;未到可执行时间/频率限制时提交被拦截。
+- **关联需求/设计**:`TaskController` `/api/tasks`(完成/审核)。
+- **关联用例**:TC-C-02
+
+---
+
+## 场景 C-3:玩小游戏并获得积分/能量
+
+**用户故事**:作为孩子,我想玩舒尔特方格等小游戏,以便边玩边涨能量。
+
+- **角色**:孩子
+- **前置条件**:小游戏入口可见。
+- **主流程**
+  1. 打开舒尔特方格并完成。
+  2. 得分按规则计算 → 积分/能量发放到账。
+  3. 成绩入排行榜。
+- **异常/边界**:中途退出不计分;作弊/异常分数被校验。
+- **关联需求/设计**:`cfc-frontend/pages/games/*`、`mini-games` e2e。
+- **关联用例**:TC-C-03
+
+---
+
+## 场景 C-4:创建并兑换心愿
+
+**用户故事**:作为孩子,我想提心愿、审批通过后兑换奖励。
+
+- **角色**:孩子(创建)/ 家长(审批)
+- **前置条件**:孩子已创建心愿「乐高机器人」。
+- **主流程**
+  1. 创建心愿(名称 + 积分)→ 进入家长待审批。
+  2. 家长通过后,孩子操作「兑换」。
+  3. 兑换成功,积分扣减正确。
+- **异常/边界**:积分不足兑换拦截;驳回后不可兑换。
+- **关联需求/设计**:`WishController` `/api/wishes`。
+- **关联用例**:TC-C-04, TC-C-05
+
+---
+
+## 场景 C-5:查看自己的五维能量
+
+**用户故事**:作为孩子,我想看到自己的能量值变化,以便有成就感。
+
+- **角色**:孩子
+- **前置条件**:已有任务/打卡能量记录。
+- **主流程**
+  1. 进入个人能量页 → 显示个人能量值。
+  2. 执行任务后能量有增量,流水可追溯。
+- **异常/边界**:能量不为负;跨维度比例合理。
+- **关联需求/设计**:`EnergyController` `/api/energy`。
+- **关联用例**:TC-C-06
+
+---
+
+## 场景 C-6:只读查看健康报告
+
+**用户故事**:作为孩子,我想查看家长上传的报告,但不应有权限编辑或删除。
+
+- **角色**:孩子
+- **前置条件**:家长已上传报告。
+- **主流程**
+  1. 打开报告列表 → 查看报告详情(菌群健康分/菌种/风险)。
+  2. 界面**无编辑/删除入口**。
+- **异常/边界**:直接调用删除接口应被 `role` 校验拒绝(403/401)。
+- **关联需求/设计**:健康报告查看权限按角色隔离。
+- **关联用例**:TC-C-07
+
+---
+
+## 场景 C-7:执行方案任务并打卡
+
+**用户故事**:作为孩子,我想完成方案生成的训练任务并打卡,以便推进方案进度。
+
+- **角色**:孩子
+- **前置条件**:规划师已激活方案,生成「舒尔特方格训练」等任务。
+- **主流程**
+  1. 打开方案任务 → 完成并提交。
+  2. 打卡成功 → 方案 `completedDays +1`。
+- **异常/边界**:未完成任务打卡被拦截;重复打卡不重复计数(幂等)。
+- **关联需求/设计**:健康打卡 `HealthCheckinController`/`DailyCheckinController`;方案进度字段。
+- **关联用例**:TC-C-08
+
+---
+
+## 场景 C-8:查看勋章墙
+
+**用户故事**:作为孩子,我想看已获得和未获得的勋章及进度。
+
+- **角色**:孩子
+- **前置条件**:已有部分成就记录。
+- **主流程**
+  1. 打开勋章墙 → 显示已获得/未获得勋章及进度。
+- **异常/边界**:未解锁勋章不显示领取按钮;达到条件自动点亮。
+- **关联需求/设计**:`RewardController` 勋章;管理端可创建勋章。
+- **关联用例**:TC-C-09

+ 128 - 0
tests/user-scenarios/04-teacher.md

@@ -0,0 +1,128 @@
+# 用户使用场景 · 成长规划师(Teacher, role=teacher)
+
+> 来源:`AGENTS.md`(成长规划师 `role=teacher`、可切回家长视角、测评订单、报告审核、方案激活拆任务、成长计划、套餐)、`API_REFERENCE.md`、`cfc-frontend/pages/teacher/*`、黑盒方案 TCH-01~TCH-12。
+> 关联用例:`test-cases/teacher.md`(TC-T-01~TC-T-12)。
+
+---
+
+## 场景 T-1:规划师登录并可切回家长视角
+
+**用户故事**:作为成长规划师,我想用账号登录工作台,并在需要时切回我自己的家长视角。
+
+- **角色**:规划师(role=teacher)
+- **前置条件**:已分配规划师账号(手机号 + 密码)。
+- **主流程**
+  1. 规划师端密码登录 → 进入仪表板首页。
+  2. 可切换回家长视角(自身家庭)。
+- **异常/边界**:规划师视角仅见其绑定家庭;不可越权访问无关家庭数据。
+- **关联需求/设计**:`AuthController`(登录/切换角色);规划师可切回家长视角(双角色)。
+- **关联用例**:TC-T-01
+
+---
+
+## 场景 T-2:绑定测试家庭
+
+**用户故事**:作为规划师,我想绑定客户家庭,以便代管其报告与方案。
+
+- **角色**:规划师
+- **前置条件**:家长已生成家庭邀请码。
+- **主流程**
+  1. 输入家庭邀请码 → 绑定。
+  2. 家庭出现在「我的家庭」列表,可见成员与数据。
+- **异常/边界**:无效/已失效邀请码 → 提示失败;重复绑定幂等。
+- **关联需求/设计**:`FamilyInviteController` 绑定;规划师绑定家庭特性。
+- **关联用例**:TC-T-02
+
+---
+
+## 场景 T-3:代上传客户报告并确认入库
+
+**用户故事**:作为规划师,我想帮不擅长操作的客户上传菌群报告,并确认解析入库。
+
+- **角色**:规划师
+- **前置条件**:已绑定家庭与孩子 B。
+- **主流程**
+  1. 上传募极生物菌群 PDF + 选择孩子 B。
+  2. 三阶段:上传 → 解析预览 → 确认入库。
+  3. 报告进入孩子档案,健康列表可见。
+- **异常/边界**:识别失败进入草稿/未知聚类;确认前可取消不入库。
+- **关联需求/设计**:健康报告上传与解析;规划师代传/审核。
+- **关联用例**:TC-T-03, TC-T-04
+
+---
+
+## 场景 T-4:方案审核列表与批准
+
+**用户故事**:作为规划师,我想审核家长生成的方案并批准,以便进入激活。
+
+- **角色**:规划师
+- **前置条件**:家长已提交方案(status=generated)。
+- **主流程**
+  1. 打开方案管理页 → 列表渲染(generated/reviewed/active 状态,无白屏)。
+  2. 对方案 A 点「批准」→ 状态 generated→reviewed。
+- **异常/边界**:列表接口参数错误(如原 400)已修复;空列表正常展示。
+- **关联需求/设计**:方案管理(规划师/运营共用);状态机 generated→reviewed→active。
+- **关联用例**:TC-T-05, TC-T-06
+
+---
+
+## 场景 T-5:激活方案并拆任务(含幂等)
+
+**用户故事**:作为规划师,我想激活方案自动拆出引导+模板任务,且重复激活不重复生成。
+
+- **角色**:规划师
+- **前置条件**:方案已 reviewed。
+- **主流程**
+  1. 点「激活」→ 弹确认「激活后将生成任务」。
+  2. 激活后状态 reviewed→active,生成引导任务 + 模板任务。孩子 B 出现方案启动任务。
+  3. 对已激活方案再次激活 → 返回状态异常提示,**不重复生成任务**(幂等)。
+- **异常/边界**:激活失败回滚不残留半任务;幂等靠状态机守护。
+- **关联需求/设计**:方案激活任务分解;幂等约束(黑盒回归项)。
+- **关联用例**:TC-T-07, TC-T-08
+
+---
+
+## 场景 T-6:家庭任务审核
+
+**用户故事**:作为规划师,我想审核孩子提交的任务,通过给分、驳回重做。
+
+- **角色**:规划师
+- **前置条件**:孩子已提交任务。
+- **主流程**
+  1. 打开家庭任务列表 → 审核提交。
+  2. 通过 → 孩子得积分;驳回 → 任务退回重做。
+- **异常/边界**:越权审核非绑定家庭任务被拒;重复审核幂等。
+- **关联需求/设计**:`TaskController` 审核;积分发放。
+- **关联用例**:TC-T-09
+
+---
+
+## 场景 T-7:录入测评结果并触发方案生成
+
+**用户故事**:作为规划师,我想录入孩子各维度测评得分,以便规则引擎自动生成方案。
+
+- **角色**:规划师
+- **前置条件**:家长已支付测评订单(待安排→已预约)。
+- **主流程**
+  1. 打开测评订单 → 录入孩子各维度得分。
+  2. 保存 → 结果可见;触发规则引擎自动生成方案(status=generated)。
+  3. (DAN 链路)录入测评结果 → 确认上传 → 自动生成 generated 方案。
+- **异常/边界**:必填维度缺失 → 校验拦截;重复录入覆盖而非新增。
+- **关联需求/设计**:`AssessmentAppointmentController`(confirm/录入);`DanAssessmentController` DAN 全链路;规则引擎。
+- **关联用例**:TC-T-10, E2E-04
+
+---
+
+## 场景 T-8:查看/创建成长计划与套餐
+
+**用户故事**:作为规划师,我想管理客户成长计划,并上架专注力提升套餐供市场购买。
+
+- **角色**:规划师
+- **前置条件**:已绑定家庭。
+- **主流程**
+  1. 打开「成长计划」页 → 列表显示自己创建的计划(childName/状态/时间)。
+  2. 创建「专注力提升套餐」含任务项 → 提交审核。
+  3. 审核通过后套餐上架,可被市场购买。
+- **异常/边界**:套餐任务项为空 → 校验拦截;未审核不可购买。
+- **关联需求/设计**:`GrowthPlanController` `/api/growth/plan`、`GuidePackageController` `/api/guide/packages`。
+- **关联用例**:TC-T-11, TC-T-12

+ 113 - 0
tests/user-scenarios/05-admin.md

@@ -0,0 +1,113 @@
+# 用户使用场景 · 平台运营(Admin / Web 管理端)
+
+> 来源:`AGENTS.md`(维度配置与知识库管理、关系类型 CRUD、文章发布-审核、报告解析中台、数据迁移、sfms 只读源)、`API_REFERENCE.md`(`/api/admin/*` 大量控制器)、`cfc-web/`、`cfc-frontend/pages/admin`、黑盒方案 A-01~A-16。
+> 关联用例:`test-cases/admin.md`(TC-A-01~TC-A-16)。
+
+---
+
+## 场景 A-1:管理端登录与看板
+
+**用户故事**:作为运营,我想登录管理端看全局数据,以便做决策。
+
+- **角色**:平台运营
+- **前置条件**:已分配 admin 账号(手机号 + 密码)。
+- **主流程**
+  1. 管理端密码登录 → 进入 Dashboard。
+  2. 看板统计加载成功(任务总量/完成率等)。
+- **异常/边界**:错误密码不签发 token;看板接口超时友好提示。
+- **关联需求/设计**:`AdminController`/`AdminAuthController`;`StatsController` `/api/stats`。
+- **关联用例**:TC-A-01, TC-A-02
+
+---
+
+## 场景 A-2:报告解析中台(类型注册 / 未知聚类)
+
+**用户故事**:作为运营,我想管理报告解析类型并对未知报告做自学习,以便扩大解析覆盖。
+
+- **角色**:平台运营
+- **前置条件**:`gut_flora` 已注册。
+- **主流程**
+  1. 打开报告解析中台 → 类型列表返回 ≥1 条(含 gut_flora)。
+  2. 注册新报告类型(typeId/显示名/解析路径/threshold)→ 保存成功,列表可见。
+  3. 重复注册同 typeId → 被拒绝。
+  4. 打开未知报告聚类 → 查看聚类下上传,可自学习生成类型。
+- **异常/边界**:解析路径非法 → 校验拦截;未知聚类无数据时正常空态。
+- **关联需求/设计**:`AdminReportParserController` `/api/admin/report-parser/*`;健康报告解析特性。
+- **关联用例**:TC-A-05, TC-A-06, TC-A-07
+
+---
+
+## 场景 A-3:文章发布-审核闭环与标题去重
+
+**用户故事**:作为运营,我想发文章经过审核上线,且标题不重复。
+
+- **角色**:平台运营
+- **前置条件**:待发布文章素材就绪。
+- **主流程**
+  1. 创建文章 → 提交审核 → 通过。
+  2. 创建 1s 内返回成功(无超时);审核通过后 C 端可见。
+  3. 同标题重复创建 → 第二次被拦截(标题已存在)。
+- **异常/边界**:长文(8000 字)创建+更新稳定;审核驳回退回草稿。
+- **关联需求/设计**:文章发布-审核系统;`AdminArticleController`;`/api/articles/*`。
+- **关联用例**:TC-A-08, TC-A-09
+
+---
+
+## 场景 A-4:关系类型 / 勋章 / 供应商 CRUD
+
+**用户故事**:作为运营,我想维护关系类型、勋章和供应商,以便前端与业务可用。
+
+- **角色**:平台运营
+- **前置条件**:对应管理页可访问。
+- **主流程**
+  1. 关系类型新增/编辑/停用 → 家长端关系选择器同步生效。
+  2. 创建勋章(名称/图标/触发条件/门槛)→ 200 成功,badgeId 自动生成,列表可见。
+  3. 新增供应商(昵称/手机号/真实姓名)→ 200 成功,列表 name=昵称;同手机号重复保存被拒或可控覆盖。
+- **异常/边界**:字段缺失/类型错误 → 400 + 字段提示(非 500);停用关系类型不影响历史数据。
+- **关联需求/设计**:关系类型 CRUD(Web `RelationshipTypes.vue`);勋章/供应商管理接口。
+- **关联用例**:TC-A-10, TC-A-11, TC-A-12
+
+---
+
+## 场景 A-5:活动提交审核 / 撤回
+
+**用户故事**:作为运营,我想管理活动全生命周期,可随时撤回重编辑。
+
+- **角色**:平台运营
+- **前置条件**:草稿活动存在。
+- **主流程**
+  1. 草稿活动提交审核 → 通过 → 撤回 → 退回草稿。
+  2. 已发布活动可撤回、退回草稿重新编辑。
+- **异常/边界**:全流程无 500;状态机合法流转。
+- **关联需求/设计**:`AdminActivityController` 等;活动报名特性。
+- **关联用例**:TC-A-13
+
+---
+
+## 场景 A-6:知识库管理与数据迁移
+
+**用户故事**:作为运营,我想维护知识库并做 sfms→cfc 数据迁移。
+
+- **角色**:平台运营
+- **前置条件**:知识条目/迁移源就绪。
+- **主流程**
+  1. 删除知识条目 → 200 成功,列表移除,无 500。
+  2. 执行 sfms→cfc 迁移 → 接口返回成功,关键业务表数据量更新。
+- **异常/边界**:迁移失败回滚并给出明确错误;多数据源 `SfmsDataSourceConfig` 只读。
+- **关联需求/设计**:知识库管理;多数据源;`DatabaseInitializer` 迁移。
+- **关联用例**:TC-A-14, TC-A-15
+
+---
+
+## 场景 A-7:全局参数校验(不再裸 500)
+
+**用户故事**:作为质量保障,我想确认所有管理接口对非法入参返回 400 而非 500。
+
+- **角色**:平台运营(测试视角)
+- **前置条件**:各管理页接口可用。
+- **主流程**
+  1. 各管理接口传空 body / 错类型字段。
+  2. 返回 400 + 具体字段提示(不再裸 500「服务器内部错误」)。
+- **异常/边界**:覆盖新增接口;回归防止回退。
+- **关联需求/设计**:统一 `Result<T>`;全局异常处理。
+- **关联用例**:TC-A-16

+ 51 - 0
tests/user-scenarios/06-vendor.md

@@ -0,0 +1,51 @@
+# 用户使用场景 · 商品服务商(Vendor)
+
+> 来源:`AGENTS.md`(商城 `dan/danshop` 独立 Spring Boot,端口 8888)、`API_REFERENCE.md`(`/api/product/*`、`/api/product/order`、`/api/admin/ecom-supplier/*`、`/api/service-role`)、黑盒方案 S-01~S-03。
+> 关联用例:`test-cases/vendor.md`(TC-S-01~TC-S-03)。
+
+> 说明:商城为独立服务(`dan/danshop`,端口 8888),商品/订单与 C 端 `cfc-backend` 通过商品/订单接口协同;服务商入驻走统一服务角色申请或管理端供应商管理。
+
+---
+
+## 场景 S-1:服务商入驻申请与审核
+
+**用户故事**:作为供应商,我想提交资质入驻,通过运营审核后卖货。
+
+- **角色**:商品服务商
+- **前置条件**:资质材料/联系方式/服务品类就绪。
+- **主流程**
+  1. 提交入驻申请(资质/联系/品类)→ 进入运营审核队列。
+  2. 运营审核通过 → 获得供应商身份。
+- **异常/边界**:资质缺失 → 驳回并说明;重复申请幂等。
+- **关联需求/设计**:`ServiceRoleApplicationController` `/api/service-role`(统一服务角色申请 + 管理端审批);或 `AdminEcomSupplierController` `/api/admin/ecom-supplier/*`。
+- **关联用例**:TC-S-01
+
+---
+
+## 场景 S-2:商品管理
+
+**用户故事**:作为供应商,我想上架商品并管控库存,让其在商城可见。
+
+- **角色**:商品服务商
+- **前置条件**:已审核通过。
+- **主流程**
+  1. 新增商品(名称/价格/库存/分类)→ 商品在商城可见。
+  2. 库存/价格变更即时生效。
+- **异常/边界**:入库存单字段校验错误 → 400 提示;价格为负/库存为负拦截;下架商品不可购买。
+- **关联需求/设计**:`ProductController` `/api/product`、`AdminProductController` `/api/admin/product`。
+- **关联用例**:TC-S-02
+
+---
+
+## 场景 S-3:订单处理(发货 / 核销)
+
+**用户故事**:作为供应商,我想处理客户订单并发货/核销,让客户看到物流或核销码。
+
+- **角色**:商品服务商
+- **前置条件**:已有客户下单。
+- **主流程**
+  1. 查看新订单 → 发货 / 核销。
+  2. 订单状态正确流转,客户可见物流 / 核销码。
+- **异常/边界**:重复发货幂等;核销码校验防冒用;退款/售后按业务规则。
+- **关联需求/设计**:`ProductOrderController` `/api/product/order`;商城订单流。
+- **关联用例**:TC-S-03

+ 27 - 0
tests/user-scenarios/README.md

@@ -0,0 +1,27 @@
+# 用户使用场景(User Scenarios)
+
+> 本目录从**真实用户视角**描述产品「怎么被使用」,是 `test-cases/` 的上游输入。
+> 每个场景遵循格式:**用户故事(作为 X,我想 Y,以便 Z)→ 前置条件 → 主流程 → 异常/边界 → 关联需求/设计 → 关联用例**。
+
+## 角色与场景索引
+
+| 文件 | 角色 | 核心场景 |
+|------|------|----------|
+| `01-guest.md` | 游客 | 首次进入、微信/手机登录、邀请注册加入家庭、越权拦截、浏览商城文章 |
+| `02-parent.md` | 家长 | 创建/邀请家庭、成员与关系编辑、双角色切换、任务/心愿、五维能量、测评订单、健康报告主链路、AI 方案与对话、购买会员 |
+| `03-child.md` | 孩子 | 孩子端登录(无家长入口)、执行任务/小游戏、心愿、查看能量与报告(只读)、方案打卡、勋章墙 |
+| `04-teacher.md` | 成长规划师 | 密码登录、绑定家庭、代传报告、审核方案、激活拆任务(幂等)、录入测评、成长计划、创建套餐 |
+| `05-admin.md` | 平台运营 | 管理端登录、全局统计、报告解析中台、文章发布审核、关系类型/勋章/供应商/活动/知识库、数据迁移、参数校验 |
+| `06-vendor.md` | 商品服务商 | 入驻申请、商品管理、订单处理(发货/核销) |
+
+## 编写依据
+
+- 需求/设计:`AGENTS.md`(双角色、五维能量、测评订单、四级地址、多数据源、LangGraph 统一 AI、报告解析、文章审核、饮食推荐、家庭邀请二维码、关系类型 CRUD)。
+- 接口:`docs/superpowers/api/API_REFERENCE.md`(统一 POST、`Result<T>`、JWT、`@RequestAttribute("role")` 校验、已废弃接口清单)。
+- 实现:后端各 `*Controller.java`、小程序 `cfc-frontend/pages/*`、LangGraph 服务(端口 9000)。
+
+## 阅读与维护约定
+
+- 场景是「人话」,用例是「机器/QA 可执行步骤」;一个场景可派生多条用例(正常流 + 异常流 + 权限流)。
+- 涉及**双角色切换**的场景必须显式写出边界:家长↔孩子视角可切;**孩子端不能切回家长**;规划师可切回家长。
+- 新增场景请同步在 `test-cases/` 对应角色文件补充用例,并在文末「关联用例」回填 TC 编号。