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.

207 lines
26 KiB

4 days ago
# 客户模块(A4)后端 spec — 复核交接清单
> 用途:交付给一个**全新的、无本会话上下文**的会话做第二轮 grill / 独立复核。
> 上一轮共 19 个 grill 决策(D18–D29 + D4-rev1/rev2)已全部由用户拍板。**本清单的目的不是报喜,而是把最可能被推翻的点提前摊开,供下一轮挑战。**
---
## 0. 怎么读这份清单
- **权威交付物**:`.scratch/customer-module/map.md`(决策索引 D1–D29,自包含)+ `issues/NN-answer.md`(各票详细决议,自包含)。
- **原型出处**:`D:\code\crm-需求梳理\lanhu-mcp\data\axure_extract_bade4454_screenshots\a4-*.txt`(蓝湖 A4 页面已本地提取文本)。
- **对称参照**:`.scratch/opportunity-module/map.md`(已完成的商机图,本图大量对称其范式)。
- **领域上下文**:`crm-customer/CONTEXT.md`、`crm-lead/CONTEXT.md`、`crm-opportunity/CONTEXT.md`。
- **协作规范**:`docs/agents/issue-tracker.md`、`docs/agents/triage-labels.md`。
**复核建议**:先读 `map.md` 的 Decisions 区(D1–D29,约 5 分钟),再逐个挑战下面「第 4 节薄弱点」。**不要**因为 map 里写了"已拍板"就跳过——这是本清单特意要求的。
---
## 1. 本图范围(D2)
**做**(8 大块):客户核心(实体+查重+公海+总览+我的客户+三视图+新增/编辑+导入)、联系人(CRUD+全局搜索+电话查重)、客户交割、客户规则族(超期提醒 + 查重设置)。
**留 seam(依赖未建)**:报备成功链路(方案卡已推送/A5 回调)→ 客户「重潜」阶段(D20 改票 B,本期潜在→重潜不触发);A5 项目模块 → 客户「已成交」阶段、「关联项目」详情页签、汇总卡「合同总额·累计回款」。
**划出(Not-yet / Out-of-scope)**:战略协议、联系人图谱(职务二级联动)、**客户查重列表+客户合并(A4-6)**、企查查/OCR 外部服务内部实现(只定契约 seam)、OCR 快捷新增、联系人导入。
---
## 2. 已冻结的决策(D1–D29 速览)
| # | 决策要点 | 原型/出处 |
|---|---|---|
| D1 | spec-only,对称商机图;做完进 /implement | — |
| D2 | 作用域三档划分(见上) | — |
| D3 | 双轴建模:轴1 归属(owner 空=公海)正交 archive_status;轴2 阶段三态只前进 | a4-2-1 |
| D4-rev1 | 客户规则族只含「超期提醒 + 查重设置」;星级/阶段退回硬编码 | a7-2-3 |
| D4-rev2 | 查重设置 = crm-rule 全局单例可配置,本期只消费于新增/编辑内建查重 | a7-2-3-查重 |
| D5 | 联系人 = crm-customer 独立表 `customer_contact`,权限继承客户 | a4-4 |
| D6 | 内建查重口径(后被 D4-rev2 改为可配置) | a4-3-3 |
| D7 | 客户主表字段八区 + DataScope + 索引(无孤立单大写陷阱) | a4-3-3 |
| D8 | 超期提醒:crm-rule 单例配置 + 待发通知表 + Job 只落待发 | a7-3-3 |
| D9 | 三视图/公海/总览 = 逻辑视图,内置视图不入库 | a4-1-1/a4-2-1 |
| D10 | 分层查重 + CustomerDedupService + 企查查 seam | a4-3-3 |
| D11 | 阶段只前进 CAS(三态字段/机制保留);重潜触发本期 seam 化不实现(D20 改票 B) | a4-4 |
| D12 | 联系人 CRUD + 全局搜索;电话查重软提示(D26);来源字典(D27) | a4-4 |
| D13 | 详情 8 页签 + 跟进 append-only + 字段级 oplog;卡片占位(D28) | a4-4 |
| D14 | 建 crm-customer/CONTEXT.md;依赖方向 opp→customer | — |
| D15 | 交割两段式;直属总监(D22);完成判定(D23) | a4-7 |
| D16 | 导入三模式 + 异步 + 行级部分成功;多行默认(D24) | a4-3-2/a4-3-5 |
| D17 | 超期提醒规则表/Job 细节 | a7-3-3 |
| D17b | 保存视图复用平台,3 scope_key;enter_pool_time 可排序(D29) | a4-1-1 |
| D18 | customer_type = crm-dict 字典,18 值(含4甲方+14非甲方) | a4-3-3 弹窗 |
| D19 | 归档=删除(软删);去掉「已被合并」态;列表筛选 default 排除已归档 | a4-2-1 |
| D20 | 重潜本期**不触发**、只留 `promote` seam(等「提交并报备成功」链路,不用「已提交」凑合) | a4-4-1 |
| D21 | 相似判定 seam 化;一期最简 = MySQL ngram FULLTEXT;阈值从配置读 | a7-2-3-查重 |
| D22 | 直属销售总监 = 组织架构推导(dept.leader 向上找销售总监);不改 crm-auth | a4-7-1 |
| D23 | 交接单完成 = 自动(assignedCount==totalCount);无手动按钮 | a4-7-1 |
| D24 | 导入多行匹配同一客户默认「重复时不导入」(重复组全失败) | a4-3-5 |
| D25 | 超期提醒锚点 = 成为「有主」时刻;公海 NULL 不计时;领取时赋锚点 | a7-3-3 |
| D26 | 电话查重=**可配置软提示**(不建唯一索引);同客户内电话不重复为表单级校验 | a7-3-3-2 查重设置 |
| D27 | contact_source 字典种子 = 组会/组局/转介绍/其他 | a4-4-1 |
| D28 | 汇总卡占位一律渲染 + 显"--"(不显 0,不留白) | a4-4-1 |
| D29 | 公海「进入公海时间」列保留 + 加入排序字段池 | a4-1-1 |
---
## 3. 为什么我信不过自己——复核方法论
用户的担忧是对的。上一轮我犯过**SOP 违规**(票 02–11 未经 grill 就标记 resolved),后来被迫全部重开重问。因此第二轮复核请遵循:
1. **每个决策都要能找到"证据"**:要么是原型页面(a4-*.txt 的原文文字),要么是用户当时明确说过的选型(如 Q8 的 18 值、Q16 的"全部电话")。**找不到证据的就是我编的,请当误入标注出来。**
2. **每个"定稿"都可被推翻**:~~D20(重潜触发点=已提交…请重点挑战)~~ **D20 已于 20260902 复核翻案为 B(本期不触发、留 seam),见 §4.1**、D22(组织架构推导在无组织数据/多领导时的降级行为我写的是"阻断",但用户可能预期"降级给普通接收人")。
3. **决策之间的一致性**:D8/D25(锚点)、D19/D3(归档)、D4-rev2/D6(查重口径)、D12/D26(电话唯一)、D4-rev1/D7(星级)——若两条决策互相打架,是我没对齐。
---
## 4. 我最担心的薄弱点(请下一轮重点挑战)
### ✅ 4.1 D20 重潜触发 —— **用户拍板 B(20260902):本期不触发、只留 seam,翻案**
- 我选了「保守」口径:方案卡状态到「已提交」就触发客户重潜。
- **风险**:原型 A4-4 的重潜定义其实写着「关联的任一方案卡**提交并报备成功**」。我因为「报备/推送链路本期不可达」而收窄成「已提交」。用户可能完全接受,也可能说"那就等报备成功再触发,本期不实现重潜"。
- **请问**:报备链路不可达时,是「用已提交凑合触发」还是「本期干脆不实现重潜、只留 seam」?
- **第三轮 fresh 复核(20260902)**:`a4-4-1`(8-26 fresh)L359/L412 原文明文「任一方案卡**提交并报备成功**后 → 重潜客户」= 两个条件。用「已提交」单条件凑合会造出「提交了但报备没成功、客户却已重潜」的错误状态。
- **✅ 已拍板(用户选 B,20260902)**:本期**不自动触发潜在→重潜**,客户阶段实际只有「潜在」;`CustomerStagePort.promote` seam(契约/只前进 CAS/幂等)全部保留,等报备成功链路(方案卡「已推送(3)」或 A5 回调)就绪再接入调用。**不用「已提交」凑合。** map.md D20/D11 + 票 05-answer + CONTEXT.md 已同步。
### ✅ 4.2 D22 直属销售总监 —— **已确认(grill Q12 拍板 A),复核补全「调动/区域调整=下拉选」分支**
- 复核发现:票 08-answer L15/L23 已把口径写全 = **离职=组织架构推导自动定唯一总监**(无/停用/多条→阻断提示管理员);**岗位调动/区域调整=在本人启用的直属总监内下拉选(不阻断)**。
- 原 HANDOFF 4.2 段只描述了「离职=推导阻断」这**一半**,漏了下半句。**非决策遗漏,是记录不全**。修正:阻断仅离职专属;调动/区域调整为可选下拉,不阻断。
- **✅ 已确认(20260902)**:无需翻案,仅补齐 map.md D22 描述(补充「调动/区域调整=下拉选、离职才阻断」)。不改 crm-auth、不加 `superior_user_id` 维持原判。
### ✅ 4.3 D4-rev1 把「星级/阶段设置」踢出客户规则族 —— 阶段 ✅A口径 / 星级 ✅已三点确认(20260826)
- **阶段**:第二轮复核拍板 **A 口径** —— 客户阶段=固定三态(潜在→重潜→已成交),只前进不回退,**不建 `a7-2-3 客户阶段设置` 页**。D4-rev1 对阶段部分**正确,保留**。
- 依据:`a4-4-1` 详情页 3 次强调「阶段由业务结果驱动、阶段条不可点击修改、只前进不回退」,与 A 口径一致。
- 注:`a7-2-3 阶段设置` 页与详情页内部矛盾(可增删/排序/迁移 vs 只前进不可配),已裁决按详情页(A 口径)走,设置页视为原型残留。
- **星级**:✅ **已确认原判成立(第二轮复核,用户拍板 20260826)**。我上一轮引用「关系星级名称+描述由管理员自定义」是**基于过时原型缓存**(`a7-2-3_星级设置_.txt` 为 2026-07-20 旧快照,仍是「潜在/高潜/合作/重点/战略 + name/desc 可配」老口径)。**新原型已更新**:`a4-3-3-1_新增客户信息.txt`(2026-08-26)L91-106 显示客户星级、关系星级**均为「一星~五星」两个普通下拉字段**,无 name+desc 可配语义。**用户三点确认**:①客户星级/关系星级=两个 1~5 星字段;②D4-rev1「星级退回硬编码枚举 1~5」**确认成立**(非翻案);③星级**彻底不进客户规则族**(`a7-2-3 星级设置`页当作不实现,同阶段设置页处理)。**我上一轮「关系星级必须可配」的纠偏作废。**
### ✅ 4.4 D26 联系人电话查重 —— **用户拍板 A(20260902):降级为可配置软提示,翻案**
- 用户拍板选了「全部电话唯一(含座机/短号)」——比我的推荐(仅手机号 11 位唯一)更强。
- **风险**:座机/短号撞号概率实际远低于手机号;但**同一个公司多个联系人的座机可能共用一个总机号**,这会误伤。强制唯一可能让"一个公司两个联系人都填了同一个座机总机"这种正常场景无法保存。
- **请确认**:是否真的对座机也做全局唯一?要不要豁免「座机且同客户」?
- **第三轮 fresh 铁证(20260902,重新提取 8-26 原型 HTML)——D26「电话全局唯一」被查重设置页正面推翻**:新版 `a7-3-3-2_客户管理设置_客户查重设置_.txt`(源 HTML 2026-08-26)**逐条否定电话唯一约束**:
- 「**总开关仅控制客户名称、联系电话的重复提醒**」——电话查重是「**提醒**」不是「约束」;
- 「**统一社会信用代码为系统强制规则,不受总开关影响,不提供关闭开关**」——**只有信用代码是唯一强制**;
- 通用判断规则:「统一社会信用代码精确命中时,**禁止创建客户**;客户名称或联系电话任一命中时,**提示疑似重复客户**」——电话命中只**提示**、不阻断;
- 「联系电话:**支持单独开启或关闭**;匹配方式固定为精确匹配;命中时提示疑似重复」——电话查重可被管理员整体关闭。
- **结论**:原型口径下电话查重 = **可开关的软提示(提示疑似重复,不禁止创建)**,与 D26 主张的「**电话全局 DB 唯一索引 + 撞号即拒绝保存**」**直接冲突**。D26 是**过度设计**:把原型的软提示误升级为硬约束。
- **座机豁免问题自动消解**:既然电话查重本来就只是"提示疑似重复、不禁止","多个联系人共用总机座机导致无法保存"的误伤场景根本不存在——因为原型从不因电话撞号阻止保存。
- **新增页佐证**:`a4-3-3-1_新增客户信息.txt`(8-26)§3.5「联系电话存在时…按电话值查重;电话值完全相同时禁止新建」仅约束**同一表格内两行**(同一客户内联系人不能填相同电话),**不是跨客户全局唯一**。
- **建议**:D26 从「电话全局唯一索引」**降级为「可配置的电话查重提示」**(跟随 crm-rule 客户查重设置单例的"联系电话"开关),DB 层**不建电话唯一约束**;仅保留同客户内联系人电话不重复的表单级校验。**待用户拍板改票 06 D26。**
- **✅ 已拍板(用户选 A,20260902)**:采纳建议。D26 改票:`uk_contact_phone(phone)` 唯一索引**撤销**;电话查重=可配置软提示(跟随 crm-rule 查重设置「联系电话」开关);仅保留同客户内联系人电话不重复的表单级校验。**map.md D26/D12 已同步改口径。**
### ✅ 4.5 D18 customer_type 18 值——**已证实,非编造(第二轮复核,证据在 `a4-1-1`)**
- **原判断撤销**:第一轮我 grep 只搜 `a4-3-3-1` 新增页,漏了 `a4-1-1` 公海列表,误判"部分编造"。
- **决定性证据**:`a4-1-1_客户公海列表.txt` L45-63 是客户类型筛选下拉的**完整展开枚举**:
`运营商 / 土建总包 / 机电总包 / 装修总包 / 教育局 / 投资(代建)公司 / 设计院 / 集成商 / 招标代理 / 咨询造价公司 / 甲方(企业用户)/ 甲方(普教)/ 甲方(中高职)/ 甲方(政府机关)/ 竞争同行 / 个人用户 / 操手 / 集成商(子客户)` = **17 具体值 + 1"全部客户类型"占位 = 18 值**
- 与票 02 列表逐字一致(含"投资(代建)公司""集成商(子客户)")。**消号,D18 成立**。
- **第三轮 fresh 复核(20260902,重新提取 8-26 原型 HTML)**:新版 `a4-1-1_客户公海列表_列表视图_.txt`(源 HTML 时间戳 2026-08-26)里客户类型筛选下拉**未展开**,文本提取只捕获表格样例行的 4 个值(甲方(中高职)/甲方(企业用户)/甲方(政府机关)/甲方(普教)),**全部落在旧 18 值集合内**,无新增/删除迹象;`a4-1-1` 列表视图 data.js 仅含 `甲方(中高职)` 单元格值,18 值枚举不在页面级资源。**新原型正面印证决策架构**:`a4-3-3-1_新增客户信息.txt`(8-26)需求文档「枚举与人员数据」明确「**下拉枚举只加载后台配置的启用项**」「已停用枚举可在编辑场景回显,新增时不可选」——即客户类型 = **后台配置字典**,与 D18「crm-dict 字典分组、非硬编码」完全吻合。**结论:D18 架构决策获新证据强化;18 个具体种子值来自 7-20 枚举、新原型未反证(样例值均在集合内),种子值列表仅影响初始化脚本、不影响架构。D18 ✅ 保持。**
### ✅ 4.6 D24 导入「重复时不导入」默认 —— 已确认(grill Q14 用户拍板 A),非缺陷
- 我默认「重复时不导入」(重复组全失败)。但**很多导入场景用户是想"更新老客户"的**,默认不导入可能让大批行失败。
- **请确认**:默认到底该是「不导入」还是「更新」?还是按导入方式(仅新增/仅更新)各自定?
- **✅ 已确认(grill Q14,用户拍板 A)**:文件内多行匹配同一客户,`覆盖导入`/`重复时不导入` 互斥,**默认「重复时不导入」**——重复组全部标失败不写入,用户看失败明细处理。覆盖模式作为可选项存在但不默认。
### ✅ 4.7 D21 ngram FULLTEXT —— 已确认可用(MySQL 8.4.8)
- 一期最简用 MySQL ngram 分词器(token_size=2)。**ngram parser 是 MySQL 5.7.6+ 功能**,且对中文分词效果一般(会切出大量无意义二元组)。
- **请确认**:项目 MySQL 版本是否 ≥5.7.6?若偏低,ngram 不可用,得回退 LIKE + Levenshtein(或我提过的 Jaccard)。
- **✅ 已确认(20260902)**:项目 MySQL = **8.4.8**,≥5.7.6,ngram 分词器可用,无需回退。
### ✅ 4.8 D17b 保存视图复用平台 —— 已确认(`user_saved_view` 支持多 scope_key)
- 我复用现有保存视图平台并假设它支持多 scope。**请核对** crm-auth / 现有平台的 `user_saved_view` 表结构和 scope 机制,确认"公海/总览/我的客户"各存一套视图不会串。
- **✅ 已确认(20260902)**:`user_saved_view` 平台支持多 scope_key(每入口各存一套),公海/总览/我的客户各自保存不串。
### ✅ 4.9 D9 视图「内置视图不入库」 —— 已确认(逻辑视图,内置硬编码)
- 我写内置视图(如"我的客户-未跟进N天")硬编码不入库,用户自定义视图才入库。但这个边界(哪些算内置、哪些算自定义)我没问用户,是拍脑袋定的。
- **请确认**:哪些内置视图是必须的?用户能不能改/删内置?
- **✅ 已确认(20260902)**:三个 workspace(公海/总览/我的客户)= 逻辑视图,靠 `@DataScope` + `owner_user_id IS NULL` + `archive_status` 过滤区分,**不建独立表**;内置视图(含常用检索)硬编码不入库,用户自定义视图才入库,边界成立。
---
## 5. 需要用户明确但**我可能漏问**的点
1. **公海 vs 我的客户是否允许"重复看到同一客户"**:一个客户在公海,同时又被我领了,会不会同时在两个列表出现?(我默认:有主就只在我的客户,公海只出无主,二者互斥。)
- **✅ 原型铁证已定向(20260902)**:`a4-1-1_客户公海列表_列表视图_.txt`(8-26)领取确认弹窗 L327/329 明文「领取后,该客户将**归属当前账号**,并**从客户公海移除**」;批量领取 L341-347 同理「领取后,以下客户将统一归属当前账号,**并从客户公海移除**」。
- **结论**:**§5.1 消号**。公海与我客户**互斥**(领取=移出公海,归属有主)。D3(归属⊥归档双轴)+ D9(公海=owner IS NULL 逻辑视图)原判**正确,维持**。无需拍板。
- **区分「关注」**:公海列表有「关注/取消关注」(个人关注状态,如 L89 取消关注 / L129 关注),关注≠领取,**不改变归属**,客户仍在公海。「我关注的客户」是检索维度,可含公海客户,但不影响互斥模型。
2. **客户能否被多个负责人共同跟**?我默认单负责人(owner_user_id 单值)——但原型有"团队成员"页签,可能暗示多协作者。**这是竞品常见分歧点,我没问。**
- **✅ 原型铁证已定向(20260902)**:`a4-4-8_客户详情_团队成员_.txt`(8-26)需求说明 **11.1 角色与管理权限** 明文「**每个客户只允许 1 名负责人,其余成员均为协同人**(如销售协同人、方案工程师等)」「协同人可查看对应客户的信息」。团队成员页签展示角色列(负责人/协同人)+ 添加成员(搜索多选、不可重复)+ 删除成员(二次确认、仅撤销后续访问权限、不影响历史记录)。
- **结论**:**§5.2 消号**。客户**单负责人**(owner 单值)+ **多个协同人**(团队成员表),协同人可见但非负责人。D3/D5/D7 单负责人原判**正确,维持**;「团队成员」页签 = 负责人+协同人列表,非多负责人。无需拍板。移除「多负责人」这一待确认项。
3. **删除语义**:D19 已归档=软删,但「归档」按钮 vs「彻底删除」——有没有彻底物理删除的入口?我默认没有(只有归档)。
- **✅ 原型证据已梳理(20260902)**:客户「删除」= **逻辑删除**(`deleted` 标志),无前端直接"删除"入口、无物理删除。依据:
- `a4-4-1_客户详情_客户信息_.txt` 操作区仅「归档」(L127)+「标记重点客户」,**无"删除"按钮**;
- `a4-4-1_客户详情_已归档客户_.txt` 提供「恢复」(L47)+ 归档条件(L325-335:有进行中商机/未完成项目/待审批流程/未履约合同/未结清款项→不允许归档;归档不填原因不审批直接执行;归档成功取消跟进提醒);
- `a4-6-3_客户合并.txt` L323「合并成功后保留主客户,将其他已选客户**标记为已合并并执行业务软删除,不做物理删除**」;
- `a4-3-3-1_新增客户信息.txt` L690 / `a4-6-1` L315 查重范围 = 「全部**未删除**客户」→ 存在 `deleted` 逻辑删除标志。
- **建议**:D19 归档=软删(`archive_status=已归档`,可恢复原判**维持**);客户`deleted` 标志 = **系统级软删除(合并/数据治理用,非前端功能)**,前端不暴露"删除客户"入口。**三态档案(有效/已归档/已被合并)+ deleted 软删标志并存**,需确认 deleted 是否仅合并时由系统置 1(而非用户手动删)。**此项需你拍板:客户删除入口是否彻底不做?**
- **✅ 已拍板(用户选 A,20260902)**:**一期只做归档**——不提供任何前端"删除客户"入口;用户侧只有归档(软删可恢复)+ 合并(源客户系统软删,且合并本体 Out-of-scope);`deleted` 标志仅系统在合并时置 1,**不开放手动删除、无前端删除按钮**;DB 不做物理删除。**票 02-answer(archiveStatus 三值→两值去掉已被合并、deleted 补充说明)+ 票 01-answer 已同步。**
4. ~~**导入时的邮箱/电话查重**~~ **已解决(D26 翻案 20260902)**:D26 电话不再唯一,导入时跨客户电话撞号=软提示疑似重复、不阻断(列明细,跟随查重设置开关);同一文件内同客户电话相同两行=该行失败。已回填票 09-answer。
5. **操作日志保留时长**:customer_oplog 字段级日志,有没有保留期/归档策略?我默认无限期。
- **✅ 原型证据已定向(20260902)**:`a4-4-8_客户详情_操作日志_.txt`(8-26)**只强调审计属性、未提保留时长**——L250「日志生成后**不可修改或删除**」,L232「仅记录提交成功后的业务变更」,L188 操作类型固定枚举(新增/修改/归档/恢复/关联/取消关联/状态变更/负责人变更/添加成员/移除成员/合并/导入/导出/敏感信息查看/系统操作)+ L199 字段级「旧值→新值」。即原型把操作日志定位为 **append-only 审计日志**
- **结论**:保留时长**原型无要求 = 技术决策**(非规格缺口)。**已拍板(用户选 A,20260902)**:`customer_oplog` **无限期保留**——① 审计日志要求完整、不可删改(L250),保留期会截断审计链;② 字段级日志量可控(客户主记录操作频次低);③ 无清理逻辑最简、无运维负担。**票 07-answer 已补保留策略行。**
---
## 7. 本轮复核结论(20260902,fresh 原型第三轮)
**复核方式**:对 4 个 7-20 过期快照页(a7-3-3-2 查重设置 / a7-3-3-1 超期提醒 / a4-4-1 客户信息 / a4-1-1 公海列表)用本机 Lanhu Python MCP 重新提取 **8-26 fresh** 文本,逐项对照。
**§4 九个薄弱点 —— 全部闭环**:
| 项 | 结论 | 拍板 |
|---|---|---|
| 4.1 D20 重潜触发 | **翻案**:原型=「提交**并报备成功**」两条件,原判「已提交」错误 | **用户选 B**:本期不触发、只留 seam |
| 4.2 D22 直属总监 | **确认**(补全「调动/区域调整=下拉选」,仅离职才阻断) | 维持 |
| 4.3 星级/阶段 | **确认**(阶段 A 口径 / 星级两点确认) | 维持 |
| 4.4 D26 电话查重 | **翻案**:原型查重设置页证明电话=软提示非唯一 | **用户选 A**:可配置软提示、不建唯一索引 |
| 4.5 D18 18 值 | **消号强化**:后端字典架构获 fresh 印证 | 维持 |
| 4.6 D24 重复导入默认 | **确认**(非缺陷) | 维持 |
| 4.7 D21 ngram | **确认**(MySQL 8.4.8) | 维持 |
| 4.8 D17b 保存视图 | **确认**(多 scope_key 不串) | 维持 |
| 4.9 D9 内置视图不入库 | **确认**(逻辑视图) | 维持 |
**§5 五个漏问点 —— 全部闭环(新增 2 个拍板)**:
1. 公海/我客户互斥 —— ✅ 消号(领取即移出公海,原型 L327-347)
2. 多负责人 —— ✅ 消号(**单负责人 + 多协同人**,原型 a4-4-8 明文「每个客户只允许 1 名负责人,其余均为协同人」)
3. **客户删除入口** —— **✅ 拍板 A(一期只做归档)**:无前端删除按钮,deleted 仅系统合并置位
4. 导入电话查重 —— ✅ 已随 D26 解决(软提示)
5. **oplog 保留时长** —— **✅ 拍板 A(无限期保留)**:审计日志不设保留期
**本次修正的字段口径(D19 拍板后的遗留同步)**:
- `archive_status` 收敛为 **有效1 / 已归档2** 两值(去掉「已被合并」,合并 Out-of-scope)
- 已归档 = **删除语义(软删)**,不做独立 tab/子页,列表加 `archive_status` 筛选(默认排除)
- 已同步:`crm-customer/CONTEXT.md`(L8/27-28/36/40/56)+ 票 01-answer / 02-answer + map.md D19/D9 + 各 research 子票加顶部废弃注记
**结论**:**全部 29 项决策 + 4 个复核翻案(D20/D26)+ 2 个新增拍板(§5.3 删除 / §5.5 oplog)已定稿**,spec 冻结,可进入实现阶段。
## 6. 交付状态
- `map.md`:D1–D29 全部记录,Frontier = 空,spec 冻结标记。
- `issues/NN-answer.md` × 11:全部 `Status: resolved`,各⚠挂号/待确认小节已销号。
- `issues/NN-<slug>.md` × 11:research/task 子票,全部 `Status: resolved`
- `crm-customer/CONTEXT.md` + `CONTEXT-MAP.md` 行:已建。
- 未动任何 Java 源码(git status 里的 `Opportunity.java` 变更与本 effort 无关,是既有改动)。
**下一步**:交给新会话按第 3、4 节方法复核。若复核对 4.1–4.9 有改动,改对应决策编号 + 重开相应票(如 D20 改 → 重开票 05),而非覆盖原决策(遵循编号+修正链约定)。