7.9 KiB
02 · 返工新增端点 API 用例
Type: task Status: resolved
Claimed: 2026-09-05 · wayfinder 工作会话(frontier 首票) Resolved: 2026-09-05
Question
round-1 矩阵从未覆盖的返工新增端点,设计并落用例(契约以 .scratch/customer-module/API-SUMMARY.md 对应节为准):
| 能力 | 端点 | 断言要点 |
|---|---|---|
| 战略协议 | POST /api/customer/agreement/create、/edit?id=、/delete?id=;GET /detail?id=、/list?customerId=(§2.6) |
create→edit→delete 全链 + DB 快照断言(返工冒烟范式:2→3→NULL);67001/67002/67017 |
| 查重设置 | GET /api/rule/customer/dedup、POST .../dedup/save(§3) |
save→get 回读;五字段(masterEnabled/nameEnabled/nameMatchMode/similarityThreshold/phoneEnabled);越界 64023 |
| 批量工商更新 | POST /api/customer/company-lookup/batch-update?ids=(§2.2) |
逐客户只补空缺字段;stub 恒 NO_HIT;五状态软处置 |
| 导入策略 | upload 增 duplicateStrategy(§2.12) |
SKIP 响应回显断言;非法值 67013 |
| confirmSimilar | POST /api/customer/quick-create 透传(§2.3) |
命中相似未确认 needConfirm / 确认后落库 |
| viewTouch | GET /api/customer/detail-head?id= 副作用(§2.5) |
customer_view_log upsert 去重(UNIQUE(user_id,customer_id)) |
| 形态偏好 | GET/POST /api/preference/view-form/get|save(§2.15) |
save→get 回读;viewForm 白名单 list/split/board |
| 联系人 oplog | 无独立端点——contact 写动作在 /api/customer/oplog/page 记 CONTACT_ADD/EDIT/DELETE |
oplog action 值域 17 种断言(AGREEMENT_* 3 种同验) |
断言语义从 .scratch/customer-rework/RETEST-REPORT.md 冒烟 43 步清单重建(脚本 tmp/smoke-t10.py 已随换机丢失,报告是唯一存证)。
决定承载方式:并入 core/heavy vs 独立 e2e-incr.py(与票 01 产物协同,避免两票改同一文件打架)。
Comments
- 2026-09-05 · 票 01 改写收官时锁定的本票精确输入:改写后静态对账(calls-r2.json
not_called_customer_domain)确认客户域未覆盖 19 端点中恰 10 个归本票——agreement×5(create/edit/delete/detail/list)、GET|POST /api/rule/customer/dedup(/save)、GET|POST /api/preference/view-form/(get|save)、POST /api/customer/company-lookup/batch-update;其余 9 个为 round-1 维持项,不进本票票面(票 06 对账附录记录)。协同件:e2e-heavy-r2.py_upload()已留duplicate_strategy形参 seam(F8 导入策略变体挂点);core F-12 已含 confirmSimilar 主断言,本票可引用或细化。另注意 round-1 未拆补的GET /api/rule/customer/reminder读端点不在本票范围(维持项)。
Answer
承载方式决定:独立 e2e-incr.py(.scratch/customer-e2e/,620 行)。理由:① 票 04 执行序 core→heavy→增量三方产物各自独立落盘;② 零触碰票 01 冻结对账产物(matrix-r2.md / calls-r2.json 记录的是改写时点静态事实,往 core-r2 里加端点即失真);③ harness 复制惯例与 heavy 先例一致。产出:e2e-incr-checks.json + specimens-incr.json(票 06 Bruno 对账素材)+ calls-incr.json(对账工具 scan_calls_incr.py 保留可复跑,正则含模块路径常量解析——dedup/view-form 调用走常量非字面量,首版对账靠它抓出盲区)。
用例结构(SETUP + I-01…I-07 + TEARDOWN,夹具 = 自建 e2c-r2i-A/B,不碰 seed 快照;setup 幂等清残留,teardown 正门 archive + DB 兜底清扫):
| 流程 | 覆盖 |
|---|---|
| I-01 战略协议全链 | create→list→detail→edit(2→3)→归属不可换(dto.customerId 忽略 + B 快照不动)→delete;快照 2→3→NULL 全程 DB 断言;负例 67001(缺 customerId)/ 67002(幽灵客户防探测同码)/ 67017×5(等级越界、等级缺失、amount>64 超长、幽灵协议 detail/edit/delete);oplog AGREEMENT×3 + 等级文案 |
| I-02 联系人 oplog | CONTACT_ADD/EDIT/DELETE 与 AGREEMENT×3 六动作齐现 + 17 种值域对账 + action= 过滤参数生效 |
| I-03 查重设置 | save 全量覆盖(响应即保存后单例)+ save→get 回读 + 缺省语义三连(开关→0 / 方式→模糊 2 / 阈值→出厂 80 非静默保留)+ 64023 越界×3 + 校验失败不落库 + 原值还原 |
| I-04 批量工商 | NO_HIT×2 + filledFields=0 + 档案前后全等(只补空缺的空转证据)+ 幽灵行级 NOT_FOUND + 空/101 ids → 67001 |
| I-05 viewTouch | 清预置→首访插入→再访 upsert 仍 1 行 + last_view_time 刷新→BUDDY 独立行(user 维度隔离)→自清 |
| I-06 形态偏好 | save→get 回读两跳 + 跨用户隔离 + 非法值 68001 + pool·board 契约漂移探测(分支设计,见下)+ 还原 |
| I-07 导入 F8 | SKIP 回显 + 重复组不写入(u=0);OVERWRITE 回显 + 末行生效(u=1);非法 67013;执行面 DB 断言(B 星级不变/变 5)+ D-05 家族 UPDATE 路径新观测分支兜底(D-08 预留续编) |
I-07 设计要点:文件仅含已有客户按编号 UPDATE 行(零 INSERT),主动绕开 round-1 D-05 的 INSERT 阻断面,使 F8 语义可获得独立验证;confirm 后按任务终态分支(DONE→DB 断言 / FAILED 且 failReason 含 is_biz_negotiated→warn + D-08「UPDATE 路径亦被阻断」家族观测 / 其他 FAILED→fail + D-08)。
confirmSimilar 处置:引用 core F-12 主断言(needConfirm→confirmSimilar=true 落库回 id)不重做;增量夹具 _mk_customer 内保留 confirmSimilar 兜底重发路径作伴生覆盖。
实现实核修正契约认知(写用例前代码侧实锤,票 06 Bruno/API-SUMMARY 对账输入):
- pool·board 白名单漂移(本票最重要发现):API-SUMMARY §2.14 与返工票 03/05 记载「公海 board 被平台拒绝(680xx)」;实现
ViewFormServiceImpl白名单仅全局三值 {list,split,board},无 pool 特判(crm-preference 全模块 grep 无 pool 分支)——预期实测 code=0,用例按「漂移记档 warn」分支设计不阻断,漂移非缺陷(归文档侧处置)。 - agreement 语义实核(
CustomerAgreementServiceImpl):67001=缺 customerId;67002=客户不存在/无权(防探测同码);67017=等级缺失/越界、amount>64、协议不存在/无权;快照=最新一条(create_time,id 倒序)回写且不 bump version——断言逐条对齐。 - dedup save 响应即保存后单例(对称 reminder 族);阈值缺省回出厂 80(a7-3-3-2 §4.1 覆盖口径)。
- batch-update:上限 100 检查先于 distinct(101 重复 id 亦 67001);空 ids 走 Spring 400(
@RequestParamrequired)而非 67001——用例按分支断言。 - view-form 为per-user 单字符串服务端状态(UNIQUE(user_id,scope_key),无 delete 端点,null 态不可经 API 复位)——地图 fog「UI 覆盖取舍」据此收敛:不进 demo,票 03 维持四入口清单(charting 拍板原文即四项;view-form/oplog 无独立 UI 语义,验证面已由 I-06/I-01/I-02 覆盖)。
静态验收 PASS:py_compile PASS(venv10 python);UTF-8 无 BOM;scan_calls_incr 对账 20 调用端点 = 105 基准全命中零未知 + 票 02 范围 10 端点全覆盖(范围外 10 = 夹具创建/清理/oplog 读取/import 执行面/detail-head 等支撑端点,基准内)。
移交票 04:
- 执行环境:venv10 缺 openpyxl(本轮实核)——跑增量前
& .venv10\Scripts\python.exe -m pip install openpyxl;compile/对账均用 venv10 解释器(shellpython不在 PATH,exit 9009)。 - 执行序:core→heavy→incr(incr 自带夹具与清理,重跑幂等);round-1 的 heavy
duplicate_strategyseam 保持未用(F8 归增量套件,避免两票改同一文件)。 - 增量套件 D-05 UPDATE 路径新观测分支已内置(FAILED 特征匹配→warn+D-08,不阻断);若真实出现即为 round-1 未知面新证据。