forcedotcom/sf-skills

platform-role-hierarchy-apply

Bulk-realign an existing Salesforce UserRole hierarchy from an external org-chart artifact (PDF, xlsx, or plain-text list of role-and-parent pairs) in one admin-approved manifest.

ソースを見る

使い方

  1. インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
  2. 必要なツール、認証情報、対応環境を原文で確認します。
  3. 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/forcedotcom/sf-skills --skill platform-role-hierarchy-apply

開始前の確認

  • 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
  • スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

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.

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.

Flow

0. Clarify before querying

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.

1. Read the current hierarchy

text
SELECT Id, DeveloperName, Name, ParentRoleId
FROM   UserRole
LIMIT  10000

Match artifact roles by DeveloperName, then case-insensitive Name.

2. Parse the artifact and resolve identities

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.

3. Build the manifest

Each mutation has operationId, operationType, dependsOnOperationIds, and one nested payload. dependsOnOperationIds is the order that matters.

operationTypeNested objectUse when
CreateRolecreateRoleRole 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.
ReparentRolereparentRoleRole exists and the parent differs. Set targetRoleId or targetRoleReference, expectedParentRoleId, and desiredParentRoleId or desiredParentRoleReference.
RenameRolerenameRoleSame role, different label or developer name. Set the expected and desired name fields.
DeleteRoledeleteRoleAdmin asked to remove an empty role. Set targetRoleId, expectedParentRoleId, expectedAssignedUserIds, and expectedDirectChildRoleIds.
AssignUser or MoveUseruserRoleAssignmentReassignment 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 operationIds 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.

4. Validate, then preview

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.

5. Submit

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.

6. Read the response

  • 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.

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 -->

Operations Reference

Operations this skill uses — routing and dependency reference.

OperationPurposeStatusCallDepends on
read-role-hierarchyread—GET /services/data/v68.0/query—
count-users-per-roleread—GET /services/data/v68.0/queryread-role-hierarchy
submit-role-hierarchy-restructurewrite—POST /services/data/v68.0/sharing/role-hierarchy-restructureread-role-hierarchy
verify-role-hierarchy-restructureverify—GET /services/data/v68.0/querysubmit-role-hierarchy-restructure

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

タスクに関連する項目

同じリポジトリから

関連する Skills

すべての Skills
forcedotcom
コミュニティ

platform-custom-application-generate

Use this skill when users need to create or configure tab-based Salesforce Custom Applications with navigation, branding, and action overrides. Trigger when users mention custom apps, application metadata, app navigation, or organizing tabs into applications. Use when users want to create app containers for tabs and pages. Do NOT use when the goal is hosting a React UI bundle in the App Launcher — use experience-ui-bundle-custom-app-generate for that case.

導入数
1
GitHub Stars
1112
更新日
10月23日
forcedotcom
コミュニティ

platform-custom-field-generate

Use when users create, generate, or validate Salesforce Custom Field metadata. Trigger on custom fields, field types, Roll-Up Summary, Master-Detail/Lookup relationships, formula fields, picklists, dependent (controlling) picklists, referencing a value set from a field, or scoping picklist values per record type; also field deployment errors, including a record type that won't deploy without a business process. DO NOT TRIGGER for creating/customizing the value set itself — a new GlobalValueSet o

導入数
1
GitHub Stars
1112
更新日
10月23日
forcedotcom
コミュニティ

platform-custom-metadata-type-generate

Use to create, generate, or validate Salesforce Custom Metadata Type metadata — the mdt object, fields, and deployable records. Trigger on custom metadata types, CMDT, mdt objects, .md-meta.xml files, or cross-org reference/config data; also admin-maintained mapping/lookup/crosswalk tables (config that changes without a deploy belongs in a CMDT, never hardcoded in Apex/Flow), and CMDT deploy errors. DO NOT TRIGGER for Custom Settings (use platform-custom-setting-generate), business-record object

導入数
1
GitHub Stars
1112
更新日
10月23日
forcedotcom
コミュニティ

platform-custom-report-type-generate

Use to create, generate, or validate Salesforce Custom Report Type metadata. Trigger on custom report types, CRTs, cross-object reports, report builder data sources, exposing fields for reporting across related objects, inner vs outer joins in reports, report type categories, or deployment errors for .reportType-meta.xml files. Do NOT trigger for running, editing, or filtering existing reports; creating report folders, dashboards, or list views; or non-authoring reporting questions.

導入数
1
GitHub Stars
1112
更新日
10月23日