Files
lingxi/docs/adr/ADR-002-两级行业目录.md
T
Stev_Wang 140dc386c1 feat(client): A3 客户与行业目录(两级行业、客户组、字段审批)
背景:A3 需把行业 / 客户 / 客户组 / 客户级字段立为资产根节点;用户确认两级行业树与混搭 UI(行业 B / 客户列表 A / 详情 A / 新建 B / 客户组 B / 字段 A)。

改动:
- 新增 ADR-002,行业改为两级树,客户挂末级行业;同步 PRD / 技术架构 / 开发计划。
- 新增 client 模块:industries / customers / customer-groups / customer-fields 接口、真实 PrismaCustomerDirectory、客户状态机与客户转交、客户组数据范围解析、跨客户 404。
- 新增迁移与幂等种子(电商/金融两级行业、2 客户、1 客户组、4 条字段)。
- 前端新增行业/客户/客户组/字段审批页面与路由、导航更名(客户管理 / 行业管理 / 客户组),复用现有 token。
- 补充 shared 契约单测、client 集成用例、A3 浏览器 e2e。

影响面:client 模块与 client 表、shared 契约、web 路由/导航、ScopeContext 数据范围、OpenAPI 与种子;A1 客户转交占位由 client 实现替换。
回滚:回滚本提交;数据库保留新增表或按报告执行 down SQL;CUSTOMER_DIRECTORY 可切回空集实现。
验证:format:check / lint / typecheck / test 全绿(shared 131 / api 90 / web 125,共 346);test:int 5 文件 39 条;A3 e2e 1/1;build 8/8;真实浏览器六页验证通过。
2026-11-03 21:45:38 +08:00

8.0 KiB
Raw Blame History

ADR-002 行业目录:由单层改为两级树,客户挂末级行业

项 内容
状态 已接受(2026-11-03,用户确认 A3 口径)
决策人 产品 / 技术负责人(用户)
记录人 工程 Lead
关联 开发计划 V0.1 §6.4 A3、§7.4、§12.1 M0 DoD、附录 C;PRD V1.6 §5.4.2 / §5.4.5、R-20;技术架构 V0.4 §5.3 / §5.4.1 / §6.3.2;ADR-001
影响范围 client 模块、industry 模块(行业包绑定)、catalog / script / media / asset 的行业维度、数据范围与统计报表、A4 字典口径、开发计划与 PRD/架构文档

背景

PRD R-20 与技术架构 §5.3 均把 industries 描述为单层行业目录(「行业 = 客户的业务属性」,名称全局唯一),「行业二级(电商 → 服饰鞋包 / 美妆个护)」在 PRD §5.4.5 中作为 A4 字典项处理;开发计划 §6.4 A3-BE-01 也按单层 industries 描述。

A3 开卡前用户确认:行业目录需要两级树(一级行业 → 二级行业),客户归属到末级行业。该口径与既有文档冲突,且影响客户归属、行业包匹配、数据范围、统计与 A4 字典边界,属于 AGENTS §0.4 要求先提 ADR 的决策。

决策

D1 行业为两级树,最多两级

industries 表增加:

字段 类型 说明
parent_id ulid FK → industries,可空 一级行业为空;二级行业指向一级行业
level smallint 1 / 2;由服务端按 parent_id 推导并校验
sort_order int 同级排序,默认 10
status varchar 启用 / 停用
remark varchar(200) 备注

约束:

  • 仅允许两级;二级行业下不可再建子行业(应用层校验 + 数据库可选触发器兜底)。
  • 一级行业 parent_id IS NULL AND level = 1;二级行业 parent_id NOT NULL AND level = 2。
  • 客户只挂末级行业,详见 D2。

D2 客户挂末级行业,行业包按祖先回退

  • 客户 industry_id 指向末级行业:有子行业的一级行业不可被客户选择;一级行业无子行业时可直接选择。
  • 客户创建后不可跨行业移动;调整行业走「停用 + 新建」(PRD R-20 原口径不变)。
  • 行业包匹配按「精确行业 → 一级行业 → 默认」回退(B0 落地);行业顾问/行业指南同样按「二级 → 一级 → default → 内置准则」匹配(PRD §5.4.7 / §7.x)。
  • 行业级资产包、行业级字段覆盖等按「客户所属末级行业 → 一级行业」继承。

D3 行业名称唯一性:一级全局唯一 + 二级同父唯一

  • 一级行业名称全局唯一。
  • 二级行业名称在同一 parent_id 下唯一;不同一级行业下允许重名(如「其他」)。
  • 客户名称仍在同一末级行业下唯一((industry_id, name) 唯一,原口径不变)。

D4 删除与停用:只停用 + 引用保护

  • 删除:无子行业、无客户、无资产时才可删除;否则只能停用。
  • 停用:有启用中的子行业时禁止停用,提示先处理子级;有客户时允许停用,停用后新建客户不可选该行业,已有客户数据不受影响。
  • 停用一级行业不级联停用子级;需逐级处理,避免一次操作影响面过大。

D5 权限复用现有 30 个权限点

A3 行业管理不新增权限点:

  • 查看:customer:read;写(新建 / 编辑 / 停用 / 删除):customer:manage。
  • 开发计划附录 C 写的 industry_pack:view 在 A2 定稿的 30 个权限点中不存在,按本 ADR 回写为 customer:read;industry:manage 仍表示行业包编辑(B0)。

D6 「行业二级」从 A4 字典中移除

PRD §5.4.5 的「行业二级」字典项改由 industries 两级树承载;A4 字典保留其他受控词表。A4-BE-01 的「三层合并(本行业 + 父行业 + 通用)」中的「行业作用域」按两级树的祖先链解释。

备选方案

方案 结论 原因
保持单层行业(PRD/架构原文) 未采用 用户明确要求两级;单层无法表达「电商 → 服饰鞋包」的行业分类
单层落地 + 预留 parent_id 未采用 本期 UI 与客户选择就要两级联动,预留字段会造成前后端口径分叉
行业二级放 A4 字典 未采用 字典项没有行业归属/状态/引用保护,且客户 industry_id 无法稳定指向二级;A3 就需要行业树维护
两级树 + 客户挂末级(本 ADR) 采用 与用户口径一致;行业包按祖先回退,保留单层时期的继承语义

后果

正面

  • 行业分类可表达一级/二级,客户归属更精确;行业包可在任一级配置并向下继承。
  • 行业二级不再依赖 A4 字典,A3 即可交付完整行业树维护。
  • 权限点不新增,复用 A2 定稿目录,治理成本低。

负面 / 代价

  • 与 PRD R-20、技术架构 industries、开发计划 A3/A4/M0 DoD 的原文冲突,必须同步修订,否则文档与实现不一致。
  • 客户归属校验从「行业存在」升级为「行业存在且为末级」,A2 CustomerDirectory 与数据范围解析需按末级行业返回客户。
  • 行业统计、报表、行业包匹配需处理祖先链,查询复杂度上升。
  • 历史数据若已按单层行业写入(当前本地库无行业数据),需 parent_id 置空并标记为一级行业;A3 首次建表,不涉及存量迁移。

迁移 / 兼容策略

A3 首次创建 industries 表即按两级结构落地,采用 expand → migrate → contract:

  1. 建表含 parent_id / level / sort_order / status / remark;
  2. 迁移脚本对存量行业(如有)设 parent_id = NULL, level = 1;
  3. 应用层先写 level,后续若需严格约束再补触发器 / 检查约束;
  4. 回滚:删除新增列即可回到单层语义(客户 industry_id 仍指向原行业)。

待办 / 回写清单

文件 章节 需要改成什么
docs/PRD/灵犀-信息流广告素材一站式生产平台PRD.md R-20 明确行业两级树、客户挂末级、一级全局唯一 / 二级同父唯一
同上 §5.4.2 客户所属行业改为末级行业;补充两级树与停用/删除规则
同上 §5.4.5 「行业二级」从字典表移除,注明由 industries 两级树承载
同上 §5.4.7 / §7.x 行业指南 明确「二级 → 一级 → default」回退
docs/技术架构/灵犀_信息流素材生产平台_技术架构_V0.1.md §5.3 表清单 industries 增加 parent_id / level,约束改为「最多两级、一级全局唯一、二级同父唯一」
同上 §5.4.1 customers industry_id 指向末级行业;补充「客户不可挂有子行业的一级行业」
同上 §6.3.2 行业接口权限改为 customer:read / customer:manage;补充两级树与删除/停用校验
docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md §6.4 A3-BE-01 改为两级行业树;删除/停用规则按 ADR-002 D4
同上 §7.4 页面口径补充「一级/二级树、客户挂末级」
同上 §12.1 M0 DoD 「行业两级」改为「行业两级树(一级 → 二级),客户挂末级」
同上 附录 C /system/industries 权限改为 customer:read / customer:manage
docs/开发计划/灵犀_A2角色权限与数据范围_实施报告_V0.1.md §5 遗留 1 注明 A3 接入真实客户目录时按末级行业返回客户
README.md / AGENTS.md 文档索引 / 事实基线 视需要补充 ADR-002 与行业口径变更

文档同步按 AGENTS §0.4「先改文档,再改代码」执行;本 ADR 先于 A3 后端实现落地。

关联

  • ADR-001 权限点目录与六类数据范围
  • 开发计划 V0.1 §6.4 A3、§7.4、§12.1
  • PRD V1.6 R-20、§5.4.2、§5.4.5
  • 技术架构 V0.4 §5.3、§5.4.1、§6.3.2
  • 前端原型:design/a3-ui-v1/(三套候选,待用户选择)