Files
prop-ai-hr/docs/租户与组织两级治理实施计划-20260723.md
T

251 lines
12 KiB
Markdown

# 租户与组织两级治理实施计划
> 日期:2026-07-23
> 适用范围:银城帮道管理后台、组织同步服务与多租户数据治理
## 1. 建设目标
将“租户”与“外部组织架构”明确为两个独立但受控关联的领域:
- **租户**是数据、用户、知识空间、业务配置和权限的隔离边界。
- **组织架构**是来自外部组织平台的集团、公司、项目、部门、人员层级目录。
- **平台层**负责外部组织源、组织目录和租户绑定规则;**租户层**只在平台授予的范围内使用组织数据。
形成正式、可审计、可扩展的两级治理模型,而不是让各租户自行配置外部接口并任意导入组织数据。
```mermaid
flowchart LR
A[外部组织开放平台] --> B[平台组织目录]
B --> C[平台租户-组织绑定]
C --> D[独占范围租户组织快照]
C --> E[仅汇总范围聚合指标]
D --> F[租户内人员、权限与业务数据]
E --> G[跨租户汇总看板]
```
## 2. 治理边界与角色
### 平台超级管理员
- 配置并维护全局外部组织连接器,包括接口地址、Token、Client ID/Secret 等敏感凭据。
- 刷新平台组织目录,维护租户与组织范围的绑定。
- 执行范围冲突校验、启停绑定、查看操作审计和汇总指标。
- 处理跨租户边界调整等高风险变更。
### 租户管理员 / HR 管理员
- 只能查看平台已分配给本租户的组织范围。
- 仅可在“独占范围”绑定下发起组织刷新;刷新范围由服务端依据绑定关系确定。
- 不能修改连接器、绑定根节点、范围模式或其他租户的组织边界。
## 3. 不可变业务规则
### 3.1 范围模式
| 模式 | 可同步组织快照 | 可查看内容 | 与其他租户的关系 |
| --- | --- | --- | --- |
| `EXCLUSIVE`(独占范围) | 可以 | 本租户范围内的原始组织、人员及业务数据 | 不得与任何已生效独占范围存在相同、祖先或子孙节点重叠 |
| `AGGREGATE_ONLY`(仅汇总) | 不可以 | 已授权的跨租户聚合指标 | 可覆盖多个子租户的独占范围,但不可读取明细、不可写入子租户数据 |
### 3.2 冲突判定
- 两个独占范围相同,冲突。
- 一个独占范围是另一个独占范围的上级或下级,冲突。
- 两个独占范围为互不包含的兄弟节点,不冲突。
- 集团根节点若要覆盖已独占绑定的子公司,必须使用“仅汇总”,不能再以“独占范围同步全部下级”。
- 首期每个租户只允许一个已生效绑定,避免一租户多范围造成权限解释歧义。
### 3.3 数据隔离
- 外部组织节点以外部稳定 ID 为准,组织名称仅用于展示和人工校验。
- `AGGREGATE_ONLY` 不落地子租户原始组织快照,不返回人员明细,不允许跨租户写入。
- 组织同步请求不再信任客户端传入的 `groupId`、`companyId`、`departmentId`;服务端必须从当前租户的有效绑定解析同步根节点。
- 当前开放组织接口只支持集团、公司、部门作为同步范围,因此“项目”节点首期仅用于展示层级,不可作为绑定根节点;这样可避免上游忽略项目过滤后扩大同步范围。
- 未建立有效绑定的租户,不允许执行组织同步或使用依赖组织范围的管理能力。
## 4. 数据模型
首期新增一份 MySQL migration;不删除、不迁移现有 `aihr_org_snapshot` 数据。
### 4.1 平台组织目录:`aihr_org_directory`
| 字段 | 说明 |
| --- | --- |
| `source_code` | 组织连接器标识 |
| `external_id` | 外部组织稳定 ID |
| `parent_external_id` | 外部父节点稳定 ID |
| `node_type` | 集团、公司、项目、部门等节点类型 |
| `name` | 节点展示名称 |
| `path` | 外部 ID 路径,用于祖先/子孙冲突校验 |
| `directory_version` | 本次目录版本 |
| `active` | 是否仍在外部源有效 |
| `created_at` / `updated_at` | 维护时间 |
唯一约束:`(source_code, external_id)`。
### 4.2 租户组织绑定:`aihr_tenant_org_binding`
| 字段 | 说明 |
| --- | --- |
| `id` | 主键 |
| `tenant_id` | 目标租户 |
| `source_code` | 关联的组织连接器 |
| `root_external_id` | 绑定根组织节点 |
| `mode` | `EXCLUSIVE` 或 `AGGREGATE_ONLY` |
| `status` | 草稿、已生效、已停用 |
| `directory_version` | 绑定校验所依据的目录版本 |
| `last_sync_at` | 最近一次独占范围同步时间 |
| `created_by` / `updated_by` | 平台操作人 |
| `created_at` / `updated_at` | 维护时间 |
约束:首期一个 `tenant_id` 最多一个已生效记录;绑定生效前必须通过服务端冲突预检。
### 4.3 审计
复用现有系统操作日志,记录以下关键信息:操作人、租户、连接器、根节点、旧/新模式、目录版本、预检结果、确认动作和失败原因。首期不另建平行审计体系。
## 5. 后端实施
### 5.1 平台治理 API
仅平台超级管理员可访问:
| 接口 | 用途 |
| --- | --- |
| `GET /api/aihr/platform/org-directory/tree` | 获取平台组织目录树 |
| `POST /api/aihr/platform/org-directory/refresh` | 从全局连接器刷新目录 |
| `GET /api/aihr/platform/tenant-org-bindings` | 查询绑定列表和状态 |
| `POST /api/aihr/platform/tenant-org-bindings/precheck` | 提交前校验范围冲突和影响 |
| `POST /api/aihr/platform/tenant-org-bindings` | 创建草稿或生效绑定 |
| `PATCH /api/aihr/platform/tenant-org-bindings/{id}` | 调整或停用绑定 |
| `GET /api/aihr/platform/tenant-org-bindings/{id}/aggregate` | 获取仅汇总范围的授权指标 |
### 5.2 改造既有组织同步
既有 `POST /api/aihr/org/sync` 调整为:
1. 从当前认证身份获取租户,不再从客户端接收或信任同步范围。
2. 查询该租户的有效 `aihr_tenant_org_binding`。
3. 无绑定时返回 `409 TENANT_ORG_BINDING_REQUIRED`。
4. 绑定模式为 `AGGREGATE_ONLY` 时返回 `409 AGGREGATE_ONLY_CANNOT_SYNC`。
5. 绑定模式为 `EXCLUSIVE` 时,由服务端解析 `root_external_id` 和允许的下级范围,再写入本租户的 `aihr_org_snapshot`。
6. 记录目录版本、同步结果和审计日志。
### 5.3 授权与安全
- 全局连接器密钥只保存在服务端配置或密钥管理系统,绝不下发浏览器和小程序。
- 平台接口必须校验平台超级管理员;不能以普通租户管理员身份绕过。
- 所有组织和人员明细查询须同时校验租户、绑定模式和当前身份权限。
- 汇总接口只返回已定义的聚合指标,禁止用筛选参数变相导出其他租户明细。
## 6. 管理后台实施
新增平台超级管理员专属菜单:**平台设置 / 租户与组织绑定**。该页面使用“平台控制台”上下文,不使用普通租户切换器。
### 6.1 绑定总览
- 指标卡:有效租户、已绑定、待绑定、范围冲突。
- 租户列表:租户、绑定状态、组织根节点、范围模式、最近同步、操作入口。
- 组织树:展示当前绑定范围;独占范围清晰标注“可同步”,仅汇总范围标注“仅查看授权汇总”。
- 治理侧栏:当前角色、操作审计、最近目录刷新、同步统计和边界说明。
### 6.2 新建绑定向导
1. 选择尚未生效绑定的租户。
2. 从平台组织目录选择根节点,并选择“独占范围”或“仅汇总”。
3. 服务端执行冲突预检,展示范围、影响数据量和冲突明细。
4. 无冲突时明确确认并生效;有冲突时阻止直接提交,进入冲突处理页。
### 6.3 冲突处理
对于“集团范围覆盖已独占的子公司租户”的常见场景,默认推荐:
> 保留子公司的独占租户,集团改为仅汇总。
结果为:子公司继续隔离并可同步;集团只能看跨租户授权聚合指标,不能访问子公司人员明细,也不能写入子公司业务数据。
另一种“解除子公司绑定,统一归入集团独占租户”属于跨租户边界迁移,首期只展示为后续高风险能力,不开放实际执行。未来实现时必须增加二次确认、迁移方案、影响预览、审批和完整审计。
### 6.4 设计图引用
以下设计图为本计划的后台交互基准。实现时应以其中的页面信息层级、状态表达和操作边界为准;文案可随真实接口字段微调,但不得改变独占范围与仅汇总的权限语义。
#### 绑定总览
![租户与组织绑定总览](assets/tenant-org-governance/tenant-org-binding-overview.png)
图 1:平台超级管理员查看租户绑定状态、组织范围、审计信息和同步概览。
#### 冲突预检
![新建租户组织绑定的冲突预检](assets/tenant-org-governance/tenant-org-binding-conflict-precheck.png)
图 2:选择租户与组织范围后,由服务端返回冲突明细;存在独占范围冲突时禁止直接生效。
#### 冲突处理
![范围冲突处理方案](assets/tenant-org-governance/tenant-org-binding-conflict-resolution.png)
图 3:默认推荐保留子公司独占租户、集团改为仅汇总;高风险的边界迁移仅作为后续能力展示。
## 7. 迁移与上线步骤
1. 新增组织目录和租户绑定表,不修改现有组织快照表结构和历史快照。
2. 由平台超级管理员刷新外部组织目录,确认外部稳定 ID、父子关系和目录版本正确。
3. 为每个存量租户创建草稿绑定,逐一执行冲突预检;不得通过名称自动猜测绑定关系。
4. 对通过预检的租户显式生效绑定;先运行一次受控的组织同步,再核对快照、人数和审计日志。
5. 启用同步守卫:未绑定租户和仅汇总租户均无法调用原始组织同步。
6. 逐步将依赖组织范围的管理能力接入绑定校验;每次启用前保留回退开关和数据核验记录。
## 8. 验收标准
### 规则与数据
- 相同、祖先、子孙独占范围均被拒绝。
- 互不包含的兄弟独占范围允许绑定。
- 集团“仅汇总”覆盖多个独占子公司时允许绑定。
- 仅汇总范围不产生子租户的原始组织快照。
- 外部节点改名不影响已建立绑定;外部稳定 ID 变化必须显式告警。
### 接口与安全
- 无有效绑定调用组织同步,收到 `TENANT_ORG_BINDING_REQUIRED`。
- 仅汇总绑定调用组织同步,收到 `AGGREGATE_ONLY_CANNOT_SYNC`。
- 客户端伪造 `groupId`、`companyId`、`departmentId` 不会扩大实际同步范围。
- 普通租户管理员不能调用平台目录、绑定管理和跨租户明细接口。
- 汇总接口无法返回人员、组织或业务明细。
### 前端与审计
- 浏览器验证绑定总览、绑定向导、冲突预检、冲突处理四种状态。
- 已生效独占范围显示最近同步与同步结果;仅汇总范围显示授权汇总状态,且无“同步”入口。
- 所有绑定新建、修改、停用、预检和同步操作均可在操作日志追溯。
## 9. 分期范围
### 第一阶段:安全治理基础
- 平台组织目录、租户组织绑定、范围冲突校验。
- 既有组织同步的服务端范围收口。
- 平台绑定管理页和基础审计。
### 第二阶段:汇总治理能力
- 仅汇总范围的指标口径、授权控制和集团看板。
- 完善目录刷新、异常告警和同步运行记录。
### 第三阶段:受控扩展
- 多组织连接器。
- 租户自有连接器的申请、审批、密钥托管和隔离执行。
- 跨租户边界迁移工作流、审批与可回滚方案。
- 外部组织事件订阅与增量同步。
## 10. 明确不在首期范围内
- 不允许每个租户自行保存外部 API 地址、Token 或 Client Secret。
- 不自动根据组织名称推断并生效绑定。
- 不允许集团仅汇总范围同步或写入下属独占租户原始数据。
- 不直接执行“解除子公司租户、归入集团”的高风险边界迁移。
- 不删除现有 `aihr_org_snapshot` 历史数据来完成结构切换。