# 权限设计 本文档描述后端化后的目标权限模型。当前版本登录认证已接入后端,但角色和部分页面级过滤仍主要在前端执行,不能作为生产安全边界;后端化后必须由服务端统一鉴权和授权。 ## 已确定规则 - 超级管理员拥有全权限,可以查看和修改系统内任何数据。 - 超级管理员默认属于 `admin` 部门,但查询、管理和授权不受部门限制。 - 管理员只能查看、编辑和删除本部门报告。 - 医生默认只能查看、编辑和删除本人报告。 - 医生完成报告后仍允许修改,也允许删除本人已完成报告。 - 完成报告后的每次修改都需要增加修订版本号,方便医疗文书追踪。 - 模板按部门授权。 - 管理员可以修改本部门模板,也可以使用被授权模板。 - 医生不可以直接修改部门模板,但可以复制/新建自己的模板并修改。 - 只有超级管理员能创建或授权管理员。 - 一个部门只能有一个管理员。 - 不设置患者维度权限。 - 部门之间不存在上级/下级关系。 - 不需要临时授权或会诊授权。 - 不允许同一用户属于多个部门。 - AI 代理只能接收当前报告内容作为上下文,不能读取跨部门报告。 - 报告导出不需要水印、导出原因、审批或专门导出审计。 - 前端菜单隐藏只是体验优化,所有权限必须在后端 API 层强校验。 ## 角色定义 | 角色 | 代码建议 | 权限定位 | | --- | --- | --- | | 超级管理员 | `super` | 系统最高权限,跨部门、跨模板、跨用户管理。 | | 管理员 | `admin` | 部门级管理者,只管理本部门业务数据;每个部门最多一个管理员。 | | 医生 | `doctor` 或沿用 `user` | 普通报告创建者,主要管理本人报告,可复制或新建个人模板。 | 当前前端代码使用 `user` 表示医生。后端化时可以继续沿用 `user`,也可以迁移为更清晰的 `doctor`。如果迁移,需要同步前端类型、接口返回和历史数据。 ## 数据边界 后端数据至少需要以下边界字段: - `tenant_id`:医院或部署实例。单医院也建议预留。 - `department_id`:科室。 - `user_id`:用户。 - `role`:用户角色。 报告、模板、用户、文件、操作日志都应带上 `tenant_id`。报告必须带 `department_id`。模板可以带拥有部门,也可以通过授权表关联部门。 组织规则: - 每个用户只能属于一个部门。 - 超级管理员默认部门为 `admin`。 - 部门没有上下级层级。 - 一个部门最多一个管理员,后端创建/修改管理员时必须校验唯一性。 ## 报告权限 ### 查看报告 | 角色 | 规则 | | --- | --- | | 超级管理员 | 可查看所有报告。 | | 管理员 | 只能查看本部门报告。 | | 医生 | 只能查看本人报告。 | 建议后端查询规则: ```text 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_id`、`department_id`、`tenant_id`,不要完全信任前端传入。 ### 编辑报告 | 角色 | 规则 | | --- | --- | | 超级管理员 | 可编辑任何报告。 | | 管理员 | 可编辑本部门报告。 | | 医生 | 可编辑本人报告,包括已完成报告。 | 完成报告后仍允许修改。后端必须: - 每次保存创建 `report_histories` 记录。 - 已完成报告每次修改递增修订版本号。 - 记录修改人、修改时间、修改动作和旧版本内容或旧版本引用。 ### 删除报告 | 角色 | 规则 | | --- | --- | | 超级管理员 | 可删除任何报告。 | | 管理员 | 可删除本部门报告,包括已完成报告。 | | 医生 | 可删除本人报告,包括已完成报告。 | 实现建议: - 后端可以先做软删除,保留 `deleted_at`、`deleted_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 查询层过滤权限。 - 医生个人模板和部门模板需要在数据模型上区分。 - 已完成报告的修改需要版本号和历史记录,不应只覆盖最新内容。 - 删除报告建议先做软删除,后续如有病历归档要求再调整为作废流程。