diff --git a/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝工作台资源对接接口测试.md b/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝工作台资源对接接口测试.md new file mode 100644 index 00000000..90f8173e --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝工作台资源对接接口测试.md @@ -0,0 +1,13 @@ +# 存客宝工作台「join·资源对接」接口测试误报失败 + +## 现象 + +管理端 `CKBConfigPanel` 接口测试对 `POST /api/ckb/join` 传 `type=investor`、`userId=admin_test`。`CKBJoin` 对资源对接在非空 `userId` 时校验 `userHasContentPurchase`,`admin_test` 非真实用户且无订单 → 返回 `success:false`、`CONTENT_PURCHASE_REQUIRED`,与其它 join 子项不一致。 + +## 处理 + +在 `internal/handler/ckb.go` 中:**当 `userId` 去空格后为 `admin_test` 时跳过购课校验**(该串仅工作台连通性测试使用)。真实用户 ID 仍为 UUID,不受影响。 + +## 注意 + +勿将真实用户 ID 设为 `admin_test`;若后续收紧,可改为管理端专用 Header 或仅 `/api/db` 代理测试接口。 diff --git a/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝计划Key列表与重推一致.md b/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝计划Key列表与重推一致.md new file mode 100644 index 00000000..583fb699 --- /dev/null +++ b/.cursor/agent/后端工程师/evolution/2026-05-08-存客宝计划Key列表与重推一致.md @@ -0,0 +1,37 @@ +# 存客宝:计划 Key 列表展示与重推实发 apiKey 一致 + +## 问题现象 + +- 管理端「推广中心 / 获客列表」**计划Key** 列显示为某条计划(如 `2y4v5-…`)。 +- 点 **重推** 时,实际请求 `ckbapi…/v1/api/scenarios` 的 `apiKey` 却是全局 `getCkbLeadApiKey()`(如 `IPQ9s-…`),存客宝返回 `无效的apiKey` / 401。 + +## 根因 + +1. **两套解析链**:`GET /api/db/ckb-leads?mode=contact` 对 `planApiKey` 做多层兜底(`plan_api_key` → action 默认 → `target_person_id`/`persons.ckb_api_key` → index_link 全局人物);旧 **`retryOneLeadRecord`** 在 `plan_api_key` 为空时**直接** `getCkbLeadApiKey()`,且曾用 `params.targetUserId` 覆盖却**未读表字段 `target_person_id`**,甚至曾在非空快照上再被人物 key 覆盖。 +2. **展示与写请求分叉**:运营按界面计划 Key 排障,与抓包不一致,误判为「存客宝挂了」。 + +## 修复要点(已实现) + +- 抽 **`resolveLeadPlanAPIKeyForRetry`**(命名保留历史;语义为「本条线索应采信的计划 apiKey」),顺序与列表原注释一致。 +- **`retryOneLeadRecord`** 仅通过该函数取 key;`target_person_id` 与 `params.targetUserId` 并用。 +- **`DBCKBLeadList` mode=contact** 循环内 **`planApiKey` 改为调用同一函数**,与重推、定时重试(同走 `retryOneLeadRecord`)长期同源,避免再分叉。 +- 调试用的 **`DBCKBLeadRetry` 终端打印、`pushLeadToCKB` URL 打印** 已按上线要求移除。 + +## 排查同类问题时的检查清单 + +| 检查项 | 说明 | +|--------|------| +| 是否存在「列表/详情一套、再请求另一套」 | 搜索同一业务字段在两处分别拼接 | +| `plan_api_key` 空时行为 | 是否与人物、`action/source` 一致 | +| 人物标识 | 表字段 `target_person_id` 与 JSON `targetUserId` 是否同时考虑 | +| 重推与首次提交 | 重推当前为 **GET scenarios 简化参数**;若与首次 **POST JSON** 不一致,可能仍有个案失败(产品另行评估) | + +## 关联代码 + +- `soul-api/internal/handler/ckb.go`:`resolveLeadPlanAPIKeyForRetry`、`retryOneLeadRecord` +- `soul-api/internal/handler/db_ckb_leads.go`:`DBCKBLeadList` mode=contact 中 `planApiKey` + +## 关联文档 / Skill + +- `.cursor/skills/ckb-leads-api-test/SKILL.md`(Gotchas:planKey 与重推一致性) +- `.cursor/skills/api-dev/SKILL.md`(Gotchas:展示与下游请求字段同源) diff --git a/.cursor/agent/后端工程师/evolution/索引.md b/.cursor/agent/后端工程师/evolution/索引.md index 256200ed..d376573c 100644 --- a/.cursor/agent/后端工程师/evolution/索引.md +++ b/.cursor/agent/后端工程师/evolution/索引.md @@ -12,3 +12,5 @@ | 2026-03-24 | router 缺失四 handler:BookRanking、DBPersonPinnedToken、CKBPinnedPerson、AdminDashboardLeads | [2026-03-24.md](./2026-03-24.md) | | 2026-04-13 | 按功能同步开发文档:接口/迁移文档化与 P0/P1 标注 | [2026-04-13.md](./2026-04-13.md) | | 2026-04-14 | 吸收沉淀:接口与需求表同步、BACKEND-P0 行 | [2026-04-14.md](./2026-04-14.md) | +| 2026-05-08 | 存客宝获客列表计划Key与重推 apiKey:`resolveLeadPlanAPIKeyForRetry` 与列表同源,避免展示与抓包分叉 | [2026-05-08-存客宝计划Key列表与重推一致.md](./2026-05-08-存客宝计划Key列表与重推一致.md) | +| 2026-05-08 | 存客宝工作台 join·资源对接测试:`userId=admin_test` 跳过购课校验,避免 CONTENT_PURCHASE_REQUIRED 误报 | [2026-05-08-存客宝工作台资源对接接口测试.md](./2026-05-08-存客宝工作台资源对接接口测试.md) | diff --git a/.cursor/agent/智能体-技能-经验总索引.md b/.cursor/agent/智能体-技能-经验总索引.md index ed235fb4..b35b8802 100644 --- a/.cursor/agent/智能体-技能-经验总索引.md +++ b/.cursor/agent/智能体-技能-经验总索引.md @@ -24,6 +24,7 @@ - 2026-03-10:迁移 Mycontent-temp(主导航收敛/Settings 承载) - 2026-03-05:文章详情@某人(编辑页插入 @ 用户) - 后端工程师:`agent/后端工程师/evolution/索引.md` + - 2026-05-08:存客宝计划 Key 列表与重推 apiKey 同源(resolveLeadPlanAPIKeyForRetry) - 2026-04-14:吸收沉淀(接口与需求表、BACKEND-P0) - 2026-04-13:按功能同步开发文档(接口/迁移文档化、P0/P1) - 2026-03-24:router 缺失四 handler 补齐(BookRanking 等) diff --git a/.cursor/agent/软件测试/evolution/索引.md b/.cursor/agent/软件测试/evolution/索引.md index 0ce120e9..94a28983 100644 --- a/.cursor/agent/软件测试/evolution/索引.md +++ b/.cursor/agent/软件测试/evolution/索引.md @@ -12,4 +12,5 @@ | 2026-03-16 | 测试用例归档规则:混合→process、纯端→miniapp/web;需求变更时更新 | [2026-03-16-scripts目录与测试关联.md](./2026-03-16-scripts目录与测试关联.md) | | 2026-04-13 | 按功能同步开发文档:以文档与索引为真源、契约缺失可阻塞 | [2026-04-13.md](./2026-04-13.md) | | 2026-04-14 | 吸收沉淀:LOOP 需求行与逆推清单回归 | [2026-04-14.md](./2026-04-14.md) | +| 2026-05-08 | 获客列表计划Key与重推 apiKey 同源后可验收:同 id 下列展示与推送 key 一致 | [后端 2026-05-08](../../后端工程师/evolution/2026-05-08-存客宝计划Key列表与重推一致.md) | | 2026-05-07 | 存客宝工作台线索类型:join=加入、match=匹配、lead=留资;开发文档与 UI 中文映射 | [存客宝-工作台线索类型](../../../开发文档/6、后端/存客宝-工作台线索类型与中英文说明.md) | diff --git a/.cursor/skills/api-dev/SKILL.md b/.cursor/skills/api-dev/SKILL.md index 1d0b9d08..dee2f43c 100644 --- a/.cursor/skills/api-dev/SKILL.md +++ b/.cursor/skills/api-dev/SKILL.md @@ -112,6 +112,7 @@ description: Trigger when 编辑 soul-api、后端、API、Go、Gin、GORM、新 | 新增表/字段后未执行迁移 | 线上报错、字段缺失 | 编写 scripts/add-xxx.sql → 执行 `node .cursor/scripts/db-exec/run.js -f soul-api/scripts/add-xxx.sql` | | 新增 model 未 AutoMigrate | 表不存在、启动失败 | 在 `internal/database/database.go` 中 `AutoMigrate(&model.Xxx{})` | | 业务逻辑直接 `os.Getenv` | 配置分散、难维护 | 仅通过 `internal/config` 的 `Load()` 读环境变量 | +| 管理端展示的「计划 Key / 状态」与再次调用第三方用的密钥 **分两处手写解析** | 线上列表对的、重推错的;排障永远对不上抓包 | **单一真源函数**:如存客宝线索 `resolveLeadPlanAPIKeyForRetry` 同时服务 `GET .../ckb-leads?mode=contact` 的 `planApiKey` 与 `retryOneLeadRecord`,禁止列表与重推各写一套顺序 | --- diff --git a/.cursor/skills/ckb-leads-api-test/SKILL.md b/.cursor/skills/ckb-leads-api-test/SKILL.md index d49acea3..2ec7437f 100644 --- a/.cursor/skills/ckb-leads-api-test/SKILL.md +++ b/.cursor/skills/ckb-leads-api-test/SKILL.md @@ -74,6 +74,7 @@ description: JWT 驱动的存客宝获客列表 API 回归。用户粘贴管理 | 把 JWT 写进会议纪要/需求文档 | **账号泄露** | 仅口头/私聊粘贴;复盘里写「已用临时 token 测过」不写原文 | | 脚本失败就认为一定是小程序 Bug | **误判** | 先区分「接口未返回字段」vs「库里真的无手机号」——前者是后端/部署,后者才可能追 C 端 | | 工作台「类型」列 join/match | **混淆** | join=**加入**(ckb/join),match=**匹配**(ckb/match);留资为 lead,见 `开发文档/6、后端/存客宝-工作台线索类型与中英文说明.md` | +| **获客列表「计划Key」与重推 URL 里 `apiKey` 不一致** | 界面是人物/快照兜底后的展示,重推曾误用全局 `CKB_LEAD_API_KEY`,报「无效的apiKey」 | 后端已统一:`resolveLeadPlanAPIKeyForRetry` 同时用于 `mode=contact` 的 `planApiKey` 与 `POST .../ckb-leads/retry` 内部推送;验收时对比**同一条 id** 下列 key 与(临时)服务端日志/抓包是否同源 | | 控制台中文乱码 | 难以读输出 | Windows 可先 `chcp 65001` 或设 `PYTHONIOENCODING=utf-8` | --- diff --git a/soul-admin/src/pages/find-partner/FindPartnerPage.tsx b/soul-admin/src/pages/find-partner/FindPartnerPage.tsx index 064cf18e..fd3ae527 100644 --- a/soul-admin/src/pages/find-partner/FindPartnerPage.tsx +++ b/soul-admin/src/pages/find-partner/FindPartnerPage.tsx @@ -182,7 +182,7 @@ export function FindPartnerPage() { 关闭 -
加入/匹配提交
@@ -631,8 +631,8 @@ export function CKBConfigPanel({ initialTab = 'overview', fullBleed }: { initial )} {activeTab === 'config' && ( -