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.

64 lines
6.4 KiB

1 day ago
# 01 · spec 冻结:图谱数据模型与契约设计
- **Type:** grilling
10 hours ago
- **Status:** resolved
1 day ago
- **Blocked by:** 00(原型 demo 验收通过后继续;以 demo 为活参照——demo 里 mock 实现的规则 = 逐组定稿的素材与对照物)
## Question
对照原型需求权威(`.scratch/opportunity-bugfix/lanhu-pages/A4-4-2_客户详情(联系人).md` u533 列表侧 + u536 图谱 15 条),HITL grilling 逐组定稿并产出 `spec.md`
10 hours ago
1. **边模型**:单父树(修订④ 拍板:一个节点最多一个上级;公司节点豁免——多个等级 10 并列挂公司);边表字段(customer_id / parent_contact_id / child_contact_id / source=auto|manual);**系统边删除的持久否决**(原型第 9 条:删除系统生成的连线并保存后不再自动恢复——tombstone 还是边行 status);自连/循环/重复的拒绝口径与错误码。
1 day ago
2. **自动生成算法**:job_title_level → 层级位置(越高越靠上、同级并列、多顶层并列、公司节点固定居中);自定义职务/层级为空 → 「未识别层级」区不生成连线;职务修改后的增量语义(全量重建 vs 差异)。
3. **布局持久化**:拖拽位置是否随「保存」落库(原型第 12 条「保存本次新增、删除和调整的关系」);归属 per customer 全局共享(推荐)还是 per user。
4. **并发冲突**(原型第 14 条):关系被他人修改的检测方案(版本号 / updated_at)与冲突响应形态。
5. **job_title 字典设计**:原型职务集(董事长/股东/采购经理/市场经理/采购专员/市场专员/人事经理/投标商务·其他)→ 标准职务 code/name/category/level 枚举 + **职务二级联动选择器**(类别→职务)的字典查询契约;层级分档规则由产品定(grill 向用户要分档表)。
6. **contact_source 字典值**(原型出现:转介绍/组会/组局;W-01 销号口径)。
7. **新端点契约清单**:图谱读 / 边 add / 边 delete / 布局 save / 关系变更日志 / 明文查看 reveal + 查看日志 / 批量导出 / 页内编辑批量保存 / 快速添加多行 / 导入三段式 —— 逐端点 method+路径+入参+出参+错误码(错误码段沿用 67xxx 还是新段?);过 ADR-0017 flat 纪律。
8. **埋点表**:明文查看日志(操作人/时间/联系人/是否命中号码),是否进 oplog 或独立表。
9. **联系人导入**:表复用深度(复用 customer_import_* 形态 vs 独立 contact_import_*)、Analyzer 预检校验清单(迁移 D-05/D-04 教训:NOT NULL 无默认列群必填前移 + clip500)、导入触发图谱自动更新的落点。
10. **图谱规模上限**记录(单客户数百联系人时的布局与读端点预案)。
**交付**:`.scratch/customer-contact-graph/spec.md`(D 决策 + 新表 DDL 草案 + 端点契约表 + 字典值定稿)——02~07 的唯一输入。
10 hours ago
## 原型已定参照(2026-09-10 票 00 resolve 时灌入)
- **已定规则全景 12 条 + 待钉点 5 条**:见票 00 `## Answer`(等级值域 1–10 / 格子布局 / 拖格子定级 / 无向连线 / 单父 / 自动边 / 否决 / 等级调整约束 / 一致性清理 / 编辑态 / 列表侧)——**已定项不重问**,与下面 Question 议程冲突时以原型为准。
- **待钉点(grilling 议程增量)**:①等级↔job_title 字典映射细则(10/6/3 仅示例);②右侧栏「未设置等级」持久化语义(定级回写职务 vs 独立存等级);③拖格子定级是否需保存确认;④自动边多候选是否改择一;⑤格子布局下自由拖拽位移是否仍需持久化(Question 3 重新表述)。
## Answer
**spec 冻结完成(2026-09-10,grilling 12 问全部拍板)**:产出 [.scratch/customer-contact-graph/spec.md](../spec.md)(191 行冻结版)——12 项用户拍板(D1–D12)+ 2 项技术自定(T1 错误码 67xxx 从 67017 起、T2 规模上限预案)+ 新表 DDL 草案 5 张 + 端点契约 15 个 + 字典种子定稿(job_title 两级树 5+9 项 / contact_source 4 项)。
### 12 项拍板速览
| # | 决策 | 拍板 |
|---|---|---|
| D1 | 等级真值 | 双值模型:字典=初始值;图谱定级只改联系人、不回写字典 |
| D2 | 职务变更流转 | 来源区分:字典来源跟随重算;手工定级锁定不动(level_source 列) |
| D3 | 分档表 | 三档制 10/6/3 原型转正(5 类别 9 职务) |
| D4 | 保存模型 | 保存才入库(前端 pending + 单一 save 事务端点) |
| D5 | 位移持久化 | 不持久化(布局纯由 level 推导,行内稳定序) |
| D6 | 边模型 | **只有手动边,没有自动边**(推翻原型自动生成/否决机制) |
| D7 | 公司边 | 等级 10 自动挂公司 = 唯一保留的自动规则 |
| D8 | 公司边语义 | 派生视图不可删(读时算出,摘线=降级,豁免锁定) |
| D9 | 并发冲突 | 独立图谱版本号(meta 表 + save 乐观锁) |
| D10 | 明文埋点 | 独立表 customer_contact_reveal_log(crm-customer 域内) |
| D11 | 联系人导入 | 独立表镜像形态(contact_import_task/fail) |
| D12 | contact_source | 四项含其他(W-01 销号) |
### 关键事实链(grilling 期自查)
- `customer_contact` 四列留位(job_title_name/id/category/level)直接启用,加 `level_source` 一列即可。
- crm-dict 两级树先例 = industry(9+51);job_title 级联复用 `GET /api/dict/item/tree` 零新端点。
- crm-log 三表全文本快照型 + AOP 只采 POST(reveal 是 GET)→ 埋点必须独立表。
- 客户导入已顺带建联系人行(toContact),但语义不同 → 联系人导入独立表镜像。
- 错误码 67xxx 已用至 67016,从 67017 起分 7 个号位(67017–67023)。
- ADR-0017 纪律核过:隐式表单绑定、禁 @RequestBody;客户导入六端点形态作联系人导入模板。
### 作废与衍生
- **作废**(spec 冻结即失效):原型自动生成边算法(rebuildAutoEdges)、删除否决/tombstone、auto 多候选歧义规则(待钉点④)、边表 source 列。demo 修订⑧已写入 [票 06](06-demo-extension.md)(接线前先回写原型行为)。
- **衍生待办**:票 02 需 crm-dict 缝合 ADR(dict_item.level 列 + 两组种子 + CONTEXT.md);票 03/04/05 按 spec §二/§三 落 DDL 与端点。
- **fog 消解**:map 四条 Not yet specified 全部落 spec(分档映射→D3;auto 边增量语义→随 D6 作废;导入表复用→D11;规模上限→T2 §六)。