关于 platform-role-hierarchy-apply
该 Salesforce 管理技能根据组织结构图或角色清单,批量调整 UserRole 层级,并通过管理员批准的清单一次提交。它在提交前解析身份、检查冲突与依赖,并预览变更。
主要功能
- 01读取现有角色层级
- 02解析组织图或角色清单
- 03匹配角色与用户身份
- 04构建带依赖的变更清单
- 05验证并预览批量变更
- 06提交后解读操作结果
适用场景
- 01按组织图批量重设角色父级
- 02创建、重命名或删除角色
- 03经确认后重新分配用户角色
- 04提交前检查循环和缺失父角色
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-role-hierarchy-apply安装后在 Claude Code 中输入/platform-role-hierarchy-apply确认已加载。
详细介绍
角色层级重构
通过一份经管理员批准的清单,一次性应用多项 UserRole 更改。
如果管理员只是询问有哪些角色或角色如何嵌套,请转交给 managing-roles。不要查询,不要询问步骤 0 中的问题,也不要提交。
输入
- 可选择文本的组织架构图 PDF、包含
role_name和parent_role_name的.xlsx/.csv(空父级表示顶级角色),或每行包含一个Role: Parent配对的纯文本。 - 或预解析的
{roleName, parentRoleName}对象列表。 - 当图表中的名称与组织的
Name或DeveloperName不一致时,可提供可选的映射提示。
流程
0. 查询前先澄清
询问所有尚未明确的事项。不要猜测。
- 范围。 默认只处理所选分支:未出现在材料中的角色保持不变。“完整层级”仍不会删除这些角色,除非管理员逐一要求删除。
- 用户重新分配。 默认不重新分配。未经明确同意,不要输出
AssignUser或MoveUser。 - 身份不明确。 批量解析所有角色和用户。参见步骤 2。
- 冲突。 一个角色有两个父级,或角色的父级是其自身:暂停,直到管理员作出选择。
如果材料中的角色与当前树匹配的比例低于 20%,请暂停并询问这是全新替换、文件错误,还是映射问题。在管理员确认这是全新替换之前,不要构建清单。匹配比例在 20% 至 50% 之间时,在预览中显示该比例并继续。
1. 读取当前层级
SELECT Id, DeveloperName, Name, ParentRoleId
FROM UserRole
LIMIT 10000
先按 DeveloperName 匹配材料中的角色,再按不区分大小写的 Name 匹配。
2. 解析材料并确定身份
将内容规范化为 {roleName, parentRoleName, users?},并在生成差异前向管理员展示该列表。无法选择文本的 PDF 无法解析。请对方提供 Role: Parent 格式的纯文本列表。
角色:先精确匹配 DeveloperName,再按不区分大小写的 Name 匹配。不进行模糊匹配。如果匹配到多个角色,列出每个候选项的 DeveloperName 和 Id 并等待回复。不要自行选择。未解析的名称返回步骤 0 处理。
仅在确认重新分配后解析用户:
- 以
005开头的 18 位 id →User.Id - 电子邮件 →
User.Email - 用户名 →
User.Username - 显示名称 →
User.Name,且仅在恰好有一位活跃用户匹配时使用
IsActive = false 表示不匹配。如果同一用户列在两个角色下,即为冲突。询问该用户应归属哪个角色,或是否取消重新分配。在管理员答复前不要提交。
如果目标图中存在循环,则暂停。报告路径,例如 A → B → C → A,并要求提供更正后的材料。不要提交。
3. 构建清单
每个变更都包含 operationId、operationType、dependsOnOperationIds 和一个嵌套载荷。顺序由 dependsOnOperationIds 决定。
| operationType | 嵌套对象 | 适用情况 |
|---|---|---|
CreateRole | createRole | 角色存在于制品中,但不在组织中。设置 roleReference、developerName、name,以及 parentRoleId 或 parentRoleReference。如果制品中未提供三个账户所有者访问字段,则将其设为组织默认值。 |
ReparentRole | reparentRole | 角色已存在,但父级不同。设置 targetRoleId 或 targetRoleReference、expectedParentRoleId,以及 desiredParentRoleId 或 desiredParentRoleReference。 |
RenameRole | renameRole | 角色相同,但标签或开发者名称不同。设置预期名称字段和目标名称字段。 |
DeleteRole | deleteRole | 管理员要求移除一个空角色。设置 targetRoleId、expectedParentRoleId、expectedAssignedUserIds 和 expectedDirectChildRoleIds。 |
AssignUser 或 MoveUser | userRoleAssignment | 已确认重新分配。设置 userId、expectedCurrentRoleId,以及 desiredRoleId 或 desiredRoleReference。 |
仅当角色在操作执行时没有直接子角色且没有已分配用户时,才能执行 DeleteRole。在更早的变更中重新指定这些子角色的父级并移动这些用户,然后将这些变更的 operationId 放入 dependsOnOperationIds。这样一来,删除操作的预期用户列表和子角色列表就为空。如果管理员拒绝重新分配,则不要删除仍有用户的角色。
如果某个变更指定的角色既不在组织中,也未在此清单中创建,则属于 missing-parent。列出指向该角色的角色。询问是否要在此清单中为其添加 CreateRole、跳过这些行,还是中止。父角色缺失时不要提交。
dependsOnOperationIds 中的循环会阻止提交。为每个新角色指定一个 roleReference 字符串,并让父角色和分配操作引用该字符串。
4. 验证,然后预览
如果仍存在以下任一情况,则阻止提交:循环、缺少父角色、重复的 developerName、依赖循环、没有第 0 步确认就执行 AssignUser 或 MoveUser、DeleteRole 的预期用户或子角色列表不为空,或重叠度低于 20%,且未确认进行全新替换。
如果 developerName 重复,展示这两行并等待管理员选择其中一行或重命名其中一行。
在预览中发出警告,并且只有在收到明确的肯定答复后才继续:
- 变更的角色被
Territory2.UserRoleId或预测层级覆盖项引用。 - 变更的角色具有
PortalType != 'None'。 - 变更的角色拥有超过 500 个用户(
SELECT COUNT() FROM User WHERE UserRoleId = :id)。
Restructure preview
-------------------
ReparentRole : 42
CreateRole : 3
RenameRole : 1
DeleteRole : 2
MoveUser : 2
Territory / forecast references : 1
Portal roles : 0
Roles with more than 500 users : 2
Approve this restructure? [yes / no]
只有答复为 yes 才会提交。其他任何答复都不会提交。保留在组织中但不在制品中的角色。
5. 提交
POST /services/data/v{version}/sharing/role-hierarchy-restructure
{
"operation": "Save",
"mutations": [
{
"operationId": "reparent-sales-vp",
"operationType": "ReparentRole",
"dependsOnOperationIds": [],
"reparentRole": {
"targetRoleId": "00E000000000001",
"expectedParentRoleId": "00E000000000002",
"desiredParentRoleReference": "cro"
}
},
{
"operationId": "delete-legacy-region",
"operationType": "DeleteRole",
"dependsOnOperationIds": ["reparent-legacy-children"],
"deleteRole": {
"targetRoleId": "00E000000000003",
"expectedParentRoleId": "00E000000000002",
"expectedAssignedUserIds": [],
"expectedDirectChildRoleIds": []
}
}
]
}
CreateRole、RenameRole、AssignUser 和 MoveUser 使用相同的信封,并包含第 3 步中的对应嵌套对象。
只发送一次已批准的清单。不要逐个编辑 UserRole 记录。
6. 读取响应
Applied— 结构变更和共享变更已提交。AppliedSharingPending— 层级已生效;共享会自行跟进。不要轮询。AsyncExecutionRequired— 服务端已将清单加入队列。不要轮询。RoleOperationInProgress— 另一项重组操作正在运行。停止。不要将清单加入队列。请管理员在另一项操作完成后重试。NotApplied— 未提交任何内容。显示reasonCodes并停止。- 提交时返回
404— 此客户端层级未启用 API。停止操作,告知管理员,不要重试,也不要退回到逐条编辑/sobjects/UserRole。
对于每个 operationResults[] 条目,outcome 为 Applied、NotApplied 或 DependencyNotApplied。对于任何 outcome 不为 Applied 的条目,显示 reasonCode。不要重试,也不要回滚。
不在范围内
- 单独创建、重命名或重新指定上级角色,且没有其他变更;以及只询问有哪些角色或这些角色如何嵌套的请求(
managing-roles)。 - 区域、客户和预测层级。
- 创建共享规则。
- 仅包含图像的 PDF。请提供文本。
- 回滚。报告响应中说明已提交的内容。
操作参考
此技能使用的操作 — 路由和依赖关系参考。
| 操作 | 用途 | 状态 | 调用 | 依赖项 |
|---|---|---|---|---|
read-role-hierarchy | 读取 | — | GET /services/data/v68.0/query | — |
count-users-per-role | 读取 | — | GET /services/data/v68.0/query | read-role-hierarchy |
submit-role-hierarchy-restructure | 写入 | — | POST /services/data/v68.0/sharing/role-hierarchy-restructure | read-role-hierarchy |
verify-role-hierarchy-restructure | 验证 | — | GET /services/data/v68.0/query | submit-role-hierarchy-restructure |