|
|
@@ -0,0 +1,118 @@
|
|
|
+# AI成长教练 + 真人管家批次 · 契约核对结论(17 SC · 防假 RED)
|
|
|
+
|
|
|
+> 归属:契约补建计划 P0「AI成长教练(AI管家)+ 真人管家域」· 核对时间 2026-11-07(EVD-14)
|
|
|
+> 开工包:`docs/tdd/orchestration/ai-butler-kickoff-20261107.md`(origin/cfclub @ b36e26240)
|
|
|
+> 核对对象:origin/cfclub `cfc-backend` controller 源码(工作树 HEAD = origin/cfclub;直接在主分支工作,未新建分支)
|
|
|
+> 核对方法:类级 `@RequestMapping` + 方法级 `@PostMapping` 逐一比对(`grep -rn '@RequestMapping|@PostMapping' cfc-backend/src/main/java/com/etotem/cfc/controller/` 实测定位,不假定包路径),逐端点记录存在性;对字面路径缺失或语义偏移者定位等价实现 / 替代载体(防假 RED:契约声明的接口范围必须能在真实源码中找到实现)
|
|
|
+
|
|
|
+## 0. 结论摘要
|
|
|
+
|
|
|
+- **17 个 SC 中 9 个端点载体齐全(SC-B-01/02/04/11、SC-H-01/02/03/06/07)**,8 个存在端点但语义/载体与场景口径存在偏差,已完成实测回填(SC-B-05/06/07/09/10/12、SC-H-04/05)。
|
|
|
+- **无完整缺失的 SC**(本批无「无端点载体需产品侧确认」项);但 **6 个 SC 存在语义缺口**,需产品/测试侧按契约标注口径执行:SC-B-05(敏感词门控无独立端点)、SC-B-06(fallback 无内容级 mock)、SC-B-09(转接语义另有载体)、SC-B-12(主动跟进无定时推送)、SC-H-04(应急处理语义间接)、SC-H-05(资源/活动对接语义间接)。
|
|
|
+- 端点核对范围内 **无「假 RED」**:凡开工包标注 ⚠ 待核实的 8 项(B-05/B-06/B-07/B-09/B-10/B-12、H-04/H-05),均逐条实测回填结论;B-07/H-04/H-05 的候选端点存在但部分已废弃(410)或语义偏移,均标注替代载体。
|
|
|
+- **已废弃端点确认**:`POST /api/butler/service-records`、`POST /api/butler/commissions` 均 `@Deprecated` 返回 410(`ButlerController`,无替代方案提示),契约中以 admin 侧 `/api/admin/butler/service-records`、`/settlements` 为替代载体。
|
|
|
+- 无新增 DB 迁移、未改动业务代码与测试文件(本批次仅新增本核对文档 + API_REFERENCE 增补段落,章节号 4.64 起)。
|
|
|
+
|
|
|
+## 1. 端点核对总表(17 SC)
|
|
|
+
|
|
|
+| SC | 场景 | 候选端点载体 | 核验 | 结论 |
|
|
|
+|----|------|--------------|:----:|------|
|
|
|
+| SC-B-01 | 问题解答 · 成长咨询对话 | `/api/ai/chat/send`(AIChatController);`/api/butler/apply`(ButlerController) | ✅ | 端点齐全;apply 为真人管家申请(并场景),chat/send 为咨询主载体 |
|
|
|
+| SC-B-02 | 任务跟踪 · 主动成长提醒 | `/api/ai/health-coach/send`(AIChatController);`/api/ai/gate`(会员门禁) | ✅ | 端点齐全;health-coach/send 支持 focus 定向跟进 |
|
|
|
+| SC-B-04 | 问题解答 · 成长报告智能解读 | `/api/ai/report/analyze`(AIChatController) | ✅ | 端点存在;含 AI 服务不可用显式错误分支 |
|
|
|
+| SC-B-05 | 安全与韧性 · 敏感问题拦截与隐私保护 | `/api/ai/gate`、`/api/ai/health-coach/gate`(门禁) | ⚠ | gate 为**会员门禁非敏感词门控**;隐私保护实为 `PiisService` PII 脱敏(name→化名、phone/idCard/email/address→[已脱敏]);`WechatService.msg_sec_check` 存在但用于文章/媒体发布,非教练对话链路;**无独立敏感词拦截端点** |
|
|
|
+| SC-B-06 | 安全与韧性 · LangGraph 不可用 Fallback | `/api/ai/chat/send`(fallback 分支) | ⚠ | fallback 半属实:`AiGateway` 熔断(failure-threshold=3,reset-timeout-ms=30000)+ 不可用时返回 null → `AIService.sendMessage` 返回空 Map → chat/send 空 answer/空 tasks;`report/analyze` 有「AI服务暂不可用」显式错误;**无内容级 mock 兜底** |
|
|
|
+| SC-B-07 | 任务跟踪 · 个性化任务/饮食推荐与采纳 | `/api/ai/nutrition/send`(AIChatController);`/api/butler/commissions`(ButlerController) | ⚠ | nutrition/send 存在且解析 `[RECOMMEND]` + `[TASK]` 标记;⚠ 候选 `/api/butler/commissions` 已废弃 410,非推荐采纳载体 |
|
|
|
+| SC-B-09 | 任务跟踪 · 教练转接成长规划师 | `/api/butler/apply`→转接;`/api/butler/select`(FamilyButlerSelectController) | ⚠ | 转接语义不符:apply=管家申请非转接、select=家庭自助选管家(L2 受限);**规划师绑定转接实际载体 = `/api/guide/bind/invite|validate|confirm`(BindInviteController)+ `/api/bind/accept|unbind`(BindController)**,契约标注替代载体 |
|
|
|
+| SC-B-10 | 任务跟踪 · 家庭成长看板(教练聚合视图) | `/api/butler/members`、`/api/butler/service-records`;`/api/admin/butler/list` | ⚠ | members 存在;⚠ `/api/butler/service-records` 已废弃 410;**聚合台账以 admin 侧 `/api/admin/butler/service-records` + `/api/admin/butler/list|user-list` 为准** |
|
|
|
+| SC-B-11 | 问题解答 · 报告细节追问 | `/api/ai/chat/send`(追问上下文);`/api/ai/chat/conversations`、`/api/ai/chat/messages` | ✅ | 端点齐全;conversations/messages/delete 会话历史闭环存在 |
|
|
|
+| SC-B-12 | 任务跟踪 · 同步规划师建议主动跟进 | `/api/ai/health-coach/send`(跟进推送) | ⚠ | health-coach/send 存在(focus 定向);「主动跟进」语义弱:**无规划师建议主动推送定时端点**(`task/` 下耗时任务仅 BASIC 到期/佣金结算等提醒,非规划师建议跟进) |
|
|
|
+| SC-H-01 | 人工介入与升级 · 接收 AI 升级并人工介入 | `/api/admin/butler/review`(升级介入);`/api/admin/butler/assignments` | ✅ | 端点齐全(admin 角色,非 admin → 权限不足) |
|
|
|
+| SC-H-02 | 一对一服务与协调 · 一对一家长陪跑 | `/api/admin/butler/assign-member`、`/api/admin/butler/list`;`/api/butler/profile` | ✅ | 端点齐全;assign-member 绑定 + list 全量 + profile 详情 |
|
|
|
+| SC-H-03 | 一对一服务与协调 · 多方沟通协调 | `/api/admin/butler/service-records`(多方记录);`/api/admin/butler/assignments` | ✅ | 端点齐全;assignments(管家-家庭分配关系)+ service-records 台账 |
|
|
|
+| SC-H-04 | 人工介入与升级 · 升级与应急处理 | `/api/admin/butler/unassign`、`/api/admin/butler/toggle-accepting`(接管开关) | ⚠ | 端点存在但语义间接:unassign=解绑管家(非应急接管)、toggle-accepting=是否接单开关;「升级与应急」语义 vs 停接/解绑有偏移,需产品确认验收口径 |
|
|
|
+| SC-H-05 | 资源对接与协同闭环 · 线下资源与活动对接 | `/api/admin/butler/list`(资源清单);`/api/ai/gate` | ⚠ | admin list 资源清单纯存在;⚠ `/api/ai/gate` 非资源/活动对接(会员门禁);**活动对接实际载体 = `GuideActivityController` `/api/guide/activities/*`**(规划师端活动 CRUD),需产品确认验收语义 |
|
|
|
+| SC-H-06 | 资源对接与协同闭环 · 与 AI 管家协同闭环 | `/api/ai/butler/send`(AI→管家协同);`/api/ai/chat/send` | ✅ | 端点齐全;butler/send 注入 child_id/report_id/focus + 画像,返回 answer/tasks |
|
|
|
+| SC-H-07 | 服务质量 · 服务质检与满意度 | `/api/admin/butler/settlements`、`/api/admin/butler/service-records`(质检台账) | ✅ | 端点齐全;settlements(佣金结算,月结)+ service-records(服务记录台账,`ButlerCommissionService.createServiceRecord` 落库) |
|
|
|
+
|
|
|
+## 2. 逐 SC 核验明细
|
|
|
+
|
|
|
+### 2.1 端点载体齐全(9 SC)
|
|
|
+
|
|
|
+| SC | 载体端点(实测路径) | 实测依据 |
|
|
|
+|----|----------------------|----------|
|
|
|
+| SC-B-01 | `POST /api/ai/chat/send`;`POST /api/butler/apply` | AIChatController.java:140(成长咨询对话,user-input 校验、会员门禁、画像注入);butler/ButlerController.java:37(申请成为管家) |
|
|
|
+| SC-B-02 | `POST /api/ai/health-coach/send`;`POST /api/ai/gate` | AIChatController.java:625(health-coach 跟进:会员门禁 + focus/画像注入 + [RECOMMEND]/[TASK] 解析);:681(AI 教练会员门禁状态) |
|
|
|
+| SC-B-04 | `POST /api/ai/report/analyze` | AIChatController.java:288(报告智能解读;LangGraph 不可用时返回「AI服务暂不可用」显式错误) |
|
|
|
+| SC-B-11 | `POST /api/ai/chat/send`;`POST /api/ai/chat/conversations`;`POST /api/ai/chat/messages`;`POST /api/ai/chat/conversations/{id}/delete` | AIChatController.java:140/347/369/407(追问上下文 = 同 conversationId 续聊;会话历史列表/消息/删除闭环) |
|
|
|
+| SC-H-01 | `POST /api/admin/butler/review`;`POST /api/admin/butler/assignments` | AdminButlerController.java:119(申请审核:通过/驳回);:221(管家-家庭分配关系列表);类内 admin/finance 角色检查(非 admin → 权限不足) |
|
|
|
+| SC-H-02 | `POST /api/admin/butler/assign-member`;`POST /api/admin/butler/list`;`POST /api/butler/profile` | AdminButlerController.java:144(指派管家到家庭);:85(管家列表);butler/ButlerController.java:55(管家个人资料) |
|
|
|
+| SC-H-03 | `POST /api/admin/butler/service-records`;`POST /api/admin/butler/assignments` | AdminButlerController.java:161(服务记录台账,分页);:221(分配关系);`ButlerCommissionService.createServiceRecord`(butlerId/memberUserId/amount/remark 落库) |
|
|
|
+| SC-H-06 | `POST /api/ai/butler/send`;`POST /api/ai/chat/send` | AIChatController.java:723(AI→管家协同:child_id/report_id/focus + 画像注入 → answer/tasks);:140(通用咨询) |
|
|
|
+| SC-H-07 | `POST /api/admin/butler/settlements`;`POST /api/admin/butler/service-records` | AdminButlerController.java:191(佣金结算列表,`ButlerCommissionService.calculateButlerSettlement` 按年月计算);:161(质检台账) |
|
|
|
+
|
|
|
+### 2.2 端点存在但语义/载体偏差(8 SC)
|
|
|
+
|
|
|
+**SC-B-05 敏感问题拦截与隐私保护(⚠)**
|
|
|
+- 存在:`POST /api/ai/gate`、`POST /api/ai/health-coach/gate`(AIChatController.java:681/703)——均为**会员付费门禁**(`membershipService.checkAiFeatureGate` → `UPGRADE_REQUIRED` 拦截),非敏感词/内容门控。
|
|
|
+- 存在:隐私保护 = `PiisService` PII 脱敏(PiisService.java:97 `sanitizeText` / :108 `sanitizeContext`;手机号/身份证/邮箱/详细地址 → `[已脱敏]`,姓名 → 固定化名),接入 AI 输入侧。
|
|
|
+- 存在但链路不符:`WechatService.msg_sec_check`(WechatService.java:394 文本内容安全检测)——用于文章/媒体发布链路,非教练对话拦截。
|
|
|
+- **缺口**:无独立教练对话敏感词/内容拦截端点。契约口径:以「PII 脱敏 + 会员门禁」作为该 SC 的安全与隐私实现载体,敏感内容拦截需产品确认验收方式。
|
|
|
+
|
|
|
+**SC-B-06 LangGraph 不可用 Fallback(⚠)**
|
|
|
+- 存在:`AiGateway` 熔断器(AiGateway.java:72 `circuitOpen`、failure-threshold=3、reset-timeout-ms=30000;:180 `chat()` 熔断打开直接 `return null`,异常 catch 后 `return null`)。
|
|
|
+- 存在:`AIService.sendMessage`(AIService.java:116-120)——`aiGateway.chat` 返回 null 时 `log.warn` + 返回 `Collections.emptyMap()` → chat/send 返回空 answer/空 tasks。
|
|
|
+- 存在:report/analyze 的显式降级(「AI服务暂不可用」错误,不 mock)。
|
|
|
+- **缺口**:无内容级 mock 兜底(对话类返回空而非预设话术);健康管家/营养/教练走同一 AiGateway 通道,熔断一致。契约口径:fallback = 空降级 + 显式错误,测试侧按此验收。
|
|
|
+
|
|
|
+**SC-B-07 个性化任务/饮食推荐与采纳(⚠)**
|
|
|
+- 存在:`POST /api/ai/nutrition/send`(AIChatController.java:421)——营养分析(reportId 必填 → 菌群分析 → 画像注入 → LangGraph),解析 `[RECOMMEND]` 标记(RECOMMEND_PATTERN + `parseSimpleJson`)+ `[TASK]` 标记生成 task 列表。
|
|
|
+- ⚠ 开工包候选 `POST /api/butler/commissions`(butler/ButlerController.java:115)已废弃 410,与推荐采纳无关。
|
|
|
+- 契约口径:推荐载体 = nutrition/send(含 TASK 采纳入口)。
|
|
|
+
|
|
|
+**SC-B-09 教练转接成长规划师(⚠)**
|
|
|
+- 开工包候选不符:`POST /api/butler/apply` = 申请成为真人管家(非转接);`POST /api/butler/select`(FamilyButlerSelectController.java:35)= 家庭自助选管家(L2 受限,`ButlerService.selectButler`)。
|
|
|
+- 实际转接载体(规划师绑定流):`POST /api/guide/bind/invite`(BindInviteController.java:36 生成绑定邀请)→ `POST /api/guide/bind/validate`(:46)→ `POST /api/guide/bind/confirm`(:58 家庭主账号确认)→ 解绑 `POST /api/bind/unbind`(BindController.java:95)/ 接受 `POST /api/bind/accept`(:43)。
|
|
|
+- 契约口径:SC-B-09 验收走规划师绑定流(guide/bind + /api/bind),非 butler 申请流。
|
|
|
+
|
|
|
+**SC-B-10 家庭成长看板(教练聚合视图)(⚠)**
|
|
|
+- 存在:`POST /api/butler/members`(butler/ButlerController.java:74,管家-家庭绑定成员列表)。
|
|
|
+- ⚠ 候选 `/api/butler/service-records`(:103)废弃 410。
|
|
|
+- 替代载体:`POST /api/admin/butler/service-records`(AdminButlerController.java:161,分页台账)+ `POST /api/admin/butler/list|user-list`(:85/:48,管家列表/用户维度列表)。
|
|
|
+- 契约口径:聚合台账以 admin 侧为准;家庭端看板需产品确认是否复用 members 单体。
|
|
|
+
|
|
|
+**SC-B-12 同步规划师建议主动跟进(⚠)**
|
|
|
+- 存在:`POST /api/ai/health-coach/send`(AIChatController.java:625,focus/画像定向跟随)。
|
|
|
+- **缺口**:无规划师建议→主动推送的定时端点;`task/` 包 `@Scheduled` 均为业务提醒(BASIC 到期、佣金结算等),非规划师建议跟进。契约口径:主动跟进 = 用户发起式(health-coach/send)非服务端定时推送,验收按用户主动触发。
|
|
|
+
|
|
|
+**SC-H-04 升级与应急处理(⚠)**
|
|
|
+- 存在:`POST /api/admin/butler/unassign`(AdminButlerController.java:232,`ButlerService.unassign` 解绑管家-家庭);`POST /api/admin/butler/toggle-accepting`(:244,`ButlerService.toggleAccepting` 接单开关)。
|
|
|
+- **语义偏移**:unassign/toggle-accepting 是「解绑/停接」运维开关,非「升级与应急接管」(如紧急人工接管家庭数据/会话)。契约口径:以停接/解绑作为应急降级手段,升级接管语义需产品确认。
|
|
|
+
|
|
|
+**SC-H-05 线下资源与活动对接(⚠)**
|
|
|
+- 存在:`POST /api/admin/butler/list`(管家资源析清单)。
|
|
|
+- ⚠ `/api/ai/gate` 非资源/活动对接(会员门禁)。
|
|
|
+- 实际活动载体:`POST /api/guide/activities/list` 等(GuideActivityController.java:24,规划师端活动创建/编辑/发布)。
|
|
|
+
|
|
|
+### 2.3 已废弃端点(410,属本域但不计载体)
|
|
|
+
|
|
|
+| 端点 | 位置 | 状态 | 替代 |
|
|
|
+|------|------|:----:|------|
|
|
|
+| `POST /api/butler/service-records` | butler/ButlerController.java:103 | @Deprecated 410 | `/api/admin/butler/service-records` |
|
|
|
+| `POST /api/butler/commissions` | butler/ButlerController.java:115 | @Deprecated 410 | `/api/admin/butler/settlements` |
|
|
|
+
|
|
|
+## 3. 角色与权限口径
|
|
|
+
|
|
|
+- 家庭端(AI 成长教练):`/api/ai/*` 走 `JwtInterceptor` 登录态 + 控制器内 `checkGate(userId)` 会员门禁(`/api/ai/gate`、`/api/ai/health-coach/gate`、chat/send、nutrition/send、health-coach/send、butler/send 均先门禁后处理)。
|
|
|
+- 真人管家申请/家庭自助选择:`/api/butler/*`、`/api/butler/available-list|my-butler|select` 登录态即可(select 含 L2 绑定受限校验,浏览开放)。
|
|
|
+- 运营/管理侧(真人管家域):`/api/admin/butler/*` 类内 admin/finance 角色检查(`@RequestAttribute("role")`,非 admin → `Result.error` 权限不足)。
|
|
|
+- 规划师转接:`/api/guide/bind/*`(规划师发起)+ `/api/bind/*`(家庭确认,`PlannerCertificationGuard` 认证 + ShopMemberShip 校验)。
|
|
|
+
|
|
|
+## 4. 交付口径与后续动作(供测试侧/产品侧)
|
|
|
+
|
|
|
+1. **可跑通**:SC-B-01/02/04/11、SC-H-01/02/03/06/07 —— 端点载体齐全,转测试侧补契约 JUnit + 三类流(正常/异常/权限)证据。
|
|
|
+2. **需按契约口径验收**:SC-B-05(PII 脱敏 + 会员门禁为隐私承载;敏感词拦截无独立端点)、SC-B-06(fallback = 空降级 + 显式错误,无 mock)、SC-B-07(推荐 = nutrition/send)、SC-B-09(转接 = guide/bind 绑定流)、SC-B-10(聚合台账 = admin 侧)、SC-B-12(主动跟进 = 用户发起式)。
|
|
|
+3. **需产品确认验收语义**:SC-H-04(升级/应急 vs unassign/toggle-accepting 语义偏移)、SC-H-05(资源/活动对接验收口径)。
|
|
|
+4. 本批**未建伪实现任务**:确无端点载体的语义项(B-05 敏感词门控、B-12 定时推送)按 O-7 契约补建裁决登记语义缺口,不新建实现。
|
|
|
+
|
|
|
+*核对依据:origin/cfclub @ b36e26240(开工包 ai-butler-kickoff-20261107.md)+ 各 Controller 源码 @ 同 sha;核对人:TDD 契约核对会话 EVD-14(OpenCode)。本批仅新增契约文档(spec + API_REFERENCE 增补)、直接提交 origin/cfclub,未修改业务代码、测试文件、DB 迁移。*
|