角色 API
用途与前置条件
scoped.roles 管理租户 scope 内的角色、层级、手工规则、影响预览和有效权限读取。角色最多有一个父角色。全部 ID 与规则只在当前上下文的完整 scope 内有意义。
我想做什么
签名
输入参数
共享的 MutationOptions、revision、preview token、分页和响应 envelope 见核心与公共合同。以下表只解释角色域字段。
RoleCreateInput
规则与变更输入
分页查询
方法详解:创建与读取
create(input, options?)
- 用途:在当前 scope 创建一个角色;角色 ID 后续用于规则、用户绑定和菜单授权。
- 参数:
input: RoleCreateInput必填;options可传操作者、原因、request/idempotency key。 - 状态影响:新增角色并推进 revision;若指定父角色会立即校验层级与循环。
- 原始返回:
MutationResult<Role>,使用data.id/status/parentId/revision与operationId/auditId。 - 常见失败:
ROLE_ALREADY_EXISTS、ROLE_NOT_FOUND(父角色)、CIRCULAR_INHERITANCE、LIMIT_EXCEEDED。
get(roleId)
- 用途:读取一个角色本身的 label、status、parentId 和 revision,不包含规则。
- 参数:
roleId必填,是当前 scope 内的角色 ID。 - 状态影响:只读。
- 原始返回:
VersionedResult<Role>;后续update/remove使用data.revision作为expectedRevision。 - 区别:读取规则用
getOwnRules/getEffectiveRules,不要从get().data猜权限。
list(query?)
- 用途:为角色列表页分页查询角色。
- 参数:
query可传first/after/status/search/parentId,见上表。 - 状态影响:只读。
- 原始返回:
PageResult<Role>;渲染items,hasNext=true时继续使用endCursor。
update(roleId, patch, options)
- 用途:只修改角色
label/description。 - 参数:
roleId、patch: RoleUpdateInput、options.expectedRevision均必填。 - 状态影响:CAS 更新角色展示字段;不改变 status、parent 或规则。
- 原始返回:
MutationResult<Role>。 - 常见失败:
ROLE_NOT_FOUND、REVISION_CONFLICT;状态/父角色变更应使用下一组 preview/execute。
方法详解:高影响角色变更
previewAccessUpdate(roleId, patch, options?)
- 用途:在改变角色状态或父角色前计算子角色、绑定用户和容量影响。
- 参数:
patch: RoleAccessUpdateInput至少包含status或parentId;preview options 不含 idempotency key。 - 状态影响:只读计划,不提交变更。
- 原始返回:
ImpactPreview<RoleAccessUpdatePlan>;只有executable=true才能取得previewToken/expected。 - 下一步:解决
conflicts,再把同一 patch、token 和 expected 传给executeAccessUpdate。
executeAccessUpdate(roleId, patch, options)
- 用途:提交刚才 preview 的 status/parent 变更。
- 参数:
roleId与patch必须和 preview 一致;options必须含expectedRevisions + previewToken,容量风险时再传确认字段。 - 状态影响:更新角色访问状态/继承,可能影响所有后代和绑定用户,并使相关缓存失效。
- 原始返回:
MutationResult<Role>。 - 常见失败:
PREVIEW_REQUIRED、PREVIEW_STALE、REVISION_CONFLICT、CIRCULAR_INHERITANCE。
getRemovalImpact(roleId)
- 用途:删除前查看子角色、绑定用户、规则和菜单来源是否阻止删除。
- 参数:
roleId必填。 - 状态影响:只读。
- 原始返回:
VersionedResult<RoleRemovalImpact>;先检查data.removable和data.blockers。 - 下一步:解除 blocker 后重新读取 revision,再调用
remove。
remove(roleId, options)
- 用途:删除一个不再被继承、绑定或引用的角色。
- 参数:
roleId与options.expectedRevision必填,revision 来自最新get/getRemovalImpact。 - 状态影响:删除角色并写审计;不会自动替调用方解除业务引用。
- 原始返回:
MutationResult<{ removedRoleId: string }>。 - 常见失败:
ROLE_IN_USE、REVISION_CONFLICT、ROLE_NOT_FOUND。
方法详解:增量修改手工规则
allow(roleId, rule, options?)
- 用途:为角色追加一个手工 allow 来源。
- 参数:
roleId与rule: PermissionRuleInput必填;where只用于数据条件。 - 状态影响:写入/合并语义规则来源,推进 revision 并失效受影响 subject 缓存。
- 原始返回:
MutationResult<PermissionRuleView>;data.semanticKey标识规范化规则,data.sources说明来源。 - 边界:存在匹配 deny 时仍以 deny 为准;allow 不是覆盖 deny。
deny(roleId, rule, options?)
- 用途:追加显式 deny,处理“已有宽泛 allow,但某资源必须拒绝”的情况。
- 参数:与
allow相同,传角色 ID、deny 规则和可选 mutation options。 - 状态影响:写入 deny 来源并失效缓存。
- 原始返回:与
allow相同的MutationResult<PermissionRule>,其中data.effect为deny。 - 选择建议:默认拒绝不需要创建 deny;只有要覆盖现有 allow 时才添加。
revoke(roleId, selector, options?)
- 用途:移除匹配的手工 allow/deny 来源,不删除菜单生成来源。
- 参数:
selector必须精确描述effect/action/resource/where?,或提供semanticKey。 - 状态影响:删除匹配手工来源;若无其他来源,语义规则随之消失。
- 原始返回:
MutationResult<{ removed; remainingCount; remainingDigest }>。 - 注意:
removed=0是 no-op 结果,不表示方法失败。
方法详解:预览并提交规则影响
previewRuleChange(roleId, change, options?)
- 用途:预览单条 allow/deny/revoke 对用户和容量的影响。
- 参数:
change是{ operation: 'allow'|'deny', rule }或{ operation: 'revoke', selector }。 - 状态影响:只读计划。
- 原始返回:
ImpactPreview<ManualRuleChangePlan>;查看plan.sourceOperation判断 insert/delete/noop。 - 下一步:可执行时调用
executeRuleChange,不要改写 change。
executeRuleChange(roleId, change, options)
- 用途:提交已预览的单条规则变更。
- 参数:同一
roleId/change,加expectedRevisions + previewToken。 - 状态影响:原子更新规则、revision、审计和缓存。
- 原始返回:
MutationResult<ManualRuleChangeResult>;allow/deny 返回rule,revoke 返回删除统计。
previewReplaceRules(roleId, rules, options?)
- 用途:管理后台“保存完整规则集合”前计算 insert/update/delete/no-op。
- 参数:
rules: ManualRuleInput[]是目标完整集合,不是要追加的差异数组;最多 2048 条。 - 状态影响:只读计划。
- 原始返回:
ImpactPreview<RoleRuleReplacePlan>,重点检查 operations、unchanged、affectedUsers 和 conflicts。
replaceRules(roleId, rules, options)
- 用途:把角色手工规则原子替换为完整目标集合。
- 参数:
rules必须与 preview 相同;options 含expectedRevisions + previewToken。 - 状态影响:批量增删改手工来源;菜单来源保持独立,不会被本方法覆盖。
- 原始返回:
MutationResult<BatchMutationSummary>,使用 inserted/updated/unchanged/deleted/conflicted。
方法详解:读取直接与有效规则
getOwnRules(roleId)
- 用途:一次读取角色自身直接拥有的全部有界规则,包含手工和菜单来源,不解析父角色继承。
- 参数:
roleId必填。 - 状态影响:只读。
- 原始返回:
VersionedResult<PermissionRuleView[]>。 - 区别:需要分页/过滤来源时用
listOwnRules;需要继承结果时用getEffectiveRules。
listOwnRules(roleId, query?)
- 用途:为规则管理列表分页读取角色自身规则。
- 参数:
query可传first/after/effect/sourceKind。 - 状态影响:只读。
- 原始返回:
PageResult<PermissionRuleView>;用于表格分页,不包含父角色规则。
getEffectiveRules(roleId)
- 用途:读取角色经过父链展开后的有效规则和 deny 冲突。
- 参数:
roleId必填。 - 状态影响:只读。
- 原始返回:
VersionedResult<EffectiveRoleRules>;data.role是目标角色,data.chain是继承链,data.rules/conflicts是有界结果。 - 边界:这是角色视角,不包含某个用户的多角色合并;用户诊断用
subject.getPermissions()。
getChain(roleId)
- 用途:单独查看父角色链,以及 disabled/deprecated 节点为何未进入有效结果。
- 参数:
roleId必填。 - 状态影响:只读。
- 原始返回:
VersionedResult<RoleChainEntry[]>;每项含role/depth/included/excludedReason。 - 区别:只解释层级,不返回规则;规则使用
getEffectiveRules。
update 只修改 label/description。状态或父角色变更使用 previewAccessUpdate 加 executeAccessUpdate。完整规则替换始终使用 preview/execute。
响应与副作用
读取返回 data、revision vector、etag 和 detail budget。写入提交角色/规则状态及审计证据,并返回 operation/audit ID。allow/deny 给规范语义规则添加手工来源;等价菜单来源仍可独立追踪。
失败与限制
重要错误包括 ROLE_NOT_FOUND、ROLE_ALREADY_EXISTS、ROLE_IN_USE、CIRCULAR_INHERITANCE、REVISION_CONFLICT、PREVIEW_REQUIRED、PREVIEW_STALE、LIMIT_EXCEEDED。限制包括单父角色、层级深度 32、每角色 2048 条规则及有界有效快照。replace 最多接受 2048 条规则。