# 数据范围权限(v0.11) 后台入口:角色与权限 → 数据范围。功能权限决定能执行什么动作,数据范围决定该动作能作用于哪些底座业务记录。 角色的 `data_scopes` 按模块配置,`*` 表示缺省范围。类型:`self`(本人)、`department`(本部门)、`department_tree`(本部门及下级)、`custom`(指定部门,不自动含下级)、`all`(全部)。未配置的新角色和新模块角色模板默认本人。 ```json {"data_scopes":{"*":{"mode":"self"},"reimbursement":{"mode":"custom","department_ids":["finance","sales"]}}} ``` 只有内置系统管理员可配置数据范围、调整既有部门的父部门,并分配非本人范围的角色。功能管理员不能仅凭 roles.manage 提升自己的数据范围。系统管理员范围固定为全部;注册用户角色不提供业务记录权限。API Key 仍只能使用账号实时权限与密钥限权的交集,不能借范围配置绕过功能限权。 管理员通过 POST `/api/admin/roles/{id}/data-scopes` 提交 `{revision,data_scopes}`,遵循既有会话、CSRF、角色权限、API Key 和版本冲突校验。范围修改被审计,立即作用于后续调用,无需重新登录。查看全部的角色不能扩大另一个仅允许本人发布的角色:仅合并授予当前模块及当前动作的角色范围。工作流里的读取还必须同时满足阅读范围和该工作流动作的范围。 ## 记录与模块契约 - `records.list` 在底座中筛选后才返回模块,H5 和导出功能必须继续使用该服务,不能自行读取宿主数据文件。 - 新记录的 `owner_id`、`department_id` 由底座取当前用户身份和部门生成。正文中的同名字段不参与授权;部门调动不改写已经保存的归属部门。 - 修订既有记录时,在 HostRequest 中传入 `record_id`,指向同模块、同集合的原始记录或先前修订。底座检查当前读写范围,并继承原记录归属,不将审核人变成记录所有者。 - 受限范围的 edit/submit/publish/reject 不允许省略 record_id。旧版全部范围模块允许无目标的追加事件以保持兼容;新模块应始终传入真实目标。业务状态、版本冲突、业务编号与记录的对应关系仍由应用后端验证。 - 请求号幂等仍有效;重试也重新检查当前数据范围,不能通过重放旧请求读取已失去访问权的结果。 ```go reply, err := host.Call(modulekit.HostRequest{ Service: "records.create", Collection: "articles", RecordID: originalRecord.ID, // 修改或审核时提供 ActorID: request.ActorID, RequestID: request.RequestID, Payload: revisedValues, }) ``` ## 升级与边界 升级前备份 data 和 modules。首次加载旧库时,旧角色缺省范围显式保留为全部,以避免未经管理员审核即改变现有访问。管理员应在后台逐项收紧。新角色默认本人,与旧角色兼容策略不同。 历史记录缺少归属元数据时,按可信 created_by 回填 owner_id,并取创建者在升级时的部门;无法还原历史调动,未知创建者不推测部门。CMS 修订使用维护脚本 `scripts/migrate-cms-ownership.py` 从带有底座创建审计的原始稿件核对归属,再升级到支持 record_id 的 CMS 0.3.1。 当前范围作用于 `records.*`。组织通讯录、外部云资源连接器有各自授权规则,本次不把它们自动改成部门数据过滤。模块已合法取得的数据仍需正确处理,不应在不同账号之间共享未经隔离的缓存;数据范围也不替代应用自身的状态校验或多租户隔离。