Files
Mdeical_Sur_Report/docs/permissions.md
admin 014aca8619 Initialize backendized SurClaw report system
- Add React/Vite frontend for login, dashboard, reports, templates, users, settings, AI, speech, and media workflows.

- Add NestJS/Prisma/PostgreSQL backend with auth, dashboard stats, reports, templates, users, departments, settings, files, AI, speech, audit logs, and HTML sanitization.

- Add Prisma schema, migrations, seed data, persistent app sessions, Docker/Nginx deployment files, and upload volume configuration.

- Add Vitest, Playwright, backend integration tests, and project documentation for requirements, design, permissions, API contracts, testing, deployment, security, and progress.

- Configure production local fallback switch and remove unused Gemini direct dependency/env wiring.
2026-05-02 01:41:57 +08:00

11 KiB
Raw Blame History

权限设计

本文档描述后端化后的目标权限模型。当前版本登录认证已接入后端,但角色和部分页面级过滤仍主要在前端执行,不能作为生产安全边界;后端化后必须由服务端统一鉴权和授权。

已确定规则

  • 超级管理员拥有全权限,可以查看和修改系统内任何数据。
  • 超级管理员默认属于 admin 部门,但查询、管理和授权不受部门限制。
  • 管理员只能查看、编辑和删除本部门报告。
  • 医生默认只能查看、编辑和删除本人报告。
  • 医生完成报告后仍允许修改,也允许删除本人已完成报告。
  • 完成报告后的每次修改都需要增加修订版本号,方便医疗文书追踪。
  • 模板按部门授权。
  • 管理员可以修改本部门模板,也可以使用被授权模板。
  • 医生不可以直接修改部门模板,但可以复制/新建自己的模板并修改。
  • 只有超级管理员能创建或授权管理员。
  • 一个部门只能有一个管理员。
  • 不设置患者维度权限。
  • 部门之间不存在上级/下级关系。
  • 不需要临时授权或会诊授权。
  • 不允许同一用户属于多个部门。
  • AI 代理只能接收当前报告内容作为上下文,不能读取跨部门报告。
  • 报告导出不需要水印、导出原因、审批或专门导出审计。
  • 前端菜单隐藏只是体验优化,所有权限必须在后端 API 层强校验。

角色定义

角色 代码建议 权限定位
超级管理员 super 系统最高权限,跨部门、跨模板、跨用户管理。
管理员 admin 部门级管理者,只管理本部门业务数据;每个部门最多一个管理员。
医生 doctor 或沿用 user 普通报告创建者,主要管理本人报告,可复制或新建个人模板。

当前前端代码使用 user 表示医生。后端化时可以继续沿用 user,也可以迁移为更清晰的 doctor。如果迁移,需要同步前端类型、接口返回和历史数据。

数据边界

后端数据至少需要以下边界字段:

  • tenant_id:医院或部署实例。单医院也建议预留。
  • department_id:科室。
  • user_id:用户。
  • role:用户角色。

报告、模板、用户、文件、操作日志都应带上 tenant_id。报告必须带 department_id。模板可以带拥有部门,也可以通过授权表关联部门。

组织规则:

  • 每个用户只能属于一个部门。
  • 超级管理员默认部门为 admin
  • 部门没有上下级层级。
  • 一个部门最多一个管理员,后端创建/修改管理员时必须校验唯一性。

报告权限

查看报告

角色 规则
超级管理员 可查看所有报告。
管理员 只能查看本部门报告。
医生 只能查看本人报告。

建议后端查询规则:

super:  WHERE tenant_id = current.tenant_id
admin:  WHERE tenant_id = current.tenant_id AND department_id = current.department_id
doctor: WHERE tenant_id = current.tenant_id AND author_id = current.user_id

新建报告

角色 规则
超级管理员 可为任意部门创建报告,默认部门为 admin,也可在表单中选择目标部门。
管理员 可在本部门创建报告。
医生 可为自己创建报告,部门取当前用户部门。

建议新建报告时由后端写入 author_iddepartment_idtenant_id,不要完全信任前端传入。

编辑报告

角色 规则
超级管理员 可编辑任何报告。
管理员 可编辑本部门报告。
医生 可编辑本人报告,包括已完成报告。

完成报告后仍允许修改。后端必须:

  • 每次保存创建 report_histories 记录。
  • 已完成报告每次修改递增修订版本号。
  • 记录修改人、修改时间、修改动作和旧版本内容或旧版本引用。

删除报告

角色 规则
超级管理员 可删除任何报告。
管理员 可删除本部门报告,包括已完成报告。
医生 可删除本人报告,包括已完成报告。

实现建议:

  • 后端可以先做软删除,保留 deleted_atdeleted_by,避免误删后无法恢复。
  • 如果未来接入正式病历归档流程,再考虑把“删除”改为“作废/归档”。

导出报告

角色 规则
超级管理员 可导出所有报告。
管理员 可导出本部门报告。
医生 可导出本人报告。

当前确定:报告导出不需要水印、导出原因、审批或专门导出审计。

模板权限

已确定:模板按部门授权。

建议数据模型:

  • templates:模板主体。
  • departments:部门。
  • template_department_permissions:模板与部门授权关系。
  • user_templates 或在 templates 中增加 owner_user_id:医生复制/新建的个人模板。

建议权限规则:

角色 查看/使用模板 管理模板
超级管理员 全部模板 全部模板,可授权给部门。
管理员 本部门模板和被授权模板 可修改本部门模板,可使用被授权模板。
医生 本部门被授权模板、自己的个人模板 不可修改部门模板;可复制/新建并修改自己的个人模板。

新建报告时,后端必须校验当前用户是否有权使用该模板。

模板授权粒度建议:

  • 部门授权模板用于“部门可见/可使用”。
  • 模板归属部门用于判断管理员是否可以管理。
  • 医生个人模板只归属创建医生本人,不自动成为部门模板。

用户权限

角色 用户管理权限
超级管理员 创建、编辑、禁用、删除所有用户,分配部门和角色,创建或授权管理员。
管理员 管理本部门医生;不能创建管理员;不能跨部门管理用户。
医生 只能查看和修改自己的基础资料,密码修改走单独接口。

管理员规则:

  • 只有超级管理员能创建或授权管理员。
  • 一个部门只能有一个管理员。
  • 管理员不能创建超级管理员。

系统设置权限

设置项 超级管理员 管理员 医生
AI Provider 和密钥 可管理 不可管理 不可管理
讯飞语音密钥 可管理 不可管理 不可管理
全局抽帧策略 可管理 不可管理 不可管理
部门默认模板 可管理全部部门 可管理本部门 不可管理
个人默认模板 可配置自己默认值 可配置自己默认值 可配置自己默认值

建议把设置拆为:

  • 全局设置:超级管理员维护。
  • 部门设置:超级管理员或本部门管理员维护。
  • 用户偏好:每个用户自己维护。

文件权限

文件包括签名、模板图片、报告图片、视频、关键帧、导出文件。

建议规则:

  • 签名文件:用户本人、本部门管理员、超级管理员可访问。
  • 报告相关文件:继承报告权限。
  • 模板图片:继承模板权限。
  • 视频文件:继承报告权限,且建议限制下载或设置过期访问 URL。
  • 导出文件:继承报告导出权限;不要求专门导出审计。

操作记录与历史

虽然报告导出不需要专门审计,但以下写操作仍建议记录基础操作日志,便于排查和追踪:

  • 登录成功/失败。
  • 新建、保存、完成、修改已完成报告。
  • 删除报告。
  • 新建、修改、删除模板。
  • 模板部门授权变更。
  • 新建、禁用、删除、改角色用户。
  • 修改 AI/语音密钥。
  • 修改系统设置。

报告历史是业务必需项:

  • 报告每次保存保留历史版本。
  • 已完成报告每次修改递增修订版本号。
  • 历史记录应包含修改人、修改时间、修改动作、旧内容或旧内容引用。

日志建议包含:

  • tenant_id
  • actor_user_id
  • actor_role
  • action
  • target_type
  • target_id
  • department_id
  • ip
  • user_agent
  • created_at
  • metadata

敏感病历正文和完整密钥不应写入普通日志;报告正文版本应放在报告历史表或对象存储中。

AI 权限

AI 代理只能接收当前报告内容作为上下文:

  • 不允许读取跨部门报告。
  • 不允许自动检索其他报告作为上下文。
  • 不需要患者维度权限。
  • AI 请求由后端代理发出,前端不接触真实 API Key。

如果用户在当前报告中选择了图片、关键帧或正文片段,这些内容必须先通过当前报告权限校验。

API 权限落点

后端每个接口都要做权限校验。建议先在服务层写统一 guard/policy

  • canViewReport(user, report)
  • canCreateReport(user, departmentId)
  • canEditReport(user, report)
  • canDeleteReport(user, report)
  • canExportReport(user, report)
  • canUseTemplate(user, template)
  • canManageTemplate(user, template)
  • canCreatePersonalTemplate(user)
  • canManageUser(actor, targetUser)
  • canCreateAdmin(actor, departmentId)
  • canManageSettings(user, scope, departmentId?)

列表接口不能只在前端过滤,必须在数据库查询条件中限制可见范围。

已关闭问题

以下问题已经确认,不再作为阻塞项:

问题 结论
管理员是否可以编辑本部门医生创建的报告? 可以。
管理员是否可以删除本部门已完成报告? 可以。
医生是否可以删除本人已完成报告? 可以。
管理员是否可以创建其他管理员? 不可以,只有超级管理员能创建/授权管理员。
一个部门是否只能有一个管理员? 是。
管理员是否可以管理本部门模板内容? 可以修改本部门模板,也可以使用被授权模板。
模板授权粒度如何处理? 部门模板按部门授权;医生不可改部门模板,但可复制/新建个人模板。
超级管理员是否属于某个部门? 默认属于 admin 部门。
是否需要患者维度权限? 不需要。
报告完成后修改是否需要修订版本号? 需要。
报告导出是否需要水印、原因、审批或专门审计? 不需要。
AI 能否读取跨部门报告作为上下文? 不能,只能接收当前报告内容。
部门是否有上下级关系? 没有。
是否需要临时授权或会诊授权? 不需要。
是否允许同一用户属于多个部门? 不允许。

后续实现注意

  • 数据库应对“一个部门一个管理员”设置唯一约束或事务校验。
  • 报告列表、模板列表、用户列表必须在 SQL 查询层过滤权限。
  • 医生个人模板和部门模板需要在数据模型上区分。
  • 已完成报告的修改需要版本号和历史记录,不应只覆盖最新内容。
  • 删除报告建议先做软删除,后续如有病历归档要求再调整为作废流程。