# 06 · demo 接真实 API:原型升格为正式 demo - **Type:** task - **Status:** resolved - **Blocked by:** 03, 04, 05 ## Question **2026-09-09 改版(用户拍板)**:票 00 的原型 demo(`.scratch/customer-contact-graph/prototype/prototype-contact-graph.html`)验收通过后,本票不再重写,而是把该原型**升格为正式 demo**:mock 数据层换成真实后端 API 调用(图谱读/边增删/布局保存/明文 reveal/快速添加/页内编辑/导入三段式),交互形态与渲染引擎沿用原型已验证版本。 1. **API 接线清单**(对齐票 01 spec 冻结的端点契约):列表分页/查询、图谱读(含自动边+手动边+布局)、边 add/delete、布局 save、明文 reveal(含埋点)、快速添加、页内编辑批量保存、导入三段式。**注意:spec 冻结后口径已变——只有手动边(无自动边/否决),公司边为派生视图不可删**(详见 [spec.md](../spec.md) §7 demo 修订⑧);本票接线前先按修订⑧回写原型行为(砍 rebuildAutoEdges/否决交互,公司边不可删)再接 API。 2. **mock→API 替换**:数据层收敛到单一 fetch 层(原型里 mock 函数逐个换真实调用),交互/状态机代码不动。 3. **导入 UI**:批量导入三段式(模板下载/上传预检/confirm),对齐客户导入 tab 形态。 4. **验证方式不变**:node --check(若内嵌 JS 抽出)+ 静态路径对账 + 既有 31+20 步冒烟不回归;图谱交互的 Playwright 自动化留给票 08。 ## Answer **实现**(demo 1491→1729 行 + selfcheck.py 360→约 530 行;ADR-0040): - 修订⑧先行回写:auto 边引擎/否决交互全删(rebuildAutoEdges/autoParentsOf/vetoed tombstone/isAuto 确认弹窗);公司边派生渲染(`derivedCompanyEdges`,edge-company 虚线浅蓝无 ×,摘线=降级,撤级/取级检查豁免公司边);层级变化只做 `sanitizeManualEdges` 非法边清理不生成边(后端 batchEdit 不动边,save 67018 兑底);删手动边直接进 pendingDeletes 无确认;saveGraph 全量快照 POST + 67017 重拉重置基准。 - 数据层收敛单一 fetch 层:`API_BASE = URL ?api=` 覆盖 + `apiGet/apiPost/apiDownload` + `apiEnvelope`(Result 信封 code==0);loadDicts(job_title 两级树 + contact_source)/loadGraph/applyGraph 落地;JacksonConfig Long→String → id 全 String() 防精度丢失;mock 9 人/内置字典/nextId 死代码清零;async init 失败 toast 提示 ?api= 用法。 - 导入三段式 modal:impStep1 模板+上传(方式/重复策略/文件)→ impStep2 预检计数+明细 → impStep3 轮询 1s 结果+失败明细;接五端点(template/upload/confirm/result/failures;page 为列表分页不在 demo 范围);终态 loadGraph 重拉(bump 后版本刷新)。 **票面逐条**: 1. API 接线清单 ✅(14 端点:dict tree/enabled-list、graph detail/save、reveal、delete、quickAdd、batchEdit、export、import template/upload/confirm/result/failures)+ 修订⑧回写先行 ✅ 2. mock→API 替换 ✅(交互/状态机不动,仅数据层替换) 3. 导入 UI 三段式 ✅(对齐客户导入 tab 形态) 4. 验证 ✅:node --check exit 0 + 静态路径对账(14 端点 ↔ Graph/Enhance/Contact/ContactImport 四 Controller + DictItem 全对齐,无幽灵路径)+ selfcheck **59 步 0 失败**(原 51 步按修订⑧改造:边计数口径 1 manual + 3 derived company、收尾A 改「无幽灵边自由降级」、步骤 8 断言 4=后端不动边拉回非法边、步骤 9 重写为公司边无 ×+手动边删免确认+save 版本推进;新增步骤 11 导入三段式冒烟)。图谱交互 Playwright(真实拖拽链路)已在自检覆盖,票 08 承接真实 API 侧。 **冒烟/对账暴露并修复 3 个原型缺陷**:① jobFull option value 错绑类别 code → 职务变更静默失效(改绑职务 code,与 jobTitleCode 提交契约一致)②脱敏回显形态误拦保存(含 \* 放行=不改口径)③模板下载 POST→GET(后端 @GetMapping,实机 405)。 ADR-0040;CONTEXT.md 无需更新(纯 .scratch demo + 自检改动,后端零代码变更)。