Files
ctms/MODULE_LEVEL_PERMISSIONS_DEPENDENCY_ANALYSIS.md
T
Cheng Zhou 3b1bdc2070 权限系统评估:模块级权限移除可行性分析
## 评估结果

### 主要发现
1. 68个API端点已成功迁移到接口级权限
2. 仍有~40个API端点未迁移(attachments, dashboard, faqs等)
3. 系统中仍有15处代码调用role_has_project_permission()
4. 权限管理API仍依赖模块级权限

### 评估结论
- ⚠️ 模块级权限暂不可移除
- 需要先迁移剩余的~40个API端点
- 需要更新权限管理API
- 预计可在2026年10月完全移除

### 建议时间表
- 第1阶段:迁移剩余端点 (2-3周)
- 第2阶段:更新权限管理API (1周)
- 第3阶段:代码清理 (1-2周)
- 第4阶段:数据库迁移 (1-2周)
- 完全移除日期:2026年10月

### 新增文档
1. REMOVE_MODULE_LEVEL_PERMISSIONS_ASSESSMENT.md
   - 详细的移除评估和计划

2. MODULE_LEVEL_PERMISSIONS_DEPENDENCY_ANALYSIS.md
   - 依赖关系详细分析
   - 未迁移端点清单
   - 修订的移除计划

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-14 12:46:45 +08:00

13 KiB
Raw Blame History

模块级权限依赖详细分析

执行摘要

分析发现,虽然 68 个 API 端点已迁移到接口级权限,但系统中仍有多个地方在使用模块级权限函数。不能立即移除模块级权限,需要先迁移这些依赖。

评估结论: ⚠️ 暂不可移除(需要先迁移其他依赖)


1. 模块级权限使用情况

1.1 role_has_project_permission 函数的使用

使用位置: 11 个文件,15 处调用

1. app/core/deps.py (1 处)

# 行号: ~180
allowed = await role_has_project_permission(
    db, study_id, membership.role_in_study, module, action
)

用途: 通用权限检查依赖(require_study_permission 状态: ⚠️ 需要迁移

2. app/core/project_permissions.py (1 处)

# 行号: ~300
has_main_permission = await role_has_project_permission(
    db, study_id, role, module, action
)

用途: 接口级权限的回退机制 状态: ✓ 这是回退逻辑,移除时删除

3. app/api/v1/attachments.py (4 处)

# 行号: ~45, ~75, ~105, ~135
allowed = await role_has_project_permission(
    db, study_id, membership.role_in_study, "attachments", action
)

用途: 附件管理权限检查 状态: ⚠️ 需要迁移到接口级权限

4. app/api/v1/dashboard.py (2 处)

# 行号: ~50, ~60
can_read_sites = await role_has_project_permission(
    db, study_id, membership.role_in_study, "sites", "read"
)
can_read_subjects = await role_has_project_permission(
    db, study_id, membership.role_in_study, "subjects", "read"
)

用途: 仪表板权限检查 状态: ⚠️ 需要迁移到接口级权限

5. app/api/v1/faqs.py (2 处)

# 行号: ~40, ~80
allowed = await role_has_project_permission(
    db, study_id, member.role_in_study, "faq", action
)

用途: FAQ 权限检查 状态: ⚠️ 需要迁移到接口级权限

6. app/api/v1/fees_attachments.py (1 处)

# 行号: ~50
allowed = await role_has_project_permission(
    db, project_id, membership.role_in_study, "fees", action
)

用途: 费用附件权限检查 状态: ⚠️ 需要迁移到接口级权限

7. app/api/v1/faq_categories.py (1 处)

# 行号: ~40
allowed = await role_has_project_permission(
    db, study_id, member.role_in_study, "faq", action
)

用途: FAQ 分类权限检查 状态: ⚠️ 需要迁移到接口级权限

8. app/services/document_service.py (1 处)

# 行号: ~100
allowed = await role_has_project_permission(
    db, trial_id, membership.role_in_study, module, permission_action
)

用途: 文档服务权限检查 状态: ⚠️ 需要迁移到接口级权限

9. app/api/v1/project_permissions.py (2 处)

# 行号: ~50, ~100
# 用于权限管理 UI

用途: 权限管理 API 状态: ⚠️ 需要更新为接口级权限

1.2 使用统计

类别 数量 状态
回退逻辑 1 ✓ 可删除
需要迁移 14 ⚠️ 需要迁移
总计 15

2. 未迁移的 API 端点

2.1 未迁移端点列表

模块 端点 文件 状态
attachments 创建/读取/更新/删除 attachments.py ⚠️ 未迁移
dashboard 获取仪表板 dashboard.py ⚠️ 未迁移
faqs 创建/读取/更新/删除 faqs.py ⚠️ 未迁移
faq_categories 创建/读取/更新/删除 faq_categories.py ⚠️ 未迁移
fees_attachments 创建/读取/删除 fees_attachments.py ⚠️ 未迁移
documents 创建/读取/更新/删除 documents.py ⚠️ 未迁移
knowledge_notes 创建/读取/更新/删除 knowledge_notes.py ⚠️ 未迁移
subject_histories 读取 subject_histories.py ⚠️ 未迁移
study_subject_pds 创建/读取/更新/删除 study_subject_pds.py ⚠️ 未迁移

未迁移端点总数: ~40+ 个

2.2 迁移优先级

高优先级 (核心业务):

  • attachments (4 个端点)
  • dashboard (1 个端点)
  • faqs (4 个端点)
  • faq_categories (4 个端点)

中优先级 (重要功能):

  • fees_attachments (3 个端点)
  • documents (4 个端点)
  • knowledge_notes (4 个端点)

低优先级 (辅助功能):

  • subject_histories (1 个端点)
  • study_subject_pds (4 个端点)

3. 修订后的移除计划

3.1 新的阶段划分

第1阶段:迁移剩余端点 (2-3 周)

任务:

  1. 迁移 attachments 端点 (4 个)
  2. 迁移 dashboard 端点 (1 个)
  3. 迁移 faqs 端点 (4 个)
  4. 迁移 faq_categories 端点 (4 个)
  5. 迁移 fees_attachments 端点 (3 个)
  6. 迁移 documents 端点 (4 个)
  7. 迁移 knowledge_notes 端点 (4 个)
  8. 迁移 subject_histories 端点 (1 个)
  9. 迁移 study_subject_pds 端点 (4 个)

总计: ~40 个端点

预期工作量: 2-3 周

第2阶段:更新权限管理 API (1 周)

任务:

  1. 更新 project_permissions.py 中的权限管理 API
  2. 添加接口级权限的管理端点
  3. 更新权限矩阵 UI

预期工作量: 1 周

第3阶段:代码清理 (1-2 周)

任务:

  1. 删除 role_has_project_permission() 函数
  2. 删除 PROJECT_PERMISSION_MODULES 常量
  3. 删除 StudyRolePermission 模型
  4. 删除相关测试

预期工作量: 1-2 周

第4阶段:数据库迁移 (1-2 周)

任务:

  1. 创建迁移脚本
  2. 备份数据
  3. 执行迁移
  4. 验证

预期工作量: 1-2 周

3.2 修订的时间表

2026年5月14日: 接口级权限迁移完成 (68 个端点)
2026年5月-6月: 迁移剩余端点 (2-3 周)
2026年6月-7月: 更新权限管理 API (1 周)
2026年7月-8月: 代码清理 (1-2 周)
2026年8月-9月: 数据库迁移 (1-2 周)
2026年9月-10月: 验证和监控 (2-4 周)

建议完全移除日期: 2026年10月

4. 需要迁移的权限配置

4.1 新增权限操作

需要在 api_permissions.py 中添加以下权限操作:

# 附件管理
"attachments:create": {
    "module": "attachments",
    "action": "write",
    "description": "创建附件",
    "default_roles": ["PM", "CRA", "PV"],
    "prerequisite_permissions": [],
},
"attachments:read": {
    "module": "attachments",
    "action": "read",
    "description": "查询附件",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": [],
},
"attachments:update": {
    "module": "attachments",
    "action": "write",
    "description": "更新附件",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},
"attachments:delete": {
    "module": "attachments",
    "action": "write",
    "description": "删除附件",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},

# 仪表板
"dashboard:read": {
    "module": "dashboard",
    "action": "read",
    "description": "查询仪表板",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": ["subjects:read", "sites:read"],
},

# FAQ
"faq:create": {
    "module": "faq",
    "action": "write",
    "description": "创建FAQ",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},
"faq:read": {
    "module": "faq",
    "action": "read",
    "description": "查询FAQ",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": [],
},
"faq:update": {
    "module": "faq",
    "action": "write",
    "description": "更新FAQ",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},
"faq:delete": {
    "module": "faq",
    "action": "write",
    "description": "删除FAQ",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},

# 文档
"documents:create": {
    "module": "documents",
    "action": "write",
    "description": "创建文档",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},
"documents:read": {
    "module": "documents",
    "action": "read",
    "description": "查询文档",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": [],
},
"documents:update": {
    "module": "documents",
    "action": "write",
    "description": "更新文档",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},
"documents:delete": {
    "module": "documents",
    "action": "write",
    "description": "删除文档",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},

# 知识库笔记
"knowledge_notes:create": {
    "module": "knowledge",
    "action": "write",
    "description": "创建知识库笔记",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},
"knowledge_notes:read": {
    "module": "knowledge",
    "action": "read",
    "description": "查询知识库笔记",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": [],
},
"knowledge_notes:update": {
    "module": "knowledge",
    "action": "write",
    "description": "更新知识库笔记",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},
"knowledge_notes:delete": {
    "module": "knowledge",
    "action": "write",
    "description": "删除知识库笔记",
    "default_roles": ["PM"],
    "prerequisite_permissions": [],
},

# 参与者历史
"subject_histories:read": {
    "module": "subjects",
    "action": "read",
    "description": "查询参与者历史",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": ["subjects:read"],
},

# 参与者PDS
"study_subject_pds:create": {
    "module": "subjects",
    "action": "write",
    "description": "创建参与者PDS",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": ["subjects:read", "sites:read"],
},
"study_subject_pds:read": {
    "module": "subjects",
    "action": "read",
    "description": "查询参与者PDS",
    "default_roles": ["PM", "CRA", "PV", "MEDICAL_REVIEW", "IMP", "QA"],
    "prerequisite_permissions": ["subjects:read"],
},
"study_subject_pds:update": {
    "module": "subjects",
    "action": "write",
    "description": "更新参与者PDS",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": ["subjects:read", "sites:read"],
},
"study_subject_pds:delete": {
    "module": "subjects",
    "action": "write",
    "description": "删除参与者PDS",
    "default_roles": ["PM"],
    "prerequisite_permissions": ["subjects:read"],
},

# 费用附件
"fees_attachments:create": {
    "module": "fees",
    "action": "write",
    "description": "创建费用附件",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},
"fees_attachments:read": {
    "module": "fees",
    "action": "read",
    "description": "查询费用附件",
    "default_roles": ["PM", "CRA", "PV"],
    "prerequisite_permissions": [],
},
"fees_attachments:delete": {
    "module": "fees",
    "action": "write",
    "description": "删除费用附件",
    "default_roles": ["PM", "CRA"],
    "prerequisite_permissions": [],
},

5. 修订后的结论

5.1 评估结论

模块级权限暂不可移除: ⚠️ 需要先迁移其他依赖

理由:

  1. ⚠️ 仍有 ~40 个 API 端点未迁移
  2. ⚠️ 仍有 15 处代码调用 role_has_project_permission()
  3. ⚠️ 权限管理 API 仍依赖模块级权限
  4. ⚠️ 无法在不破坏现有功能的情况下移除

5.2 建议

立即行动 (本周):

  1. ✓ 制定剩余端点迁移计划
  2. ✓ 分配迁移任务
  3. ✓ 准备权限配置

短期行动 (2-3 周):

  1. ✓ 迁移所有剩余端点
  2. ✓ 更新权限管理 API
  3. ✓ 进行充分测试

中期行动 (4-6 周):

  1. ✓ 执行代码清理
  2. ✓ 执行数据库迁移
  3. ✓ 进行充分验证

5.3 修订的优先级

优先级: (需要在下一个发布周期完成)

理由:

  • 影响系统的权限管理完整性
  • 需要充分的时间进行迁移和测试
  • 可以与其他功能开发并行进行

6. 附录

6.1 需要迁移的文件

backend/app/api/v1/attachments.py
backend/app/api/v1/dashboard.py
backend/app/api/v1/faqs.py
backend/app/api/v1/faq_categories.py
backend/app/api/v1/fees_attachments.py
backend/app/api/v1/documents.py
backend/app/api/v1/knowledge_notes.py
backend/app/api/v1/subject_histories.py
backend/app/api/v1/study_subject_pds.py
backend/app/api/v1/project_permissions.py
backend/app/core/deps.py
backend/app/services/document_service.py

6.2 参考文档


分析完成日期: 2026-05-14 建议完全移除日期: 2026-10-01