You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
8.9 KiB

2 days ago
# 客户模块联调就绪报告(customer-integration-ready 终验收 · 票 09)
**日期**:2026-09-11 **图**:`.scratch/customer-integration-ready/map.md`(十票全 resolved) **宣告**:A4 客户模块达到「前端可直接联调」状态,三层证据齐备。**用户验收(demo 走查)已过**:8080 运行态 23/23 全绿,记录 `demo-walkthrough.md`
## 一、结论
| 层 | 状态 |
|---|---|
| E2E 回归 | r3 全量 295 checks + UI 75 步,0 产品回归(票 01);票 10 后 e2e-graph 复跑 58 checks 全绿 |
| 模块测试 | crm-customer + crm-project **265 tests / 0 fail / 0 error / 0 skip**(含票 10 新代码) |
| 文档真值化 | 118 文件六项核验 **ALL_PASS**(下 §三);「非真实返回」占位全仓清零 |
| 原型处置 | 票 08 四题拍板全部落地:N1/N2/N3 当轮修完(票 10),G1-G6/N4/N5 记档进移交清单 |
## 二、E2E 与测试基线
- **r3 全量回归**(票 01,详见 `e2e-report-r3.md`):core 113✅1⚠ / heavy 59✅1❌ / incr 61✅2⚠ / graph 57✅1⚠ + 双 demo 冒烟 35/35、40/40。4⚠1❌ 逐一取证为共享库数据态或已记档模式,**0 产品回归**。
- **票 10 增量回归**:e2e-graph 重跑 **58 checks 全绿**(0 fail 0 warn,端点 17/17,teardown 清扫);模块测试 265/265 绿(首跑失败为本地仓 crm-dict/opportunity/rule snapshot 过期预存坑,`-pl install` 刷新后全绿,非代码回归)。
- **8080 交付态**:jar 2026-09-11 15:58:30 重建(含票 10 全部修复 + CodeReview 2×P3),verify profile 在跑,**运行服务 = 工作树源码**。
## 三、文档真值化与终验收核验
四票接力把 117+1 端点文档做到「不看源码就能联调」:
1. **缺口普查**(票 03):占位示例 79 文件 / 退化 7 / 嵌套未展开 26 / 说明不清晰 10 / 错误码节回退 30 —— 产出 117 行机器可 grep worklist。
2. **嵌套 DTO 展开**(票 04):`expand_nested.py` v4 写回 26 文件,五形态全覆盖(DTO-zero / 图谱 nodes·edges / type-F / DTO-flat / partial)。
3. **真值采集**(票 02 + 票 10):23 端点交割四件套真值 + 4 条 proj-truth(关联项目页签 / detail-head×2 / 图谱悬停字段)。
4. **真值化写回**(票 05):92 文件写回,**117 端点响应示例全部 E2E 实测真值**,验收 V1–V9 绿。
5. **说明清晰化**(票 06):错误码节回捞 30 文件(全仓 78/78 = HEAD 基线,码 67001–67024 源码比对零漂移)+ createTime×9 + 引号截断 7 行重建 + jobTitleLevel 值域源码先回写再同步。
**终验收六项核验**(`verify_integration_ready.py` → `verify-integration-ready.json`):
| 项 | 结果 |
|---|---|
| V1 结构对账 | **PASS**:磁盘 118 文件 ↔ 期望 118(mapping 117 + 票 10-N3 补充),双向零缺零余,对账钥匙行全一致 |
| V2 非真实返回 | **PASS**:全仓 0 命中 |
| V3 四件套结构 | **PASS**:meta / 请求块 / docs / 请求参数 / data 结构 / 响应示例 0 缺节(3 个二进制端点按票 05 口径豁免示例节) |
| V4 嵌套 DTO 展开 | **PASS**:`List<非原始类型>` 行 0 缺子表 |
| V5 说明质量 | **PASS**:说明列 0 空行、0 断行残片 |
| V6 UTF-8 无 BOM | **PASS**:0 |
## 四、原型对照与处置落点
- **台账**(票 07,`assets/prototype-parity-r3.md`):P0/P1 ×0;P2×2(N1 图谱悬停缺字段、N3 关联项目无数据源)、P3×3(N2 图谱不记日志、N4 操作日志仅单叙事列、N5 省市区无后端源);复核翻转 G4/G5 部分残留(与 ADR-0017 防泄露口径一致)。
- **拍板**(票 08,HITL):①N1/N2/N3 全部当轮修;②G1-G6 维持记档;③N4 记档 + N5 前端自带国标码表;④quick-create 维持七必填。
- **落地**(票 10):
- N1 `GraphNodeDTO` +`isInternal`/`giftRemark`,demo 悬停气泡切真值,图谱文档结构表同步;
- N2 `ACTION_GRAPH_EDIT` + 图谱保存落 oplog(action 值域 18 种两文档同步);
- N3 关联项目走 **port 路**(ADR-0029 对称商机范式):`CustomerProjectQueryPort` 三件套 + `detailHead.projectCount` 降级契约(失败显 "--")+ 新端点 `GET /api/customer/project/page` + `关联项目页签.bru` 新建。
- CodeReview:无 P1/P2,2×P3 采纳(分页 id 兜底排序、Noop javadoc 契约措辞)。
## 五、联调移交注意事项(前端)
1. **鉴权**:请求头 `Authorization: Bearer {{token}}`;联调环境(verify profile)取 token:`GET /api/auth/debug/token?userId=<用户id>`(如 admin = `739564171091247104` 罗伟健)。
2. **URL 与出入参约定**(ADR-0017):扁平动作动词 + 查询参数传 id(`POST /edit?id=`、`GET /detail?id=`);写端点一律 POST + **表单绑定(非 JSON body)**;读端点 GET。
3. **id 与数值形态**:雪花 id / total / size 等长整型一律**字符串出参**(防 JS 精度丢失),前端按字符串处理。
4. **脱敏口径**:联系人列表/详情出参 `phone` 字段即脱敏值(前 3 + `****` + 后 4),图谱节点出参字段名为 `phoneMasked`;明文一律走 reveal 端点(电话明文查看,留痕)。(demo 走查实测修正)
5. **乐观锁错误码**:编辑客户 `version` 必传,CAS 不符报 **67005**;图谱保存 `version` 比对不符报 **67018**(提示用户刷新后重试)。
6. **二进制端点**(3 个,文档为文字说明、非 JSON 示例,Axios 需 `responseType:'blob'`):`GET /api/customer/import/template`(客户公海 / 我的客户两分区同 URL)、`GET /api/customer/contact/import/template`。
7. **N5 注记**:省市区级联无后端数据源(票 08 拍板)——前端自带国标码表,存 `provinceCode` / `cityCode` 编码值。
8. **记档项**(不阻塞联调,均见台账):G1-G6(六处字段级缺口,G4/G5 与 ADR-0017 防泄露口径一致)、N4(操作日志三结构化列缺)、batchEdit 空串清空语义表单绑定下不可达(D-G1 豁免)。
9. **字典驱动**:customer_type / job_title(两级档位 level 1–10)/ 项目阶段别名等全部走 `/api/dict/*`,文档示例值即字典真值。
10. **参考实现**:`crm-customer` demo `.scratch/customer-e2e/demo/index.html`(E2E 同款调用姿势,含图谱编辑器)。
## 六、双仓未提交变更清单(均待用户审查提交)
**后端仓 `d:\code\crm-backend-matt`**(`git status` 为准,此处列代码增量,.scratch 产物与 logs 不列):
- 票 10(本图):改 7(CustomerConstants / CustomerDetailController / GraphNodeDTO / OplogPageParam / ICustomerDetailService / CustomerContactGraphServiceImpl / CustomerDetailServiceImpl)+ 新 3(customer port 接口与 Noop、crm-project port 真实现)+ 测试适配 4(Enhance / Graph / Members / Follow)+ demo index.html。
- 前置轮基线:@Schema 注解 8 文件(BaseDTO / BaseEntity / ContactDTO / CustomerFollow / CustomerOplog / CompanyLookupPort / CustomerOpportunityQueryPort / ColumnPreference——含票 06 jobTitleLevel 源码回写)。
- demo/E2E 运行产物(.scratch 下截图 / checks / xlsx)随审查取舍。
**文档仓 `D:\code\crm-api-docs`**:A4 分区约 100 个 .bru 修改(票 04 展开 / 票 05 真值化 / 票 06 回捞 / 票 10 同步叠加)+ 新目录 `A4 客户管理/客户详情/关联项目/`(关联项目页签.bru)。
## 七、环境与复跑指南
- **起服**(PowerShell):`$env:SPRING_PROFILES_ACTIVE='verify'; $env:CRM_MINIO_AK='admin'; $env:CRM_MINIO_SK='Itc@123456'; java -jar crm-app\target\crm-app-1.0.0-SNAPSHOT.jar`
- **远程共享库**:8.129.84.155(db crm);夹具纪律 `e2c-` 前缀 + 正门清扫。
- **文档核验**:`py -X utf8 .scratch/customer-integration-ready/verify_integration_ready.py`(期望 ALL_PASS,VERIFY_EXIT=0)。
- **E2E 复跑**:`py -X utf8` 跑 `.scratch/customer-e2e/{e2e-core-r2,e2e-heavy-r2,e2e-incr}.py` + `.scratch/customer-contact-graph/e2e-graph.py`;Playwright venv `.scratch/customer-e2e/.venv10`
- **模块测试**:`mvn -s settings.xml -pl crm-customer,crm-project test`;若遇 NoClassDefFound/NoSuchMethod 先 `mvn -pl <依赖模块> install -DskipTests` 刷新本地仓 snapshot(本图三次应验)。
- **发版部署**:需用户 SSH 凭据(移交清单见 `.scratch/customer-contact-graph/e2e-report.md` §八)。
## 八、产物索引
- 核验:`verify_integration_ready.py` + `verify-integration-ready.json`(本目录)
- 报告:`e2e-report-r3.md`(票 01)+ `assets/prototype-parity-r3.md`(票 07)+ `assets/doc-gap-worklist.md`(票 03)
- specimens:`specimens-{core,heavy,incr,graph}-r3.json` + `specimens-doc-truth.json`(23 端点)+ `specimens-proj-truth.json`(4 条)
- 日志:`{core,heavy,incr,graph,demo-t04,demo-graph}-r3-run.log`、`compile-n3.log`、`package-n3.log`、`e2e-graph-n3.log`、`test-n3-r3.log`、`server-final.log`
- 票据:`issues/01…10`(十票全 resolved,Answer 各附细节)