platform-role-hierarchy-apply

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Role Hierarchy Restructure

角色层级重组

Apply many UserRole changes from an artifact in one admin-approved manifest.
If the admin only asks which roles exist or how they are nested, hand off to
managing-roles
. Do not query, do not ask the step 0 questions, and do not submit.
通过一个经管理员批准的 manifest,一次性应用来自 artifact 的大量 UserRole 变更。
如果管理员只是询问存在哪些角色或这些角色如何嵌套,请转交给
managing-roles
。不要查询,不要询问步骤 0 中的问题,也不要提交。

Inputs

输入

  • PDF org chart (text-selectable),
    .xlsx
    /
    .csv
    with
    role_name
    and
    parent_role_name
    (empty parent = top-level), or plain text with one
    Role: Parent
    pair per line.
  • Or a pre-parsed list of
    {roleName, parentRoleName}
    objects.
  • Optional mapping hints when a chart name is not the org's
    Name
    or
    DeveloperName
    .
  • 可选择文本的 PDF 组织结构图、包含
    role_name
    和
    parent_role_name
    的
    .xlsx
    /
    .csv
    (父级为空表示顶层),或每行包含一个
    Role: Parent
    角色与父角色对的纯文本。
  • 或预先解析好的
    {roleName, parentRoleName}
    对象列表。
  • 当组织结构图中的名称不是组织中的
    Name
    或
    DeveloperName
    时,可选提供映射提示。

Flow

流程

0. Clarify before querying

0. 查询前先澄清

Ask anything still unresolved. Do not guess.
  • Scope. Default is selected branches: roles absent from the artifact stay. "Full hierarchy" still does not delete those roles unless the admin asked for each deletion.
  • User reassignment. Default is no. Do not emit
    AssignUser
    or
    MoveUser
    without an explicit yes.
  • Ambiguous identities. Resolve every role and user in one batch. See step 2.
  • Conflicts. Two parents for one role, or a role parented to itself: stop until the admin picks.
If the artifact matches fewer than 20% of its roles to the current tree, stop and ask whether it is a greenfield replacement, the wrong file, or a mapping problem. Do not build a manifest until the admin confirms a greenfield replacement. Between 20% and 50%, show the fraction in the preview and continue.
询问所有尚未解决的问题。不要猜测。
  • 范围。 默认仅处理选定分支:artifact 中未出现的角色保持不变。即使选择“完整层级”,除非管理员明确要求删除每一个此类角色,否则仍不得删除它们。
  • 用户重新分配。 默认不重新分配。没有明确同意时,不要发出
    AssignUser
    或
    MoveUser
    。
  • 身份不明确。 在一个批次中解析所有角色和用户。参见步骤 2。
  • 冲突。 如果一个角色有两个父级,或某个角色的父级是自身,则停止操作,直到管理员作出选择。
如果 artifact 与当前层级树的角色匹配率低于 20%,停止操作,并询问这是全新替换、文件错误还是映射问题。在管理员确认全新替换之前,不要构建 manifest。匹配率介于 20% 和 50% 之间时,在预览中显示该比例并继续。

1. Read the current hierarchy

1. 读取当前层级

text
SELECT Id, DeveloperName, Name, ParentRoleId
FROM   UserRole
LIMIT  10000
Match artifact roles by
DeveloperName
, then case-insensitive
Name
.
text
SELECT Id, DeveloperName, Name, ParentRoleId
FROM   UserRole
LIMIT  10000
先按
DeveloperName
匹配 artifact 中的角色,然后按不区分大小写的
Name
匹配。

2. Parse the artifact and resolve identities

2. 解析 artifact 并确定身份

Normalize to
{roleName, parentRoleName, users?}
and show that list to the admin before the diff. A PDF that is not text-selectable cannot be parsed. Ask for a plain-text
Role: Parent
list.
Roles: exact
DeveloperName
, then case-insensitive
Name
. No fuzzy match. When more than one role matches, list each candidate's
DeveloperName
and
Id
and wait. Do not pick one. Unresolved names go back to step 0.
Users, only after reassignment was confirmed:
  1. 18-character id starting with
    005
    →
    User.Id
  2. Email →
    User.Email
  3. Username →
    User.Username
  4. Display name →
    User.Name
    , and only when exactly one active user matches
IsActive = false
is a non-match. A user listed under two roles is a conflict. Ask which role that user should land under, or whether to drop the reassignment. Do not submit until the admin answers.
Stop on a cycle in the target graph. Report the path, for example
A → B → C → A
, and ask for a corrected artifact. Do not submit.
规范化为
{roleName, parentRoleName, users?}
,并在差异对比前向管理员显示该列表。无法选择文本的 PDF 无法解析。请提供纯文本
Role: Parent
列表。
角色:先精确匹配
DeveloperName
,再按不区分大小写的
Name
匹配。不进行模糊匹配。当匹配到一个以上角色时,列出每个候选项的
DeveloperName
和
Id
并等待。不要自行选择。未解析的名称返回步骤 0。
仅在确认重新分配后处理用户:
  1. 18 位且以
    005
    开头的 ID →
    User.Id
  2. 邮箱 →
    User.Email
  3. 用户名 →
    User.Username
  4. 显示名称 →
    User.Name
    ,且仅当恰好有一个活跃用户匹配时
IsActive = false
视为不匹配。同一用户被列在两个角色下属于冲突。询问该用户应归属哪个角色,或是否取消重新分配。在管理员回答之前不要提交。
如果目标图中存在循环,则停止。报告路径,例如
A → B → C → A
,并要求提供修正后的 artifact。不要提交。

3. Build the manifest

3. 构建 manifest

Each mutation has
operationId
,
operationType
,
dependsOnOperationIds
, and one nested payload.
dependsOnOperationIds
is the order that matters.
operationTypeNested objectUse when
CreateRole
createRole
Role is in the artifact and not in the org. Set
roleReference
,
developerName
,
name
, and
parentRoleId
or
parentRoleReference
. Default the three account-owner access fields to the org defaults when the artifact omits them.
ReparentRole
reparentRole
Role exists and the parent differs. Set
targetRoleId
or
targetRoleReference
,
expectedParentRoleId
, and
desiredParentRoleId
or
desiredParentRoleReference
.
RenameRole
renameRole
Same role, different label or developer name. Set the expected and desired name fields.
DeleteRole
deleteRole
Admin asked to remove an empty role. Set
targetRoleId
,
expectedParentRoleId
,
expectedAssignedUserIds
, and
expectedDirectChildRoleIds
.
AssignUser
or
MoveUser
userRoleAssignment
Reassignment was confirmed. Set
userId
,
expectedCurrentRoleId
, and
desiredRoleId
or
desiredRoleReference
.
DeleteRole
applies only when the role has no direct children and no assigned users at the moment it runs. Reparent those children and move those users in earlier mutations, and put those
operationId
s in
dependsOnOperationIds
. The delete's expected user and child lists are then empty. If the admin declined reassignment, do not delete a role that still has users.
A mutation that names a role neither in the org nor created in this manifest is
missing-parent
. Name the roles that point at it. Ask whether to add a
CreateRole
for it in this manifest, skip those rows, or abort. Do not submit with that parent missing.
A cycle in
dependsOnOperationIds
blocks the submit. Give every new role a
roleReference
string and point parents and assignments at that string.
每个 mutation 都包含
operationId
、
operationType
、
dependsOnOperationIds
和一个嵌套 payload。
dependsOnOperationIds
决定必须遵循的执行顺序。
operationType嵌套对象使用场景
CreateRole
createRole
角色存在于 artifact 中但不在组织中。设置
roleReference
、
developerName
、
name
,以及
parentRoleId
或
parentRoleReference
。当 artifact 未提供时,将三个 account-owner access 字段设为组织默认值。
ReparentRole
reparentRole
角色已存在,但父级不同。设置
targetRoleId
或
targetRoleReference
、
expectedParentRoleId
,以及
desiredParentRoleId
或
desiredParentRoleReference
。
RenameRole
renameRole
同一角色,但 label 或 developer name 不同。设置预期名称字段和目标名称字段。
DeleteRole
deleteRole
管理员要求删除空角色时使用。设置
targetRoleId
、
expectedParentRoleId
、
expectedAssignedUserIds
和
expectedDirectChildRoleIds
。
AssignUser
或
MoveUser
userRoleAssignment
确认需要重新分配时使用。设置
userId
、
expectedCurrentRoleId
,以及
desiredRoleId
或
desiredRoleReference
。
DeleteRole
仅在角色执行时没有直接子角色且没有已分配用户的情况下适用。在更早的 mutations 中重新设定这些子角色的父级并移动这些用户,同时把这些
operationId
放入
dependsOnOperationIds
。随后 delete 的预期用户列表和子角色列表应为空。如果管理员拒绝重新分配,则不要删除仍包含用户的角色。
如果某个 mutation 引用了一个既不在组织中、也不是由此 manifest 创建的角色,则该角色为
missing-parent
。指出引用该角色的角色。询问是否在 manifest 中为它添加
CreateRole
、跳过这些行,或中止操作。父级缺失时不要提交。
dependsOnOperationIds
中存在循环会阻止提交。为每个新角色提供
roleReference
字符串,并让父级和分配操作指向该字符串。

4. Validate, then preview

4. 验证并预览

Block the submit when any of these remain: a cycle, a missing parent, a duplicate
developerName
, a dependency cycle, an
AssignUser
or
MoveUser
without the step 0 yes, a
DeleteRole
whose expected user or child lists are not empty, or overlap under 20% without a confirmed greenfield replacement.
On a duplicate
developerName
, show both rows and wait until the admin picks one or renames one.
Warn in the preview, and continue only after an explicit yes:
  • A changed role is referenced by
    Territory2.UserRoleId
    or a forecast hierarchy override.
  • A changed role has
    PortalType != 'None'
    .
  • A changed role has more than 500 users (
    SELECT COUNT() FROM User WHERE UserRoleId = :id
    ).
text
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
submits. Anything else does not. Roles left in the org and absent from the artifact stay in place.
存在以下任一情况时阻止提交:循环、缺失父级、重复的
developerName
、依赖关系循环、未经步骤 0 明确同意的
AssignUser
或
MoveUser
、预期用户列表或子角色列表不为空的
DeleteRole
,或匹配率低于 20% 但尚未确认全新替换。
出现重复的
developerName
时,显示两行记录,并等待管理员选择其中一行或重命名其中一个角色。
在预览中发出警告,并且只有在明确同意后才能继续:
  • 被更改的角色被
    Territory2.UserRoleId
    或 forecast 层级覆盖项引用。
  • 被更改的角色满足
    PortalType != 'None'
    。
  • 被更改的角色拥有超过 500 个用户(
    SELECT COUNT() FROM User WHERE UserRoleId = :id
    )。
text
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
表示提交。其他任何回复均不提交。组织中保留而 artifact 中未出现的角色保持原位。

5. Submit

5. 提交

text
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
, and
MoveUser
use the same envelope with their nested object from step 3.
Send the approved manifest once. Do not edit
UserRole
records one by one.
text
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
使用相同的 envelope,并采用步骤 3 中各自的嵌套对象。
只发送一次已批准的 manifest。不要逐条编辑
UserRole
记录。

6. Read the response

6. 读取响应

  • Applied
    — structural and sharing changes committed.
  • AppliedSharingPending
    — hierarchy is live; sharing catches up on its own. Do not poll.
  • AsyncExecutionRequired
    — the server queued the manifest. Do not poll.
  • RoleOperationInProgress
    — another restructure is running. Stop. Do not queue the manifest. Ask the admin to retry once the other operation finishes.
  • NotApplied
    — nothing committed. Show
    reasonCodes
    and stop.
  • 404
    on submit — API not enabled for this client tier. Halt, tell the admin, do not retry, do not fall back to per-record
    /sobjects/UserRole
    edits.
For each
operationResults[]
entry,
outcome
is
Applied
,
NotApplied
, or
DependencyNotApplied
. Show
reasonCode
for any entry that is not
Applied
. Do not retry and do not roll back.
  • Applied
    — 结构和 sharing 变更已提交。
  • AppliedSharingPending
    — 层级已生效;sharing 将自行完成追赶。不要轮询。
  • AsyncExecutionRequired
    — 服务端已将 manifest 排队。不要轮询。
  • RoleOperationInProgress
    — 另一次重组正在运行。停止。不要为该 manifest 排队。询问管理员在另一项操作完成后重试。
  • NotApplied
    — 未提交任何变更。显示
    reasonCodes
    并停止。
  • 提交时返回
    404
    — 当前客户端层级未启用该 API。停止,告知管理员,不要重试,也不要回退为逐条编辑
    /sobjects/UserRole
    。
对于每个
operationResults[]
条目,
outcome
为
Applied
、
NotApplied
或
DependencyNotApplied
。任何非
Applied
条目都要显示
reasonCode
。不要重试,也不要回滚。

Out of scope

不在范围内

  • A single role create, rename, or reparent with no other changes, and any request that only asks which roles exist or how they are nested (
    managing-roles
    ).
  • Territory, account, and forecast hierarchies.
  • Authoring sharing rules.
  • Image-only PDFs. Ask for text.
  • Rollback. Report what the response says was committed.

<!-- skill-validate: ignore-start --> <!-- codey:operations start -->
  • 没有其他变更的单项角色创建、重命名或重新设定父级,以及任何仅询问存在哪些角色或角色如何嵌套的请求(
    managing-roles
    )。
  • Territory、account 和 forecast 层级。
  • 编写 sharing rules。
  • 仅含图像的 PDF。请提供文本。
  • 回滚。报告响应中说明已提交的内容。

<!-- skill-validate: ignore-start --> <!-- codey:operations start -->

Operations Reference

操作参考

Operations this skill uses — routing and dependency reference.
OperationPurposeStatusCallDepends on
read-role-hierarchy
read—
GET /services/data/v68.0/query
—
count-users-per-role
read—
GET /services/data/v68.0/query
read-role-hierarchy
submit-role-hierarchy-restructure
write—
POST /services/data/v68.0/sharing/role-hierarchy-restructure
read-role-hierarchy
verify-role-hierarchy-restructure
verify—
GET /services/data/v68.0/query
submit-role-hierarchy-restructure
<!-- codey:operations end --> <!-- skill-validate: ignore-end -->
此 skill 使用的操作——路由与依赖关系参考。
操作用途状态调用依赖于
read-role-hierarchy
read—
GET /services/data/v68.0/query
—
count-users-per-role
read—
GET /services/data/v68.0/query
read-role-hierarchy
submit-role-hierarchy-restructure
write—
POST /services/data/v68.0/sharing/role-hierarchy-restructure
read-role-hierarchy
verify-role-hierarchy-restructure
verify—
GET /services/data/v68.0/query
submit-role-hierarchy-restructure
<!-- codey:operations end --> <!-- skill-validate: ignore-end -->