docs(spec): add dynamic roles and doc visibility rbac design spec

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WeiCHEN
2026-09-08 22:27:17 +08:00
co-authored by Cursor
parent 2745e89ed3
commit 3d75471dc2
@@ -0,0 +1,258 @@
# 动态角色管理与单文档可见性覆盖权限系统架构设计规范
# (Dynamic Roles & Document-Level Visibility Override RBAC Specification)
- **归档路径**: `docs/superpowers/specs/2026-09-08-dynamic-roles-and-doc-visibility-rbac-design.md`
- **编制日期**: 2026-09-08
- **当前状态**: 批准实施 (Approved)
- **技术栈**: React 19 + TypeScript + Vite + FlowMind Token 设计系统 + Go 后端规范兼容
---
## 一、 业务背景与问题分析 (Background & Core Problem)
在医疗器械全流程智能协同研发系统中,业务交付物既包含依照法规(GMP/ISO13485/NMPA)强制要求的受控主线文档(如《立项可行性报告》、《技术规格书》),也包含高敏感度的商业机密、专利拆解草案以及跨部门协作资料。
目前系统已具备初步的三层交付物分类(`workflow` / `shared` / `private`)与文档三权(编制/审核/批准)生命周期流转。但在团队规模化协作和企业级权限管控上面临以下核心痛点:
1. **角色模型固化且缺乏全局唯一性**:
- 用户角色与项目职责混杂,缺乏公司级/系统级的全局角色(如研发总监、技术主管、合规专家、方案工程师、外聘访客);
- 无法在系统中动态新增、修改或删除角色,无法根据企业实际组织架构灵活配置默认功能权限。
2. **工作流文档可见性缺乏精细化受控与覆盖机制**:
- 目前受控工作流交付物对项目成员默安全域一视同仁,缺乏工作流基线可见性规则;
- 关键涉密文档(如涉及未公开核心光学算法、敏感供应链成本底牌)无法由文档负责人或主管单独配置“单文档可见性覆盖”(例如:收紧为仅三权责任人可见,或仅指定角色可见);
- 无法满足“单文档覆盖规则强于工作流默认规则”的严谨层级治理。
3. **关键业务动作缺乏统一权限拦截控制**:
- 发起新研发项目(立项)、指派文档法定三权责任人、配置系统权限等高危操作缺乏严格的角色权限拦截与 UI 状态响应。
---
## 二、 三层正交解耦权限模型体系 (Three-Tier Orthogonal Model)
为彻底解决上述矛盾,系统确立 **“全局动态角色 (Global RBAC) + 项目法定三权 (Project-Scoped Duties) + 单文档资源覆盖 (Doc-Level Visibility Override)”** 的三层正交解耦架构:
```
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ 第一层:全局角色与权限库 (Global RBAC) │
│ • 实体:RoleDefinition (支持动态 CRUD 增删改查) │
│ • 职能:用户全局绑定唯一角色,赋予默认功能权限集 (创建项目、管理权限、指派负责人等) │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
│ 作用于项目与流程协作
┌───────────────────────────────────────────▼────────────────────────────────────────────┐
│ 第二层:项目法定三权分立 (Project-Scoped Duties) │
│ • 实体:DocPermissionRole (编制人 Author / 审核人 Reviewer / 批准人 Approver) │
│ • 职能:跟随具体项目与受控流转状态机(认领、就地编辑、送审、审核驳回、终审盖章锁定) │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
│ 作用于交付物资源访问
┌───────────────────────────────────────────▼────────────────────────────────────────────┐
│ 第三层:交付物可见性继承与单文档覆盖 (Visibility & Override) │
│ • 工作流默认策略 (Workflow Baseline): 阶段/工作流内文档的基线可见范围 (workflow:view_all) │
│ • 单文档覆盖策略 (Doc-level Override): 独立策略覆盖工作流基线(收紧或放宽) │
└────────────────────────────────────────────────────────────────────────────────────────┘
```
---
## 三、 数据模型与接口契约设计 (Data Contracts & Models)
在 `web/src/types/rbac.ts` 中确立核心类型定义,并与 `web/src/types/docgov.ts`、`web/src/types/workbench.ts` 保持向下兼容与解耦。
### 1. 原子功能权限项 (`PermissionKey`)
```typescript
export type PermissionKey =
| 'project:create' // 创建新项目/立项推演
| 'project:assign_lead' // 设置/变更文档责任人(编制/审核/批准)
| 'perm:manage' // 系统权限与角色管理配置 (进入管理中心增删改角色)
| 'workflow:config_visibility' // 配置工作流默认可见性基线
| 'doc:override_visibility' // 配置单文档可见性覆盖策略
| 'doc:export' // 导出受控交付物 (DOCX/XLSX)
| 'workflow:view_all'; // 默认查阅常规工作流文档
```
### 2. 全局动态角色定义 (`RoleDefinition`)
```typescript
export interface RoleDefinition {
id: string; // 唯一标识:如 'role-admin', 'role-director', 'role-custom-qa'
name: string; // 显示名称:如 "系统管理员", "研发总监", "方案工程师"
code: string; // 唯一代码:如 "ADMIN", "DIRECTOR", "ENGINEER"
description: string; // 职责描述
isSystem?: boolean; // 系统内置防死锁标记 (内置管理员角色不可删除)
permissions: PermissionKey[]; // 默认拥有的全局权限点列表
createdAt: string; // 创建时间
updatedAt: string; // 更新时间
}
```
### 3. 用户全局属性扩展 (`UserProfile`)
```typescript
export interface UserProfile {
id: number;
name: string;
employeeId: string;
department: string;
position: string; // 岗位职称 (如 "资深医疗器械方案工程师")
roleId: string; // 关联的全局角色 ID (全局唯一)
customPermissions?: PermissionKey[]; // 用户个人级特例微调权限 (可选)
projectPermissions?: Record<string, DocPermissionRole>; // 项目内法定职责记录 (docId -> role)
}
```
### 4. 单文档可见性覆盖规则 (`DocVisibilityRule`)
受控交付物实体 `DeliverableItem` 扩展 `visibilityRule` 可选配置项:
```typescript
export type VisibilityMode =
| 'inherit' // 默认:继承工作流/阶段默认可见性
| 'role_whitelist' // 覆盖:仅允许特定全局角色可见 (如仅总监、质保QA)
| 'designated_only' // 覆盖:严格收紧,仅该文档当前的三权责任人可见
| 'public'; // 覆盖:放宽,所有成员乃至访客均可查阅
export interface DocVisibilityRule {
mode: VisibilityMode;
allowedRoleIds?: string[]; // 当 mode === 'role_whitelist' 时生效
allowedUserIds?: number[]; // 特例用户白名单 (例如外聘临床专家工号)
overrideReason?: string; // 覆盖原因说明 (质量合规留痕审计)
configuredBy?: string; // 设置人姓名
configuredAt?: string; // 设置时间
}
export interface DeliverableItem {
// ...既有字段 (docId, projectId, title, stage, category, author, reviewer, approver 等)
visibilityRule?: DocVisibilityRule; // 单文档可见性覆盖规则
}
```
---
## 四、 权限判定决策引擎设计 (Permission Engine & Pipeline)
在 `web/src/engine/rbac.ts` 中实现高内聚、无副作用的纯函数判定引擎。
### 1. 全局功能权限判定 (`hasPermission`)
```typescript
export function hasPermission(
user: UserProfile,
roles: RoleDefinition[],
permKey: PermissionKey
): boolean {
const role = roles.find((r) => r.id === user.roleId);
if (!role) return false;
// 超级管理员或具备权限管理特权者通配放行
if (role.code === 'ADMIN' || role.permissions.includes('perm:manage')) {
return true;
}
// 个人特例微调权限优先
if (user.customPermissions?.includes(permKey)) {
return true;
}
return role.permissions.includes(permKey);
}
```
### 2. 文档可见性 5 步决策流水线 (`isDeliverableVisible`)
严格遵循短路求值(Short-circuit Evaluation),解决工作流基线与单文档覆盖的层级冲突:
```
[用户请求访问交付物]
│
▼
[步骤 1: 个人私密隔离检查]
文档 category === 'private'? ──(是)──> 用户是否为创建者 (creatorId === user.id)? ──(否)──> 🚫 隐藏/拒绝
│ (否) │ (是)
│ ▼
│ ✅ 允许查阅
▼
[步骤 2: 管理员审计特权]
用户是否拥有 perm:manage 或 ADMIN 角色? ──(是)──> ✅ 允许查阅
│ (否)
▼
[步骤 3: 法定三权责任人保底]
用户是否为该文档的编制人/审核人/批准人? ──(是)──> ✅ 允许查阅 (防业务断档)
│ (否)
▼
[步骤 4: 单文档覆盖策略判定 (Override Priority)]
文档是否存在 visibilityRule 且 mode !== 'inherit'?
├─ 'designated_only' ──> 🚫 拒绝查阅 (步骤3已确认当前用户非责任人)
├─ 'public' ──────────> ✅ 允许查阅
├─ 'role_whitelist' ──> 当前用户全局角色是否在 allowedRoleIds 中? ──(是)──> ✅ / (否)──> 🚫
│
▼ (若 mode 为 'inherit' 或未显式配置)
[步骤 5: 工作流基线继承 (Workflow Baseline)]
回退继承工作流基线:用户角色是否具备 workflow:view_all 权限? ──(是)──> ✅ / (否)──> 🚫
```
### 3. 业务动作权限判定 (`canPerformDocAction`)
- `project:create`:必须通过 `hasPermission(user, roles, 'project:create')` 校验;
- `project:assign_lead`:必须通过 `hasPermission(user, roles, 'project:assign_lead')` 校验;
- `doc:override_visibility`:必须通过 `hasPermission(user, roles, 'doc:override_visibility')` 校验。
---
## 五、 最小可测试框架与界面设计 (UI & Testing Touchpoints)
为确保能够立即测试和实际应用,最小框架闭环落实以下四大触点:
### 1. 动态角色管理控制台 (`SettingsModal` 升级)
- **入口**:点击左下角系统设置齿轮图标打开;
- **动态角色 CRUD**:
- 左侧展示系统所有角色列表(支持展示系统角色徽章 `SYSTEM` 与普通角色);
- “+ 新建角色”按钮,支持输入角色名称、代码和描述;
- 支持删除非系统内置角色(带有确认弹框);
- **权限配置矩阵**:
- 右侧呈现 7 项原子权限开关/复选框;
- 支持一键为当前选中的角色勾选/反选对应权限;
- **用户角色委派与模拟切换 (Quick Switch & Test)**:
- 支持将张工、李主管、王总监快速绑定到指定全局角色;
- 界面提供用户一键切换工具,立刻直观感受不同身份下的权限差异;
- **持久化**:角色库与用户角色绑定状态通过 `localStorage` 自动持久化存储。
### 2. 单文档可见性覆盖配置弹窗 (`DocVisibilityModal`)
- **入口**:在受控交付物详情头栏、大盘右侧或抽屉卡片上,点击【🔒 权限覆盖】图标;
- **权限守卫**:若当前用户无 `doc:override_visibility` 权限,该按钮置灰或隐藏;
- **覆盖模式选择器**:
- 单选:`继承工作流默认` / `仅三权责任人可见` / `指定角色白名单` / `全员公开`;
- 当选择“指定角色白名单”时,列出动态角色多选列表供勾选;
- 附带“覆盖原因”输入框(合规审计说明);
- **生效反馈**:保存后文档立即绑定 `visibilityRule`,交付物大盘与目录即刻重算可见性。
### 3. 核心业务动作受控联动拦截 (Realtime Interception)
- **创建项目受控**:
- 顶部导航栏的【+ 新建项目】按钮,无 `project:create` 权限时置灰禁用,鼠标悬停提示:“当前角色 [xxx] 无权发起新研发项目”;
- **设置文档负责人受控**:
- 用户项目权限弹窗与文档详情的三权责任人下拉框,无 `project:assign_lead` 权限时锁定只读;
- **文档可见性实时隐藏联动**:
- 当任一文档被配置为覆盖模式(如“仅研发总监可见”),切换登录人至“方案工程师”后,该文档在左侧目录树、交付物抽屉大盘中完全消失,不可点击访问。
---
## 六、 自动化测试套件与质量验证方案 (Test Plan & Verification)
遵循仓库质量规范与 `test-reports-standard.mdc` 要求,测试分为单元测试矩阵与端到端实测验证:
### 1. 自动化单元测试矩阵 (`web/src/engine/rbac.test.ts`)
- **用例 1 (角色 CRUD 与默认权限绑定)**:验证角色动态添加、编辑、权限分配与持久化序列化;
- **用例 2 (系统管理员特权)**:验证 ADMIN 角色及具备 `perm:manage` 权限者的全局通配放行;
- **用例 3 (工作流基线查阅权)**:验证具备 `workflow:view_all` 与无该权限的访客的基线过滤行为;
- **用例 4 (单文档覆盖 - designated_only)**:验证仅编制/审核/批准人可见,其他项目成员被精确拦截;
- **用例 5 (单文档覆盖 - role_whitelist)**:验证仅白名单内角色(如总监)可见,其他角色被精确拦截;
- **用例 6 (单文档覆盖 - public)**:验证无 `workflow:view_all` 权限的普通访客在公开单文档上成功查阅;
- **用例 7 (私密文档隔离强校验)**:验证即使具有超级权限或角色白名单,非创建者的 private 文档绝对不可见;
- **用例 8 (核心动作权限拦截)**:验证 `project:create` 与 `project:assign_lead` 的判定契约。
### 2. 测试报告归档
所有测试结果必须归档于:
`.doc/test-reports/2026-09-08-dynamic-roles-and-doc-visibility-rbac-test-report.md`
---
## 七、 实施与渐进式提交计划 (Progressive Commits)
严格遵循仓库 Conventional Commits 与渐进式提交铁律:
1. `feat(rbac)`: 增加 RBAC 数据模型契约与权限判定引擎纯函数 (`rbac.ts`, `rbac.test.ts`)
2. `feat(web)`: 升级 `SettingsModal` 实现动态角色增删改与权限配置面板
3. `feat(web)`: 新增 `DocVisibilityModal` 实现单文档可见性覆盖配置与大盘联动
4. `feat(web)`: 联动「新建项目」与「指派负责人」动作权限拦截控制
5. `test(rbac)`: 运行全量测试套件并归档自动化测试报告
6. `docs(spec)`: 归档本设计规范文档并同步关联引用