docs(spec): add dynamic roles and doc visibility rbac design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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)`: 归档本设计规范文档并同步关联引用
|
||||
Reference in New Issue
Block a user