@salesforce/afv-skills 1.65.0 → 1.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/field-service-data-capture-form-deployer-configure/SKILL.md +2 -23
- package/skills/field-service-data-capture-form-designer-configure/SKILL.md +3 -13
- package/skills/field-service-mobile-branding-configure/SKILL.md +3 -17
- package/skills/field-service-objective-designer-configure/SKILL.md +379 -72
- package/skills/field-service-prework-brief-deployer-configure/SKILL.md +537 -10
- package/skills/field-service-scheduling-policy-designer-query/SKILL.md +1093 -65
- package/skills/field-service-sobject-create-configure/SKILL.md +213 -13
- package/skills/field-service-voice-to-form-configure/SKILL.md +11 -40
- package/skills/field-service-work-rule-designer-configure/SKILL.md +95 -121
- package/skills/agentforce-gpt-email-generation-configure/SKILL.md +0 -312
- package/skills/agentforce-wizard-ui-forecasting-analytics-components-configure/SKILL.md +0 -64
- package/skills/agentforce-wizard-ui-sales-einstein-components-configure/SKILL.md +0 -46
- package/skills/automation-company-profile-info-query/SKILL.md +0 -51
- package/skills/automation-digital-wallet-configure/SKILL.md +0 -689
- package/skills/automation-flow-coordinate/SKILL.md +0 -95
- package/skills/automation-flow-coordinate/references/elements/action-call/action-call.md +0 -1569
- package/skills/automation-flow-coordinate/references/elements/action-call/conversation-messaging.md +0 -96
- package/skills/automation-flow-coordinate/references/elements/action-call/examples/send-sms-message.json +0 -23
- package/skills/automation-flow-coordinate/references/elements/action-call/examples/send-to-journey-no-fields.json +0 -31
- package/skills/automation-flow-coordinate/references/elements/action-call/send-to-journey.md +0 -179
- package/skills/automation-flow-coordinate/references/elements/exit-rule/examples/event-email-link-click.json +0 -13
- package/skills/automation-flow-coordinate/references/elements/exit-rule/exit-rule.md +0 -83
- package/skills/automation-flow-coordinate/references/elements/forward-to-bot-or-agent/examples/forward-to-bot-or-agent.json +0 -69
- package/skills/automation-flow-coordinate/references/elements/forward-to-bot-or-agent/forward-to-bot-or-agent.md +0 -274
- package/skills/automation-flow-coordinate/references/elements/start/audience-common.md +0 -192
- package/skills/automation-flow-coordinate/references/elements/start/automation-event-triggered.md +0 -130
- package/skills/automation-flow-coordinate/references/elements/start/data-cloud-data-change-triggered.md +0 -92
- package/skills/automation-flow-coordinate/references/elements/start/form-submission-triggered.md +0 -88
- package/skills/automation-flow-coordinate/references/elements/start/segment-triggered.md +0 -152
- package/skills/automation-flow-coordinate/references/elements/start/start.md +0 -539
- package/skills/automation-flow-coordinate/references/elements/subflow/subflow.md +0 -152
- package/skills/automation-flow-coordinate/references/elements/wait/wait.md +0 -497
- package/skills/automation-flow-coordinate/references/recipes/author/author.md +0 -868
- package/skills/automation-flow-coordinate/references/recipes/summarize/element-generic.md +0 -300
- package/skills/automation-flow-coordinate/references/recipes/summarize/reference-resolution.md +0 -292
- package/skills/automation-flow-coordinate/references/recipes/summarize/summarize.md +0 -323
- package/skills/automation-flow-coordinate/references/recipes/testing/examples/debug-output-template.md +0 -109
- package/skills/automation-flow-coordinate/references/recipes/testing/shape.md +0 -219
- package/skills/automation-flow-coordinate/references/recipes/testing/shared-stages/intent-analyzer.md +0 -180
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/debug.md +0 -175
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/promote.md +0 -255
- package/skills/automation-flow-coordinate/references/recipes/testing/workflows/save-debug.md +0 -212
- package/skills/automation-flow-coordinate/references/resources/variable/variable.md +0 -171
- package/skills/automation-flow-coordinate/references/shared/anti-patterns.md +0 -786
- package/skills/automation-flow-coordinate/references/shared/end/end.md +0 -267
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/README.md +0 -69
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/predictions.jsonl +0 -80
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/eval/prompts.jsonl +0 -116
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/flow-type-resolver.md +0 -321
- package/skills/automation-flow-coordinate/references/shared/flow-type-resolver/taxonomy.json +0 -320
- package/skills/automation-flow-coordinate/references/shared/server-functions.md +0 -597
- package/skills/automotive-cloud-appraisal-management-settings-configure/SKILL.md +0 -69
- package/skills/automotive-cloud-dealer-essentials-configure/SKILL.md +0 -78
- package/skills/automotive-cloud-ground-agent-data-pipelines-configure/SKILL.md +0 -373
- package/skills/automotive-cloud-ground-mfg-agent-data-pipelines-configure/SKILL.md +0 -273
- package/skills/automotive-cloud-mfg-agent-data-pipelines-configure/SKILL.md +0 -259
- package/skills/automotive-cloud-mfg-sales-concierge-agent-create/SKILL.md +0 -369
- package/skills/automotive-cloud-mfg-sales-concierge-foundation-configure/SKILL.md +0 -542
- package/skills/automotive-cloud-mfg-sales-concierge-foundation-coordinate/SKILL.md +0 -159
- package/skills/automotive-cloud-mfg-sales-concierge-orchestrator-agent-create/SKILL.md +0 -349
- package/skills/automotive-cloud-mfg-sales-concierge-orchestrator-configure/SKILL.md +0 -505
- package/skills/automotive-cloud-sales-concierge-agent-create/SKILL.md +0 -380
- package/skills/automotive-cloud-sales-concierge-foundation-configure/SKILL.md +0 -567
- package/skills/automotive-cloud-sales-concierge-foundation-coordinate/SKILL.md +0 -159
- package/skills/automotive-cloud-sales-concierge-orchestrator-agent-create/SKILL.md +0 -360
- package/skills/automotive-cloud-sales-concierge-orchestrator-configure/SKILL.md +0 -539
- package/skills/automotive-cloud-sales-concierge-search-grounding-configure/SKILL.md +0 -358
- package/skills/commerce-b2b-merchant-quote-configure/SKILL.md +0 -602
- package/skills/commerce-b2b-store-configure/SKILL.md +0 -251
- package/skills/commerce-credit-memo-create/SKILL.md +0 -139
- package/skills/commerce-delivery-business-hours-configure/SKILL.md +0 -277
- package/skills/commerce-delivery-estimation-apply/SKILL.md +0 -155
- package/skills/commerce-delivery-estimation-configure/SKILL.md +0 -377
- package/skills/commerce-delivery-routing-specs-integrate/SKILL.md +0 -174
- package/skills/commerce-estimate-bopis-query/SKILL.md +0 -279
- package/skills/commerce-estimate-delivery-date-query/SKILL.md +0 -349
- package/skills/commerce-fees-apply/SKILL.md +0 -227
- package/skills/commerce-fulfillment-routing-analyze/SKILL.md +0 -200
- package/skills/commerce-guest-buyer-create/SKILL.md +0 -173
- package/skills/commerce-location-bopis-configure/SKILL.md +0 -378
- package/skills/commerce-location-business-hours-configure/SKILL.md +0 -235
- package/skills/commerce-location-delivery-processing-time-configure/SKILL.md +0 -309
- package/skills/commerce-location-graph-integrate/SKILL.md +0 -131
- package/skills/commerce-location-shipping-carrier-method-configure/SKILL.md +0 -755
- package/skills/commerce-location-temporary-operating-hours-configure/SKILL.md +0 -331
- package/skills/commerce-merchant-buyer-groups-configure/SKILL.md +0 -579
- package/skills/commerce-merchant-buyer-user-onboarding-create/SKILL.md +0 -626
- package/skills/commerce-merchant-catalog-configure/SKILL.md +0 -614
- package/skills/commerce-merchant-extension-provider-configure/SKILL.md +0 -368
- package/skills/commerce-merchant-insights-account-health-churn-analyze/SKILL.md +0 -118
- package/skills/commerce-merchant-insights-inventory-returns-analyze/SKILL.md +0 -65
- package/skills/commerce-merchant-insights-order-shopper-get/SKILL.md +0 -90
- package/skills/commerce-merchant-insights-product-performance-analyze/SKILL.md +0 -72
- package/skills/commerce-merchant-insights-query/SKILL.md +0 -279
- package/skills/commerce-merchant-storefront-guest-access-configure/SKILL.md +0 -656
- package/skills/commerce-order-summary-change-apply/SKILL.md +0 -375
- package/skills/commerce-product-details-get/SKILL.md +0 -363
- package/skills/commerce-product-search/SKILL.md +0 -563
- package/skills/commerce-react-storefront-create/SKILL.md +0 -350
- package/skills/commerce-return-order-summary-create/SKILL.md +0 -513
- package/skills/commerce-search-relevance-analyze/SKILL.md +0 -757
- package/skills/commerce-temporary-processing-time-override-create/SKILL.md +0 -274
- package/skills/communications-initial-setup-configure/SKILL.md +0 -630
- package/skills/communications-multisite-configure/SKILL.md +0 -571
- package/skills/communications-revenue-cloud-settings-configure/SKILL.md +0 -74
- package/skills/communications-smb-fiber-catalog-create/SKILL.md +0 -413
- package/skills/communications-tmf-integrate/SKILL.md +0 -1368
- package/skills/consumer-goods-visit-activity-act4-questions-assign/SKILL.md +0 -448
- package/skills/consumer-goods-visit-activity-act5-standard-create/SKILL.md +0 -269
- package/skills/consumer-goods-visit-activity-act6-assortment-configure/SKILL.md +0 -271
- package/skills/consumer-goods-visit-activity-act7-account-scoping-create/SKILL.md +0 -382
- package/skills/consumer-goods-visit-activity-act8-plan-attach-create/SKILL.md +0 -373
- package/skills/consumer-goods-visit-activity-act9-proof-validate/SKILL.md +0 -389
- package/skills/consumer-goods-visit-and-activity-act1-specification-create/SKILL.md +0 -338
- package/skills/consumer-goods-visit-and-activity-act2-template-create/SKILL.md +0 -547
- package/skills/consumer-goods-visit-and-activity-act3-definition-create/SKILL.md +0 -346
- package/skills/consumer-goods-visit-and-activity-configure/SKILL.md +0 -1110
- package/skills/crm-analytics-adoption-insights-configure/SKILL.md +0 -224
- package/skills/crm-analytics-custom-report-type-lightning-configure/SKILL.md +0 -418
- package/skills/crm-analytics-dashboards-configure/SKILL.md +0 -731
- package/skills/crm-analytics-operational-analytics-metadata-bridge-migrate/SKILL.md +0 -233
- package/skills/crm-analytics-report-notifications-ui-configure/SKILL.md +0 -184
- package/skills/crm-analytics-sharing-inheritance-coverage-analyze/SKILL.md +0 -167
- package/skills/crm-analytics-sonic-getting-started-configure/SKILL.md +0 -55
- package/skills/crm-analytics-tableau-next-app-deploy/SKILL.md +0 -1350
- package/skills/crm-analytics-tableau-next-c360-basemodel-validate/SKILL.md +0 -1862
- package/skills/crm-analytics-tableau-next-datacloud-validate/SKILL.md +0 -83
- package/skills/crm-analytics-tableau-next-provisioning-validate/SKILL.md +0 -81
- package/skills/data360-activation-create/SKILL.md +0 -104
- package/skills/data360-activation-external-platform-get/SKILL.md +0 -49
- package/skills/data360-activation-target-create/SKILL.md +0 -93
- package/skills/data360-activation-v2-create/SKILL.md +0 -456
- package/skills/data360-audience-dmo-get/SKILL.md +0 -38
- package/skills/data360-calculated-affinity-create/SKILL.md +0 -82
- package/skills/data360-calculated-insight-create/SKILL.md +0 -148
- package/skills/data360-catalog-metadata-create/SKILL.md +0 -183
- package/skills/data360-code-extension-create/SKILL.md +0 -115
- package/skills/data360-communication-capping-create/SKILL.md +0 -227
- package/skills/data360-connection-create/SKILL.md +0 -491
- package/skills/data360-content-lens-create/SKILL.md +0 -181
- package/skills/data360-data-action-create/SKILL.md +0 -126
- package/skills/data360-data-action-target-create/SKILL.md +0 -181
- package/skills/data360-data-clean-room-create/SKILL.md +0 -238
- package/skills/data360-data-governance-create/SKILL.md +0 -746
- package/skills/data360-data-graph-create/SKILL.md +0 -82
- package/skills/data360-data-harmonized-model-object-reference-create/SKILL.md +0 -38
- package/skills/data360-data-lake-object-create/SKILL.md +0 -207
- package/skills/data360-data-model-object-catalog-get/SKILL.md +0 -49
- package/skills/data360-data-model-object-create/SKILL.md +0 -128
- package/skills/data360-data-model-object-mapping-create/SKILL.md +0 -106
- package/skills/data360-data-space-create/SKILL.md +0 -161
- package/skills/data360-data-streams-create/SKILL.md +0 -324
- package/skills/data360-engagement-signal-get/SKILL.md +0 -38
- package/skills/data360-experiment-create/SKILL.md +0 -82
- package/skills/data360-goal-based-campaign-create/SKILL.md +0 -192
- package/skills/data360-harmonization-process-history-get/SKILL.md +0 -38
- package/skills/data360-harmonized-unstructured-dmo-create/SKILL.md +0 -84
- package/skills/data360-identity-resolution-create/SKILL.md +0 -115
- package/skills/data360-intelligent-document-processing-create/SKILL.md +0 -148
- package/skills/data360-knowledge-graph-construction-create/SKILL.md +0 -93
- package/skills/data360-knowledge-graph-create/SKILL.md +0 -216
- package/skills/data360-knowledge-space-mcp-configure/SKILL.md +0 -475
- package/skills/data360-machine-learning-mcp-configure/SKILL.md +0 -697
- package/skills/data360-multi-org-mcp-configure/SKILL.md +0 -117
- package/skills/data360-secondary-index-mcp-configure/SKILL.md +0 -126
- package/skills/data360-segment-mcp-configure/SKILL.md +0 -159
- package/skills/data360-semantic-calculated-dimension-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-calculated-measurement-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-data-object-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-dimension-mcp-configure/SKILL.md +0 -38
- package/skills/data360-semantic-engine-mcp-configure/SKILL.md +0 -62
- package/skills/data360-semantic-measurement-mcp-configure/SKILL.md +0 -38
- package/skills/data360-semantic-metric-mcp-configure/SKILL.md +0 -93
- package/skills/data360-semantic-model-mcp-configure/SKILL.md +0 -115
- package/skills/data360-standard-mapping-mcp-configure/SKILL.md +0 -38
- package/skills/data360-tenant-lifecycle-mcp-configure/SKILL.md +0 -73
- package/skills/experience-afv-query/SKILL.md +0 -234
- package/skills/experience-agentforce-vibes-in-react-configure/SKILL.md +0 -63
- package/skills/experience-apex-components-configure/SKILL.md +0 -69
- package/skills/experience-apex-pages-configure/SKILL.md +0 -107
- package/skills/experience-app-home-configure/SKILL.md +0 -76
- package/skills/experience-aura-lightning-out-access-configure/SKILL.md +0 -58
- package/skills/experience-briefcase-configure/SKILL.md +0 -287
- package/skills/experience-community-flexi-page-list-create/SKILL.md +0 -74
- package/skills/experience-community-template-definition-list-query/SKILL.md +0 -48
- package/skills/experience-community-theme-definition-list-query/SKILL.md +0 -38
- package/skills/experience-content-assets-configure/SKILL.md +0 -86
- package/skills/experience-custom-domain-create/SKILL.md +0 -727
- package/skills/experience-defer-rendering-workspace-page-setup-configure/SKILL.md +0 -41
- package/skills/experience-field-service-app-builder-configure/SKILL.md +0 -187
- package/skills/experience-flow-category-configure/SKILL.md +0 -117
- package/skills/experience-formula-configure/SKILL.md +0 -358
- package/skills/experience-global-actions-configure/SKILL.md +0 -69
- package/skills/experience-global-publisher-layouts-configure/SKILL.md +0 -79
- package/skills/experience-instrumentation-configure/SKILL.md +0 -64
- package/skills/experience-lex-engagement-configure/SKILL.md +0 -50
- package/skills/experience-lightning-bolt-open/SKILL.md +0 -12
- package/skills/experience-lightning-out-configure/SKILL.md +0 -129
- package/skills/experience-lightning-preview-configure/SKILL.md +0 -67
- package/skills/experience-lightning-types-query/SKILL.md +0 -98
- package/skills/experience-malware-scan-configure/SKILL.md +0 -71
- package/skills/experience-my-salesforce-configure/SKILL.md +0 -126
- package/skills/experience-navigation-menus-configure/SKILL.md +0 -235
- package/skills/experience-notification-types-configure/SKILL.md +0 -206
- package/skills/experience-notifications-configure/SKILL.md +0 -75
- package/skills/experience-record-discovery-query/SKILL.md +0 -227
- package/skills/experience-regenerate-previews-open/SKILL.md +0 -94
- package/skills/experience-sales-cloud-mab-configure/SKILL.md +0 -254
- package/skills/experience-schema-builder-open/SKILL.md +0 -38
- package/skills/experience-simple-record-home-configure/SKILL.md +0 -110
- package/skills/experience-static-resources-configure/SKILL.md +0 -74
- package/skills/field-service-setup-coordinate/SKILL.md +0 -62
- package/skills/field-service-work-plan-configure/SKILL.md +0 -253
- package/skills/fsc-actionable-segmentation-settings-configure/SKILL.md +0 -180
- package/skills/fsc-digital-origination-bre-decision-matrix-foundation-create/SKILL.md +0 -196
- package/skills/fsc-digital-origination-bre-disclosures-consent-configure/SKILL.md +0 -106
- package/skills/fsc-digital-origination-bre-document-upload-configure/SKILL.md +0 -96
- package/skills/fsc-digital-origination-bre-permissions-assign/SKILL.md +0 -111
- package/skills/fsc-digital-origination-bre-setup-coordinate/SKILL.md +0 -250
- package/skills/fsc-digital-origination-bre-stp-eligibility-configure/SKILL.md +0 -122
- package/skills/fsc-digital-origination-coordinate/SKILL.md +0 -653
- package/skills/fsc-digital-origination-demo-run/SKILL.md +0 -225
- package/skills/fsc-digital-origination-execution-guardrails-validate/SKILL.md +0 -112
- package/skills/fsc-digital-origination-initial-setup-configure/SKILL.md +0 -396
- package/skills/fsc-digital-origination-pricing-setup-coordinate/SKILL.md +0 -336
- package/skills/fsc-digital-origination-pricing-setup-data-foundation-create/SKILL.md +0 -208
- package/skills/fsc-digital-origination-pricing-setup-procedure-create/SKILL.md +0 -375
- package/skills/fsc-digital-origination-product-setup-act1-permissions-assign/SKILL.md +0 -83
- package/skills/fsc-digital-origination-product-setup-coordinate/SKILL.md +0 -248
- package/skills/fsc-digital-origination-sample-data-create/SKILL.md +0 -206
- package/skills/fsc-document-checklist-settings-configure/SKILL.md +0 -57
- package/skills/fsc-flexible-hierarchy-configure/SKILL.md +0 -148
- package/skills/fsc-flexible-hierarchy-foundation-configure/SKILL.md +0 -1430
- package/skills/fsc-flexible-hierarchy-graph-config-create/SKILL.md +0 -471
- package/skills/fsc-flexible-hierarchy-rule-based-graph-deploy/SKILL.md +0 -429
- package/skills/fsc-pricing-product-configurator-configure/SKILL.md +0 -150
- package/skills/fsc-pricing-salesforce-omnistudio-switch/SKILL.md +0 -123
- package/skills/fsc-product-act2-catalog-categories-create/SKILL.md +0 -82
- package/skills/fsc-product-act3-attributes-create/SKILL.md +0 -249
- package/skills/fsc-product-act4-classification-assignment-create/SKILL.md +0 -196
- package/skills/fsc-product-act5-considerations-get/SKILL.md +0 -44
- package/skills/fsc-stage-management-apex-flow-deploy/SKILL.md +0 -384
- package/skills/fsc-stage-management-compliant-data-sharing-configure/SKILL.md +0 -144
- package/skills/fsc-stage-management-decision-matrices-create/SKILL.md +0 -107
- package/skills/fsc-stage-management-definition-assignments-create/SKILL.md +0 -189
- package/skills/fsc-stage-management-definition-create/SKILL.md +0 -108
- package/skills/fsc-stage-management-permissions-assign/SKILL.md +0 -143
- package/skills/fsc-stage-management-transitions-configure/SKILL.md +0 -139
- package/skills/health-cloud-appt-booking-config-configure/SKILL.md +0 -135
- package/skills/health-cloud-appt-booking-url-config-configure/SKILL.md +0 -134
- package/skills/health-cloud-care-provider-affl-role-config-configure/SKILL.md +0 -136
- package/skills/health-cloud-care-provider-search-config-configure/SKILL.md +0 -134
- package/skills/health-cloud-care-requests-create/SKILL.md +0 -178
- package/skills/health-cloud-initial-configure/SKILL.md +0 -511
- package/skills/health-cloud-patient-appointment-scheduling-configure/SKILL.md +0 -1374
- package/skills/health-cloud-provider-search-settings-configure/SKILL.md +0 -924
- package/skills/health-cloud-referral-management-coordinate/SKILL.md +0 -513
- package/skills/health-cloud-timeline-configure/SKILL.md +0 -622
- package/skills/health-cloud-virtual-visit-config-configure/SKILL.md +0 -135
- package/skills/industries-account-score-settings-query/SKILL.md +0 -78
- package/skills/industries-actionable-list-data-sources-dmo-configure/SKILL.md +0 -177
- package/skills/industries-ad-product-availability-search/SKILL.md +0 -399
- package/skills/industries-advanced-account-forecast-settings-configure/SKILL.md +0 -628
- package/skills/industries-advanced-therapy-management-settings-configure/SKILL.md +0 -73
- package/skills/industries-atm-settings-starter-configure/SKILL.md +0 -76
- package/skills/industries-batch-document-ai-configure/SKILL.md +0 -196
- package/skills/industries-behavioral-health-app-settings-configure/SKILL.md +0 -71
- package/skills/industries-branch-management-settings-configure/SKILL.md +0 -89
- package/skills/industries-bre-decision-table-access-configure/SKILL.md +0 -367
- package/skills/industries-brokerage-settings-configure/SKILL.md +0 -41
- package/skills/industries-calendar-sync-settings-configure/SKILL.md +0 -89
- package/skills/industries-care-request-settings-configure/SKILL.md +0 -218
- package/skills/industries-case-management-intelligence-settings-configure/SKILL.md +0 -54
- package/skills/industries-catalog-process-attributes-products-configure/SKILL.md +0 -380
- package/skills/industries-catalog-process-fulfillment-configure/SKILL.md +0 -216
- package/skills/industries-catalog-process-intake-configure/SKILL.md +0 -219
- package/skills/industries-catalog-process-knowledge-configure/SKILL.md +0 -153
- package/skills/industries-catalog-process-preprocessor-configure/SKILL.md +0 -168
- package/skills/industries-cds-general-settings-configure/SKILL.md +0 -69
- package/skills/industries-claim-financial-settings-configure/SKILL.md +0 -169
- package/skills/industries-clinical-data-model-settings-configure/SKILL.md +0 -136
- package/skills/industries-clinical-data-model-settings-starter-configure/SKILL.md +0 -105
- package/skills/industries-collection-plan-settings-configure/SKILL.md +0 -132
- package/skills/industries-comms-service-console-settings-configure/SKILL.md +0 -159
- package/skills/industries-compliance-configure/SKILL.md +0 -102
- package/skills/industries-compliance-document-extraction-setup-configure/SKILL.md +0 -76
- package/skills/industries-contact-center-app-layout-configure/SKILL.md +0 -88
- package/skills/industries-contact-center-components-configure/SKILL.md +0 -96
- package/skills/industries-contact-center-path-knowledge-configure/SKILL.md +0 -95
- package/skills/industries-contact-center-user-access-assign/SKILL.md +0 -96
- package/skills/industries-course-waitlist-config-configure/SKILL.md +0 -162
- package/skills/industries-crisis-center-settings-configure/SKILL.md +0 -84
- package/skills/industries-custom-object-settings-configure/SKILL.md +0 -94
- package/skills/industries-data-cloud-integration-configure/SKILL.md +0 -88
- package/skills/industries-data-space-feature-mappings-configure/SKILL.md +0 -245
- package/skills/industries-decision-matrix-builder-configure/SKILL.md +0 -78
- package/skills/industries-decision-table-hbase-configure/SKILL.md +0 -87
- package/skills/industries-decision-table-version-configure/SKILL.md +0 -74
- package/skills/industries-decision-tables-builder-configure/SKILL.md +0 -253
- package/skills/industries-decision-tables-configure/SKILL.md +0 -439
- package/skills/industries-energy-utilities-configure/SKILL.md +0 -251
- package/skills/industries-eu-cloud-multisite-configure/SKILL.md +0 -1008
- package/skills/industries-eu-new-connections-configure/SKILL.md +0 -30
- package/skills/industries-explainability-msg-template-configure/SKILL.md +0 -135
- package/skills/industries-expression-set-message-token-configure/SKILL.md +0 -135
- package/skills/industries-field-service-settings-configure/SKILL.md +0 -82
- package/skills/industries-form-framework-settings-configure/SKILL.md +0 -30
- package/skills/industries-fsc-ai-settings-configure/SKILL.md +0 -57
- package/skills/industries-fsc-association-engine-settings-configure/SKILL.md +0 -172
- package/skills/industries-fsc-b2b-settings-configure/SKILL.md +0 -61
- package/skills/industries-fsc-insurance-settings-configure/SKILL.md +0 -58
- package/skills/industries-fsc-visa-fulfillment-setup-configure/SKILL.md +0 -103
- package/skills/industries-fsc-wealth-agent-settings-configure/SKILL.md +0 -117
- package/skills/industries-fsc-wealth-settings-configure/SKILL.md +0 -99
- package/skills/industries-fundraising-gift-entry-settings-configure/SKILL.md +0 -120
- package/skills/industries-fundraising-rfm-configure/SKILL.md +0 -128
- package/skills/industries-fundraising-settings-configure/SKILL.md +0 -145
- package/skills/industries-fundraising-source-code-gen-configure/SKILL.md +0 -299
- package/skills/industries-google-maps-api-key-settings-configure/SKILL.md +0 -87
- package/skills/industries-grantmaking-intelligence-settings-open/SKILL.md +0 -58
- package/skills/industries-hc-score-category-settings-configure/SKILL.md +0 -167
- package/skills/industries-health-engagement-settings-configure/SKILL.md +0 -218
- package/skills/industries-home-health-agentforce-setup-configure/SKILL.md +0 -131
- package/skills/industries-home-health-bundling-policy-create/SKILL.md +0 -50
- package/skills/industries-home-health-entity-labels-configure/SKILL.md +0 -29
- package/skills/industries-home-health-fsl-package-deploy/SKILL.md +0 -71
- package/skills/industries-home-health-fsl-settings-validate/SKILL.md +0 -27
- package/skills/industries-home-health-guided-setup-care-and-skill-get/SKILL.md +0 -80
- package/skills/industries-home-health-guided-setup-configure/SKILL.md +0 -836
- package/skills/industries-home-health-guided-setup-enable-org-fsl-get/SKILL.md +0 -55
- package/skills/industries-home-health-guided-setup-get-org-ready-get/SKILL.md +0 -61
- package/skills/industries-home-health-licenses-assign/SKILL.md +0 -27
- package/skills/industries-home-health-operating-hours-create/SKILL.md +0 -40
- package/skills/industries-home-health-scheduling-policy-create/SKILL.md +0 -41
- package/skills/industries-home-health-service-objective-create/SKILL.md +0 -22
- package/skills/industries-home-health-skills-create/SKILL.md +0 -31
- package/skills/industries-home-health-users-create/SKILL.md +0 -29
- package/skills/industries-icm-act3-toggles-configure/SKILL.md +0 -198
- package/skills/industries-icm-act5-genai-suggested-assessments-configure/SKILL.md +0 -361
- package/skills/industries-icm-act6-mcg-integration-configure/SKILL.md +0 -550
- package/skills/industries-integrated-care-management-configure/SKILL.md +0 -168
- package/skills/industries-object-enablement-configure/SKILL.md +0 -86
- package/skills/industries-tpm-system-processing-service-configure/SKILL.md +0 -64
- package/skills/integration-apex-settings-configure/SKILL.md +0 -61
- package/skills/marketing-e360-email-archiving-configure/SKILL.md +0 -73
- package/skills/platform-custom-permissions-configure/SKILL.md +0 -687
- package/skills/platform-label-workbench-import-create/SKILL.md +0 -67
- package/skills/platform-privacy-agent-settings-configure/SKILL.md +0 -752
|
@@ -1,1430 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: fsc-flexible-hierarchy-foundation-configure
|
|
3
|
-
description: "Financial Services Cloud Flexible Hierarchy foundation setup — confirm org connectivity, validate prerequisites, enable the feature, assign the Flexible Hierarchies permission sets and ARC access via whichever ARC-granting permission set (`FSCSales` / `FSCService` / `FinancialServicesCloudExtension`) is actually present on the org, configure hierarchy node roles, add the hierarchy component to record pages, and create the hierarchy type. Full detail for the fsc-flexible-hierarchy-configure skill."
|
|
4
|
-
metadata:
|
|
5
|
-
relatedSkills:
|
|
6
|
-
- fsc-flexible-hierarchy-configure
|
|
7
|
-
- platform-flexipage-generate
|
|
8
|
-
version: "1.0"
|
|
9
|
-
cliTools:
|
|
10
|
-
- tool:
|
|
11
|
-
- "python3"
|
|
12
|
-
semver: ">=3.8"
|
|
13
|
-
- tool:
|
|
14
|
-
- "sf"
|
|
15
|
-
semver: ">=2.0.0"
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# Enable & Configure the Foundation
|
|
19
|
-
|
|
20
|
-
Full detail for the [`fsc-flexible-hierarchy-configure`](../../../SKILL.md) skill, whose scope is currently
|
|
21
|
-
limited to this foundation/enablement phase. Building an actual hierarchy instance (parsing a
|
|
22
|
-
reference artifact, creating nodes/relations, rollup metrics, agent activation) is out of scope
|
|
23
|
-
for this skill for now.
|
|
24
|
-
|
|
25
|
-
## Sequencing — run one step at a time, never batch
|
|
26
|
-
|
|
27
|
-
This skill is multi-turn: process the steps below one at a time, in the order the conversation
|
|
28
|
-
actually needs. For each step, ask **only that step's query**, wait for the answer, then execute
|
|
29
|
-
that step's write (or gate) before moving on. **Never bundle a later step's question into the
|
|
30
|
-
same message as an earlier one, and never collect several steps' answers up front.** This rule
|
|
31
|
-
applies in full even if you're serving this skill directly rather than being routed here from the
|
|
32
|
-
parent `fsc-flexible-hierarchy-configure` skill — it is not context you're expected to have
|
|
33
|
-
carried over from elsewhere.
|
|
34
|
-
|
|
35
|
-
## Session state (track across the conversation)
|
|
36
|
-
|
|
37
|
-
This skill is multi-turn and branch-driven — thread this state across turns rather than
|
|
38
|
-
re-deriving it, and never lose a decision the admin already made:
|
|
39
|
-
|
|
40
|
-
- `target_org_alias` — org being configured; confirmed before any write.
|
|
41
|
-
- `org_state` — the Step 1 detection result: feature pref already on? hierarchy type(s) already
|
|
42
|
-
present? permission sets already assigned to some users? Feeds every check-before-write.
|
|
43
|
-
- `prereqs` — the Step 2 checklist result per item (Flexible Hierarchy org perm, ARC org
|
|
44
|
-
perm, admin access), each ✅/❌ with the value actually queried.
|
|
45
|
-
- `feature_pref_state` — `enableFlexibleHierarchyPref` value confirmed by **re-read** after Step 3,
|
|
46
|
-
not the deploy result.
|
|
47
|
-
- `rule_based_pref_state` — the optional Step 4 result: `enableRuleBasedHierarchyPref` value confirmed
|
|
48
|
-
by **re-read**, and which terminal state this run reached — `skipped` (opt-in declined), `already-on`
|
|
49
|
-
(check-before-write found it true), `declined-at-confirm` (backed out at the irreversibility gate),
|
|
50
|
-
or `enabled` (turned on and verified by re-read). This preference is **one-way** — once `enabled`,
|
|
51
|
-
never re-toggle or offer to disable it.
|
|
52
|
-
- `arc_permset` — the Step 5 lead-in result: which permission set on **this org** actually grants
|
|
53
|
-
ARC access (`FinancialServices2UserAccess`) — resolved once, before the per-user loop, by querying
|
|
54
|
-
which of the known candidates (`FSCSales` / `FSCService` / `FinancialServicesCloudExtension`) exist
|
|
55
|
-
on the org. Reused for every user in the loop; never re-resolved per user.
|
|
56
|
-
- `user_permset_list` — the per-user `{user, permission set, arc?}` list accumulated in Step 5 from
|
|
57
|
-
**individual** answers (never one permission set applied to the whole batch), plus each user's ARC
|
|
58
|
-
(`arc_permset`) choice. Each user is confirmed with a per-user go-ahead and written **immediately**,
|
|
59
|
-
right before moving to the next user (pick → role → ARC → confirm → write per user); this list is
|
|
60
|
-
the running record of who's been handled for the end-of-step report, not a batch collected up front
|
|
61
|
-
and deployed at the end.
|
|
62
|
-
- `object_permissions` — the optional Step 6 result: which profile (if any) the admin
|
|
63
|
-
chose to grant object CRUD on the master `FlexibleHierarchy` (the two detail objects inherit it),
|
|
64
|
-
the access level, and whether the step was skipped.
|
|
65
|
-
- `node_role_values` — the comma-separated role picklist values the admin gave for Step 7.
|
|
66
|
-
- `record_page_objects` — which of the 11 objects the admin confirmed for Step 8 (Account by default).
|
|
67
|
-
- `hierarchy_type` — the confirmed type name handed to Step 9.
|
|
68
|
-
- `hierarchy_config_mode` — Step 9's modality result: `bespoke` (the only value when
|
|
69
|
-
`rule_based_pref_state` isn't `already-on`/`enabled`, or when it is but the admin picked Bespoke
|
|
70
|
-
anyway) or `rule-based` (admin picked Rule Based Configuration at the modality gate). Determines
|
|
71
|
-
which sub-skill Step 9 delegates to — `graph-config-create` or `fsc-flexible-hierarchy-rule-based-graph-config-create`.
|
|
72
|
-
|
|
73
|
-
## Entry point — route on the admin's actual ask
|
|
74
|
-
|
|
75
|
-
An unqualified "set up / enable Flexible Hierarchies" runs Steps 1–9 in order. A narrow ask should
|
|
76
|
-
start at the matching step (still verifying the earlier steps' gates first — e.g. you can't assign a
|
|
77
|
-
permset if the license prereq in Step 2 fails), not restart at Step 1:
|
|
78
|
-
|
|
79
|
-
| Admin ask signal | Where to start | What to run |
|
|
80
|
-
|---|---|---|
|
|
81
|
-
| "Set up / enable Flexible Hierarchies" (unqualified) | Step 1 | Steps 1–9 in order |
|
|
82
|
-
| "Enable the Flexible Hierarchies feature" | Step 3 | Verify Step 2 gate, then Step 3 |
|
|
83
|
-
| "Enable Rule-Based Hierarchy / `RuleBasedHierarchyPref`" | Step 4 | Verify Step 2 + Step 3 gates, then Step 4 (optional, irreversible — opt-in + double-confirm) |
|
|
84
|
-
| "Assign the Flexible Hierarchy Manager/Admin/User permset to \<user\>" / "give \<user\> ARC access" | Step 5 | Verify Step 2 gate, then Step 5 for those users |
|
|
85
|
-
| "Grant object permissions on the Flexible Hierarchy objects to \<profile\>" | Step 6 | Step 6 only |
|
|
86
|
-
| "Configure the hierarchy node role picklist" | Step 7 | Step 7 only |
|
|
87
|
-
| "Add the Flexible Hierarchy component to the \<object\> record page" | Step 8 | Step 8 only |
|
|
88
|
-
| "Create a \<Legal Entity/…\> hierarchy type" | Step 9 | Verify prereqs, then Step 9 → modality gate (if Rule-Based pref is on) → bespoke or rule-based sub-skill |
|
|
89
|
-
|
|
90
|
-
## Transport & deploy discipline
|
|
91
|
-
|
|
92
|
-
Applies to every write below — hoisted here so it isn't re-stated per step:
|
|
93
|
-
|
|
94
|
-
1. **Prefer `dispatch` over CLI.** Use the canonical operation paths against the live org; CLI
|
|
95
|
-
(`sf project deploy`, `sfdx`) is a fallback only where no API path exists.
|
|
96
|
-
2. **Dry-run first.** Before each write, state the operation + payload (which pref, which permset
|
|
97
|
-
Id, which StandardValueSet values) so the admin can review scope.
|
|
98
|
-
3. **Split deploy per step.** One step's write at a time — don't batch the pref deploy, permset
|
|
99
|
-
assignments, node-role SVS, FlexiPage, and RGD into one transaction. Each has its own confirm.
|
|
100
|
-
4. **Re-read to verify — a deploy result can lie.** `IndustriesSettings` and other metadata deploys
|
|
101
|
-
can report `changed=true` / "Succeeded" while an access gate silently no-ops the change. **Always
|
|
102
|
-
re-read the setting/record after deploying and confirm the new value stuck** — never trust the
|
|
103
|
-
deploy response alone. (Proven on this skill: the Step 3 pref deploy returns success, and only the
|
|
104
|
-
re-read confirms `enableFlexibleHierarchyPref` actually flipped.)
|
|
105
|
-
5. **Ground the final report in reads.** Report done from what you re-read back, not from write
|
|
106
|
-
responses.
|
|
107
|
-
6. **Config ≠ data — this is a mixed-transport skill; use the right one per step.**
|
|
108
|
-
- **Data records → REST/SOQL create**, *not* MDAPI: `PermissionSetAssignment` (Step 5). Never try
|
|
109
|
-
to MDAPI-deploy a permission-set assignment.
|
|
110
|
-
- **Metadata → MDAPI deploy** (via `/headless/metadata`): the `IndustriesSettings`
|
|
111
|
-
`enableFlexibleHierarchyPref` (Step 3) and — optionally, one-way — `enableRuleBasedHierarchyPref`
|
|
112
|
-
(Step 4), both PUT-only on the `IndustriesSettings` singleton;
|
|
113
|
-
the `Profile` `objectPermissions` (Step 6),
|
|
114
|
-
the `FlexiPage` (Step 8), and the `RelationshipGraphDefinition` (Step 9).
|
|
115
|
-
- **Metadata → genuine MDAPI CLI, *not* the facade** (`sf project retrieve` / `sf project deploy`):
|
|
116
|
-
the `FlexibleHierarchyNodeRole` `StandardValueSet` (Step 7). The `/headless/metadata` facade
|
|
117
|
-
blocks BOTH directions for this type (confirmed live — see Step 7 below) — this is the one
|
|
118
|
-
metadata write in this skill that must bypass `dispatch` entirely, not a dispatch-first,
|
|
119
|
-
CLI-only-as-fallback case like the others above.
|
|
120
|
-
|
|
121
|
-
**If you fall back to the `sf` CLI (no `dispatch` available), two setup gotchas will look like org
|
|
122
|
-
problems but aren't.** Both bit a real run:
|
|
123
|
-
- **`sf project retrieve/deploy` needs a DX project scaffold.** Run from a dir with a minimal
|
|
124
|
-
`sfdx-project.json` (a `packageDirectories` entry, e.g. `force-app`) or the command fails with
|
|
125
|
-
`InvalidProjectWorkspaceError: This directory does not contain a valid Salesforce DX project` —
|
|
126
|
-
which reads like a connection/auth failure but is just a missing scaffold. Create it **once** up
|
|
127
|
-
front, before the first retrieve, and reuse it for every step's write.
|
|
128
|
-
- **Build manifests and metadata XML with a file-writing tool, not shell heredocs.** A mistyped
|
|
129
|
-
heredoc terminator silently writes the *trailing shell commands* into the manifest instead of
|
|
130
|
-
closing it, producing a corrupt `package.xml` that then fails opaquely downstream. Every write in
|
|
131
|
-
this skill (`package.xml`, the settings/profile/SVS/FlexiPage/RGD components) is small and
|
|
132
|
-
known-shape — author it as a file directly rather than piping a heredoc through the shell. (This is
|
|
133
|
-
distinct from the quote-escaping note below, which is about inline `python3 -c` formatting code, not
|
|
134
|
-
metadata files.)
|
|
135
|
-
|
|
136
|
-
**User-facing prompt language — never expose internal step numbers.** In anything the admin sees —
|
|
137
|
-
questions, option labels, skip choices — refer to the *work*, never the skill's ordinal. Every
|
|
138
|
-
optional step must offer a way out, and that option is always labelled **"Skip this step"** (or
|
|
139
|
-
"skip <the work>", e.g. "skip adding the record-page component"), **never "Skip Step 6/7/8/9."** This
|
|
140
|
-
applies to every skip/opt-out throughout the skill, not just one step.
|
|
141
|
-
|
|
142
|
-
**Free-text inputs must use a real text prompt — never a fixed-option picker.** One input in this
|
|
143
|
-
foundation skill is open free-text, not a selection from a known set: the node-role picklist values
|
|
144
|
-
(Step 7) — the admin invents them, so there's no list to pick from. Ask it as a plain free-text
|
|
145
|
-
question the admin types into. **If the only question mechanism available forces fixed selectable
|
|
146
|
-
options with no real text field** — e.g. an `AskUserQuestion`-style tool where free text arrives only
|
|
147
|
-
via an auto-added "Other" — **do not use it for this input**: a label like "Enter role values" inside
|
|
148
|
-
such a picker is a *dead option* (selecting it captures the literal label string, with nowhere to
|
|
149
|
-
type the actual values). Ask as a plain free-text turn and read the answer from the admin's reply.
|
|
150
|
-
(This class of bug bit a real run.) Note the **record-page objects (Step 8) are NOT free-text** —
|
|
151
|
-
they're a selection from the fixed 11-object set, so they use a multiple-choice picker (no typed
|
|
152
|
-
list); and the hierarchy-type name (handled in the bespoke sub-skill) remains free-text there.
|
|
153
|
-
|
|
154
|
-
**API-version floor — deploy at the org's max supported API version, not the CLI default; v66.0+ is a
|
|
155
|
-
supported floor, don't invent a stricter one.** The
|
|
156
|
-
`enableFlexibleHierarchyPref` field and the FSC objects
|
|
157
|
-
(`FlexibleHierarchy`, `FlexibleHierarchyNode`, `RelationshipGraphDefinition`) **do not exist at older
|
|
158
|
-
API versions** — deploying at an older version fails with `Property 'enableFlexibleHierarchyPref' not
|
|
159
|
-
valid in version <n>.0`, and those sObjects describe as "not supported"; at a recent enough version
|
|
160
|
-
the deploy succeeds and the objects come online. If a deploy is rejected as an invalid property, or
|
|
161
|
-
an FSC object reads as "not supported," **suspect the API version before concluding the org isn't
|
|
162
|
-
provisioned** — the two failure modes look identical but the fix is a version bump, not a licensing
|
|
163
|
-
escalation. **Don't hardcode a version number, and don't flag a discovered max version as a blocker
|
|
164
|
-
just because it isn't the newest release** — this skill's writes are confirmed working from **API
|
|
165
|
-
v66.0 and above**; a discovered max of v66.0, v67.0, v68.0, etc. is a fine floor, not a gap to report
|
|
166
|
-
to the admin or ask them how to proceed about. Discover the org's max supported API version at
|
|
167
|
-
connect time (Step 1) — e.g. the highest entry from `GET /services/data/` — pin every write in this
|
|
168
|
-
skill to that discovered version, and **don't re-verify it again in later steps** — one discovery at
|
|
169
|
-
connect time covers the whole run.
|
|
170
|
-
|
|
171
|
-
**Inline scripting to format query results — avoid the quote-escaping trap.** Several steps format
|
|
172
|
-
live query results into a picker or table for the admin (the Step 5 user picker `Name — Username`,
|
|
173
|
-
the Step 6 profile picker, the permission/assignment tables). If you build these with
|
|
174
|
-
an inline `python3 -c "..."` wrapped in a **double-quoted** shell string, **do not reuse `"` inside
|
|
175
|
-
the Python, and never backslash-escape quotes inside an f-string expression** — `f"{x[\"Name\"]}"`
|
|
176
|
-
fails with `SyntaxError: f-string expression part cannot include a backslash` (bit a real run on the
|
|
177
|
-
Step 5 user picker). Use single quotes inside instead (`f"{x['Name']}"`), or pass the code via a
|
|
178
|
-
heredoc / temp `.py` file. Better still, apply the same read-then-parse hygiene as the `sf` CLI note
|
|
179
|
-
in Step 6: dump the query result to a file and parse the file, rather than piping formatted output
|
|
180
|
-
through a fragile one-liner.
|
|
181
|
-
|
|
182
|
-
## What this skill does
|
|
183
|
-
|
|
184
|
-
1. **Authenticate + confirm org connectivity.** Before touching anything, confirm the target org
|
|
185
|
-
is authenticated and reachable — resolve the alias/username, confirm a live connection, and
|
|
186
|
-
**discover the org's max supported API version** (e.g. the highest entry from `GET /services/data/`),
|
|
187
|
-
which every later write pins to. That's the whole of this step: **just connectivity.** Do **not** probe
|
|
188
|
-
feature-preference state, permission-set assignments, or object existence here — those reads
|
|
189
|
-
belong to the steps that own them (the pref to Step 3, assignments to Step 5, existing hierarchy
|
|
190
|
-
types to Step 9), each of which does its own check-before-write when it runs.
|
|
191
|
-
2. **Validate true prerequisites. Surface these as an explicit, itemized checklist up front —
|
|
192
|
-
one reported line per item with its live value — not a silent internal gate.** Report each
|
|
193
|
-
as ✅/❌ with the value actually queried, present the whole checklist even when everything
|
|
194
|
-
passes:
|
|
195
|
-
- **License / provisioning** — the **Flexible Hierarchy** org permission (a provisioned
|
|
196
|
-
permission) must be granted by SKU/entitlement; this is not admin-toggleable — if
|
|
197
|
-
absent, the feature cannot be enabled at all (Step 3 will find the preference ungated and
|
|
198
|
-
stop). Confirm the platform license named `FlexibleHierarchy-1` is present (its
|
|
199
|
-
`PermissionSetLicense` `DeveloperName` is `FlexibleHierarchyPsl` — note it does **not** contain
|
|
200
|
-
"FSC", so a `LIKE '%FSC%'` license scan won't surface it; query it by its own name).
|
|
201
|
-
**Do NOT gate this step on describing the `FlexibleHierarchy` / `FlexibleHierarchyNode` /
|
|
202
|
-
`RelationshipGraphDefinition` sObjects.** Those sObjects do **not** exist until Step 3 enables
|
|
203
|
-
the feature — on a fresh, correctly-licensed org they describe as **"not supported"** and a
|
|
204
|
-
`SELECT ... FROM FlexibleHierarchy` returns `sObject type ... is not supported`. That is the
|
|
205
|
-
*expected* pre-enablement state, **not** a missing-provisioning signal; treat the platform
|
|
206
|
-
license (above) as the pre-enablement proxy for the org permission, and expect the sObjects to
|
|
207
|
-
come online only *after* Step 3. (They become the read surface for Step 9's read-back once the
|
|
208
|
-
feature is on.)
|
|
209
|
-
- **Actionable Relationship Center (ARC) enabled** — the **ARC** org permission (a provisioned
|
|
210
|
-
permission).
|
|
211
|
-
Unlike Flexible Hierarchy, ARC has **no separate admin-toggleable preference** — this
|
|
212
|
-
permission alone gates the `RelationshipGraphDefinition` object Step 9 creates records in
|
|
213
|
-
and the user-level `FinancialServices2UserAccess` permission Step 5 assigns, so it's
|
|
214
|
-
check-only here, not something to enable. It's typically bundled in via a
|
|
215
|
-
Permission Set License such as `FSCSales` / `FSCService` / `FinancialServicesCloudExtension`
|
|
216
|
-
— if absent, report it and note ARC access (Step 5) can't proceed until it's provisioned.
|
|
217
|
-
**Which of those PSLs is present varies by SKU** (e.g. an org provisioned via the
|
|
218
|
-
`FSCServiceAddon` SKU has `FSCService`, not `FSCSales`) — this check only confirms ARC is
|
|
219
|
-
provisioned *at all*; Step 5 resolves *which specific permission set* to assign from
|
|
220
|
-
whatever's actually on this org, never assuming `FSCSales` specifically.
|
|
221
|
-
- **Admin access** to the org.
|
|
222
|
-
|
|
223
|
-
Any unmet item → report which one, redirect to Salesforce/the license add-on process, **stop**.
|
|
224
|
-
These cannot be fixed by this skill; they're the customer's or Salesforce's provisioning
|
|
225
|
-
decisions, not something to work around. Do not attempt Step 3 without the org permission
|
|
226
|
-
confirmed present. Present the whole checklist even when everything passes, so the admin sees
|
|
227
|
-
what was verified rather than an unexplained "prereqs OK."
|
|
228
|
-
3. **Enable the Flexible Hierarchies feature, if not already on.** The master toggle is the
|
|
229
|
-
**`FlexibleHierarchyPref`** org preference — MDAPI `IndustriesSettings.enableFlexibleHierarchyPref`
|
|
230
|
-
(boolean) — confirmed live in `FlexibleHierarchyUdd.settings.xml`. **Check its current value
|
|
231
|
-
first via MDAPI, not SOQL** (don't assume it's off): retrieve the `IndustriesSettings` metadata
|
|
232
|
-
(`Settings:Industries`) and read `enableFlexibleHierarchyPref` from it. **Do not attempt to query
|
|
233
|
-
this preference with SOQL** — it is a settings field, not a queryable sObject column, so
|
|
234
|
-
`SELECT enableFlexibleHierarchyPref FROM ...` fails with `INVALID_FIELD` (a "No such column"
|
|
235
|
-
error); that failure means "wrong transport," not "feature absent." The same MDAPI-not-SOQL rule
|
|
236
|
-
applies to reading it back after the deploy. If already on, report that and move on to the next
|
|
237
|
-
step (Step 4, the optional Rule-Based Hierarchy preference). If off, **ask a single explicit
|
|
238
|
-
go-ahead confirm before deploying — `enableFlexibleHierarchyPref` is not reversible; there is no
|
|
239
|
-
supported way to turn it back off once enabled** (lighter than Step 4's double-confirm, since
|
|
240
|
-
Step 4 gates a second, independently-irreversible preference stacked on top of this one). Only
|
|
241
|
-
on that confirm, deploy `IndustriesSettings` with `enableFlexibleHierarchyPref=true` (equivalent
|
|
242
|
-
to the in-product Setup Discovery / Salesforce Go "Enable" action on the Flexible Hierarchy
|
|
243
|
-
tile, which flips this same preference under the hood), then re-read the setting to confirm it
|
|
244
|
-
stuck — don't trust the deploy result alone. This step depends on Step 2's org-permission check: the
|
|
245
|
-
preference's `editAccess` gate requires the **Flexible Hierarchy** org permission already being
|
|
246
|
-
present, so without that permission this deploy will not take effect.
|
|
247
|
-
4. **Enable the Rule-Based Hierarchy preference (optional, IRREVERSIBLE).** Beyond the base feature
|
|
248
|
-
(Step 3), Flexible Hierarchy has a second, separate org preference — **`RuleBasedHierarchyPref`**,
|
|
249
|
-
MDAPI `IndustriesSettings.enableRuleBasedHierarchyPref` (boolean) — that turns on the Rule-Based
|
|
250
|
-
Hierarchy mode. It is a **sibling** of `enableFlexibleHierarchyPref` in the same
|
|
251
|
-
`IndustriesSettings` (`Settings:Industries`) metadata. **Version gate — this optional step needs
|
|
252
|
-
v68.0+:** `enableFlexibleHierarchyPref` (Step 3, the base feature) is present in the retrieved xmlRep
|
|
253
|
-
from API **v66.0+**, but `enableRuleBasedHierarchyPref` appears only from **v68.0+** — at v66.0/v67.0
|
|
254
|
-
the RBH element is absent from the xmlRep entirely. So keep the same **v66.0+** gate as before for the
|
|
255
|
-
base workflow, and treat Step 4 as available **only when the org's pinned max version is v68.0 or
|
|
256
|
-
higher**. If the org is on v66.0/v67.0, **silently ignore Step 4** — record `rule_based_pref_state`
|
|
257
|
-
as skipped (not applicable at this version), move straight to Step 5, and do **not** raise it as a
|
|
258
|
-
blocker or "out-of-range" error to the admin; the RBH element's absence is expected on those
|
|
259
|
-
releases. This step **only flips that preference on** — it does not author any rule content
|
|
260
|
-
itself. Authoring the actual `rules.graph.rootNode` tree (role labels, filters, and
|
|
261
|
-
OneToMany/ManyToMany child relationships) happens later, and only conditionally: Step 9 asks
|
|
262
|
-
whether to build a Bespoke or Rule-Based hierarchy type, and only offers the Rule-Based path when
|
|
263
|
-
this step left `rule_based_pref_state` as `already-on` or `enabled`.
|
|
264
|
-
|
|
265
|
-
This step is **optional AND one-way** — treat it more carefully than the reversible Step 3 toggle.
|
|
266
|
-
Run it as a gated sequence, and do **not** proceed past any gate without an explicit yes:
|
|
267
|
-
|
|
268
|
-
1. **Optional opt-in gate — ask first, using the exact preference name.** Before doing anything,
|
|
269
|
-
ask a plain yes/no using the real pref name so the admin knows exactly what's being toggled:
|
|
270
|
-
> Do you want to enable **`RuleBasedHierarchyPref`** (the Rule-Based Hierarchy mode) on this org?
|
|
271
|
-
> - **Yes**
|
|
272
|
-
> - **Skip this step**
|
|
273
|
-
|
|
274
|
-
On **Skip**, record `rule_based_pref_state` as skipped and move straight to Step 5 — don't read,
|
|
275
|
-
don't deploy, don't ask anything further. (Label the opt-out per the user-facing-language rule —
|
|
276
|
-
"Skip this step", never "Skip Step 4".)
|
|
277
|
-
2. **Check-before-write — read the current value first; it may already be on.** On **Yes**, before
|
|
278
|
-
any deploy, **read `enableRuleBasedHierarchyPref` via MDAPI** (retrieve `IndustriesSettings` /
|
|
279
|
-
`Settings:Industries` and read the element — the same MDAPI-not-SOQL rule as Step 3; a
|
|
280
|
-
`SELECT enableRuleBasedHierarchyPref FROM …` fails `INVALID_FIELD`, which means "wrong
|
|
281
|
-
transport," not "absent"). **An org that already has `FlexibleHierarchyPref` on can also,
|
|
282
|
-
occasionally, already have `RuleBasedHierarchyPref` on** — so don't assume it's off. If the
|
|
283
|
-
re-read shows it is **already `true`**, report that it's already enabled, record
|
|
284
|
-
`rule_based_pref_state` as already-on, and **skip the deploy entirely** — there is nothing to do
|
|
285
|
-
(and nothing could be undone anyway). Only proceed to the confirmation gate when it reads
|
|
286
|
-
`false`.
|
|
287
|
-
3. **Irreversibility double-confirm — this is the extra gate the reversible Step 3 doesn't have.**
|
|
288
|
-
`RuleBasedHierarchyPref` **cannot be turned off once enabled** — there is no supported way to
|
|
289
|
-
disable it afterward. So even though the admin already said Yes in the opt-in gate, **ask a
|
|
290
|
-
second, explicit confirmation that names the irreversibility** before writing:
|
|
291
|
-
> ⚠️ **`RuleBasedHierarchyPref` cannot be disabled once it's turned on.** Do you wish to turn it
|
|
292
|
-
> on?
|
|
293
|
-
> - **Yes, turn it on** (this is permanent)
|
|
294
|
-
> - **No, leave it off**
|
|
295
|
-
|
|
296
|
-
Only on an explicit **Yes, turn it on** do you deploy. On **No**, record `rule_based_pref_state`
|
|
297
|
-
as declined-at-confirm and move on — the admin backed out at the irreversibility gate, which is
|
|
298
|
-
a valid outcome, not an error.
|
|
299
|
-
4. **Deploy, then re-read to verify.** Deploy `IndustriesSettings` with
|
|
300
|
-
`enableRuleBasedHierarchyPref=true` via `/headless/metadata` at the org's max supported API
|
|
301
|
-
version (discovered in Step 1). **`IndustriesSettings` is a singleton settings type — deploy with
|
|
302
|
-
PUT, not POST** (POST returns 400 `UNSUPPORTED_OPERATION`, same as the Step 3 pref deploy). Leave
|
|
303
|
-
`enableFlexibleHierarchyPref` at its current value in the payload (don't flip the base feature off
|
|
304
|
-
as a side effect). Then **re-read `enableRuleBasedHierarchyPref` via MDAPI and confirm it now
|
|
305
|
-
reads `true`** — a deploy "Succeeded" is not proof (the "a deploy result can lie" rule from the
|
|
306
|
-
transport discipline; the pref's `editAccess` gate can silently no-op the change without the
|
|
307
|
-
**Flexible Hierarchy** org perm from Step 2 and the feature from Step 3 both in
|
|
308
|
-
place). Record `rule_based_pref_state` from the re-read, not the deploy response.
|
|
309
|
-
|
|
310
|
-
Depends on Step 2's org-permission check and Step 3's feature enablement: Rule-Based mode sits on
|
|
311
|
-
top of the base Flexible Hierarchy feature, so if the feature preference isn't on (or the org
|
|
312
|
-
permission is absent), this deploy won't take effect — surface that rather than reporting success.
|
|
313
|
-
|
|
314
|
-
5. **Assign user access — a Flexible Hierarchies permission set, and ARC via whichever permission
|
|
315
|
-
set actually grants it on this org.** Three Flexible Hierarchy permission sets exist —
|
|
316
|
-
`FlexibleHierarchiesUser`, `FlexibleHierarchyManager`, `FlexibleHierarchyAdmin` — but **only one
|
|
317
|
-
is needed per user**, matching the role they'll actually play (viewer/user vs. manager vs.
|
|
318
|
-
admin). **Heads-up on the names: they are NOT uniformly pluralized.** The viewer set is plural —
|
|
319
|
-
label "Flexible Hierarch**ies** User", API name `FlexibleHierarchiesUser` — while Manager and Admin
|
|
320
|
-
are singular ("Flexible Hierarchy Manager/Admin", `FlexibleHierarchyManager`/`FlexibleHierarchyAdmin`).
|
|
321
|
-
**Do not "regularize" the viewer set to the singular "Flexible Hierarchy User" / `FlexibleHierarchyUser`
|
|
322
|
-
— that name does not exist on the org, and a lookup for it comes back empty.** (Verified live on an
|
|
323
|
-
FSC org.)
|
|
324
|
-
|
|
325
|
-
**Resolve the ARC permission set once, before anything else in this step — never hardcode
|
|
326
|
-
`FSCSales`.** Step 2 only confirmed the ARC org permission is provisioned; it did not
|
|
327
|
-
pin down *which* permission set on this specific org grants the user-level
|
|
328
|
-
`FinancialServices2UserAccess` permission that backs it, and that varies by SKU (e.g. the
|
|
329
|
-
`FSCServiceAddon` SKU provisions `FSCService`, not `FSCSales` — an org with only `FSCService`
|
|
330
|
-
has no `FSCSales` permission set to assign, and treating `FSCSales` as fixed fails outright on
|
|
331
|
-
that org). Resolve it once per session, not per user:
|
|
332
|
-
1. Query `SELECT Id, Name FROM PermissionSet WHERE Name IN ('FSCSales', 'FSCService',
|
|
333
|
-
'FinancialServicesCloudExtension')` (the known candidates from Step 2's PSL list) to see which
|
|
334
|
-
of them actually exist on this org.
|
|
335
|
-
2. **Exactly one exists** → that's `arc_permset`; use it for every user in the loop below, no
|
|
336
|
-
further prompt.
|
|
337
|
-
3. **More than one exists** → ask the admin once, up front, which one to use for ARC access —
|
|
338
|
-
e.g. *"This org has both `FSCSales` and `FSCService` available for ARC access. Which should I
|
|
339
|
-
assign?"* — and use their answer as `arc_permset` for the whole loop. Don't re-ask per user.
|
|
340
|
-
4. **None exist** → ARC access can't be assigned via a known permission set even though
|
|
341
|
-
the ARC org permission is provisioned; leave `arc_permset` unresolved, report that gap, and treat ARC
|
|
342
|
-
as blocked for the rest of this step rather than guessing a name (inferred — the
|
|
343
|
-
three-candidate list is what Step 2 already documents; verify against a live
|
|
344
|
-
`FSCServiceAddon`-only org and extend the list if a new PSL surfaces). **When `arc_permset` is
|
|
345
|
-
unresolved, bypass every ARC-specific action in the rest of Step 5:** query and report existing
|
|
346
|
-
assignments for the three role permission sets only (not a fourth ARC set), skip the per-user
|
|
347
|
-
ARC prompt (sub-step 3) entirely, and never create an ARC `PermissionSetAssignment`. The
|
|
348
|
-
role-permission-set workflow still runs in full — only the ARC lookup/prompt/create is skipped,
|
|
349
|
-
so the no-candidate org degrades cleanly to "roles assigned, ARC reported as blocked."
|
|
350
|
-
|
|
351
|
-
**First, surface what's already assigned — don't jump straight to collecting new users.** Query
|
|
352
|
-
`PermissionSetAssignment` for the three role permission sets plus the resolved `arc_permset`
|
|
353
|
-
**when ARC is available** — on the no-candidate org from branch 4 above, `arc_permset` is
|
|
354
|
-
unresolved, so query the three role sets only and never reference a fourth ARC set. If any users
|
|
355
|
-
already have them, **show the admin the current assignments as a table (user → permission set,
|
|
356
|
-
and — only when ARC is available — whether they have ARC via `arc_permset`) and
|
|
357
|
-
ask whether any changes are needed** — "Here's who's already set up. Do you want to add/change
|
|
358
|
-
any assignments, or should I proceed to the next step?" If the admin says no changes, **skip the
|
|
359
|
-
rest of this step and move on** — don't re-ask the per-user permission-set questions for users
|
|
360
|
-
who are already correctly assigned. Only when they want changes (or there are no existing
|
|
361
|
-
assignments at all) do you collect the targets below.
|
|
362
|
-
|
|
363
|
-
**Collect targets one user at a time — a pick-then-loop flow, not one big up-front list.** Handle
|
|
364
|
-
each user completely (who → role → ARC) before offering to add another, rather than gathering a
|
|
365
|
-
roster first and asking roles afterward. For each user:
|
|
366
|
-
|
|
367
|
-
1. **Pick the user (single-select).** Query the org's **assignable human users** and present them
|
|
368
|
-
as the options: `SELECT Id, Username, Name, UserType FROM User WHERE IsActive = true` —
|
|
369
|
-
**exclude system/integration users. Filter structurally, not by a hardcoded name list:** keep
|
|
370
|
-
only `UserType = 'Standard'` (drop `AutomatedProcess`, `CsnOnly`, portal/community types, etc.),
|
|
371
|
-
and additionally drop the platform integration/service accounts that still describe as
|
|
372
|
-
`Standard` — those whose username ends in a non-login suffix like `.ext` or matches a known
|
|
373
|
-
integration pattern (e.g. `Automated Process`, `Platform Integration User`, `Insights
|
|
374
|
-
Integration` / `insightsintegration@…`, `Analytics Cloud Integration/Security User`, `Sales
|
|
375
|
-
Insights Integration User`, `B2B/B2C Store Integration User`, `Integration User`, `Security
|
|
376
|
-
User`). When in doubt whether an account is a human login, **leave it out of the picker** rather
|
|
377
|
-
than offering it — a system/integration user should never appear as an assignment target.
|
|
378
|
-
(A real run surfaced `Insights Integration` as an option because the filter only excluded a
|
|
379
|
-
hardcoded name set; the `UserType`/suffix check above closes that gap.) Show each option as
|
|
380
|
-
`Name — Username`. **The picker holds four choices, so cap it: if there are three or fewer
|
|
381
|
-
assignable users, list them all; if there are more than three, show the first three as options
|
|
382
|
-
and make the fourth option "Type a username/email"** (an explicit type-it-in escape). That
|
|
383
|
-
typed-entry option is also the fallback whenever the target isn't among the shown three. Pick
|
|
384
|
-
**one user** here; don't multi-select a batch.
|
|
385
|
-
2. **Pick that user's role (single-select — exactly one).** Present **exactly these three
|
|
386
|
-
options and no others** — this is a fixed, known set, so the picker must NOT carry a fourth
|
|
387
|
-
"Other" / "Type a permission-set name" / free-text option (unlike the user picker in sub-step 1,
|
|
388
|
-
whose targets aren't a fixed set). Any FH permission set a user could need is one of these three;
|
|
389
|
-
a typed/other option here is a dead option that can only capture an invalid value. **Show each
|
|
390
|
-
option's exact label AND API name — the three are NOT uniformly named (see the heads-up in the
|
|
391
|
-
step intro): the viewer set is plural, Manager/Admin are singular. Present the labels verbatim;
|
|
392
|
-
don't regularize the viewer set to "Flexible Hierarchy User".** Present them
|
|
393
|
-
as a single-select so more-than-one is structurally impossible:
|
|
394
|
-
> *"Which Flexible Hierarchy permission set should `<user>` get?*
|
|
395
|
-
> - *Flexible Hierarchies User (`FlexibleHierarchiesUser`) — view and work with hierarchies*
|
|
396
|
-
> - *Flexible Hierarchy Manager (`FlexibleHierarchyManager`) — build and edit hierarchies*
|
|
397
|
-
> - *Flexible Hierarchy Admin (`FlexibleHierarchyAdmin`) — full administration*
|
|
398
|
-
> *(Pick one — each user needs exactly one.)"*
|
|
399
|
-
|
|
400
|
-
**When you resolve the chosen set's Id, match on the EXACT API `Name` above** — e.g.
|
|
401
|
-
`SELECT Id, Name, Label FROM PermissionSet WHERE Name = 'FlexibleHierarchiesUser'`. A
|
|
402
|
-
`WHERE Name LIKE '%FlexibleHierarchy%'` / `Label LIKE '%Flexible Hierarchy %'` scan **silently
|
|
403
|
-
misses the viewer set** (its name/label is "…Hierarch**ies**…", not "…Hierarchy…") — that exact
|
|
404
|
-
miss is what makes "Flexible Hierarchy User" appear not to exist. If you must pattern-match across
|
|
405
|
-
all three at once, use the plural-safe stem `LIKE '%Hierarch%'`. (Verified live on an FSC org:
|
|
406
|
-
`SELECT Name, Label FROM PermissionSet` returns Label "Flexible Hierarchies User" / Name
|
|
407
|
-
`FlexibleHierarchiesUser`, "Flexible Hierarchy Manager" / `FlexibleHierarchyManager`, and
|
|
408
|
-
"Flexible Hierarchy Admin" / `FlexibleHierarchyAdmin`.)
|
|
409
|
-
3. **Confirm that user's ARC access (single-select, still inside the loop).** **Skip this
|
|
410
|
-
sub-step entirely when `arc_permset` is unresolved** (the no-candidate branch 4 above) — there
|
|
411
|
-
is no ARC-granting permission set to assign, so don't prompt for ARC and set this user's `arc?`
|
|
412
|
-
to "blocked"; go straight to sub-step 4 with the role permission set only. Otherwise, right
|
|
413
|
-
after the role, handle **this** user's ARC access (the per-user ARC question detailed below) — keep each
|
|
414
|
-
user's full setup together rather than batching ARC into a separate pass. **Frame ARC as
|
|
415
|
-
required, not optional:** Actionable Relationship Center is what backs the
|
|
416
|
-
`RelationshipGraphDefinition` object hierarchy operations run against, so a user cannot actually
|
|
417
|
-
view or work with hierarchies without it. Word the prompt to say ARC is **required to perform
|
|
418
|
-
hierarchy operations** and default to Yes — e.g. *"`<user>` needs ARC access to work with
|
|
419
|
-
hierarchies. Assign it now? (Recommended — hierarchy operations don't work without it.)"* Only
|
|
420
|
-
an admin who explicitly declines for a specific user skips it; don't present it as a neutral,
|
|
421
|
-
equally-weighted yes/no.
|
|
422
|
-
4. **Confirm THIS user's assignment, then write it — one go-ahead right before the write.** Once
|
|
423
|
-
you have this user's `{user, permission set, arc?}`, show that one user's line back and ask for a
|
|
424
|
-
go-ahead just for them, immediately before creating their `PermissionSetAssignment`(s):
|
|
425
|
-
|
|
426
|
-
> Assign `<Name — Username>` the `<FlexibleHierarchyManager>` permission set (plus ARC via
|
|
427
|
-
> `<arc_permset>`)? (yes / change / skip)
|
|
428
|
-
|
|
429
|
-
On *yes*, write **this user's** assignments now — the role permission set, plus `arc_permset`
|
|
430
|
-
when their ARC choice was Yes (the `PermissionSetAssignment` creates described below). On *change*,
|
|
431
|
-
let them amend this user's role or ARC choice and re-show the one line. On *skip*, drop this user
|
|
432
|
-
and move on. This per-user yes/no is the confirmation gate for Step 5 — **one simple go-ahead
|
|
433
|
-
immediately before each user's write, not a batched plan-review of everyone at once.** It does
|
|
434
|
-
not change the skill's minimal-intervention default for the other steps, which still proceed
|
|
435
|
-
straight from their own information-gathering answers.
|
|
436
|
-
|
|
437
|
-
5. **Offer to add another user, then loop.** After writing (or skipping) this user, append the
|
|
438
|
-
handled `{user, permission set, arc?}` to `user_permset_list` for the end-of-step report, then
|
|
439
|
-
ask **"Assign another user?"** — on *yes*, loop back to sub-step 1 (drop already-handled users
|
|
440
|
-
from the picker) and run pick → role → ARC → confirm-and-write again for the next user; on *no*,
|
|
441
|
-
end the step. Never ask for all users in a single prompt, and never assume one user is the whole
|
|
442
|
-
set — handle each user completely (pick → role → ARC → confirm → write) before offering the next.
|
|
443
|
-
|
|
444
|
-
Ask the role **per user** — don't assume everyone needs the same permission set, and don't ask
|
|
445
|
-
once and apply the answer to the whole batch. Build a per-user `{user, permission set, arc?}`
|
|
446
|
-
record from each loop iteration's answers, and **confirm-then-write that one user before moving to
|
|
447
|
-
the next** (sub-step 4). For each user, at the confirm step: check assigned-vs-needed by querying
|
|
448
|
-
`PermissionSetAssignment` for that user and the permission set's Id, then, on their go-ahead,
|
|
449
|
-
assign by creating a `PermissionSetAssignment` record
|
|
450
|
-
(`AssigneeId`=that user's Id, `PermissionSetId`=that set's Id) if they need it —
|
|
451
|
-
**the per-user confirm (sub-step 4) is the one gate right before that user's write; don't also
|
|
452
|
-
batch everyone into a separate plan-review pass**.
|
|
453
|
-
**Query `PermissionSetAssignment` by the raw `AssigneeId` / `PermissionSetId` fields, not by
|
|
454
|
-
relationship traversal.** On Core-backed orgs `SELECT Assignee.Username, PermissionSet.Name FROM
|
|
455
|
-
PermissionSetAssignment` fails with `INVALID_OPERATION` ("operation not yet supported by this
|
|
456
|
-
sObject storage type") — resolve the user Id and the permission-set Id first (a separate query on
|
|
457
|
-
`User`/`PermissionSet`), then filter the assignment query on those raw Ids. Don't mistake that
|
|
458
|
-
query error for a missing assignment. (Verified against a live org.) Never assign a
|
|
459
|
-
permission set to a user who wasn't individually asked about it. A `DUPLICATE_VALUE` response on that
|
|
460
|
-
create means it's already assigned — treat that as success, not an error. Report the resulting
|
|
461
|
-
assignments as a table when done.
|
|
462
|
-
|
|
463
|
-
**Actionable Relationship Center (ARC) access rides on the same per-user loop** (step 3 above) — it is
|
|
464
|
-
*not* a separate Setup-UI-only step, and *not* a batched pass after all users are collected. ARC's
|
|
465
|
-
user-level gate is the `FinancialServices2UserAccess`
|
|
466
|
-
user permission, which the standard **`FSCSales`** permission set (label "FSC Sales", API
|
|
467
|
-
name `FSCSales`) grants — confirmed live via `FSCSalesPsl-1.uld.xml`'s
|
|
468
|
-
`standardPermissionSets` block — but `FSCSales` is only one of the possible carriers: on an
|
|
469
|
-
org provisioned via a different SKU (e.g. `FSCServiceAddon`), the equivalent grant comes from
|
|
470
|
-
`FSCService` or `FinancialServicesCloudExtension` instead, and `FSCSales` won't exist at all.
|
|
471
|
-
That's why this step resolves `arc_permset` once, up front (see the resolution sub-step above),
|
|
472
|
-
rather than assuming `FSCSales`. **ARC is required, not optional, for a user to work with
|
|
473
|
-
hierarchies** — hierarchy operations run against the `RelationshipGraphDefinition` object ARC
|
|
474
|
-
backs, so a user without it can't view or edit hierarchies. Ask each user in turn, right after
|
|
475
|
-
their role, framing ARC as required and defaulting to Yes (see sub-step 3); record the choice on
|
|
476
|
-
that user's record. For each user whose ARC choice is Yes, check/assign the resolved
|
|
477
|
-
`arc_permset` the same way as the Flexible Hierarchy permission set above (query
|
|
478
|
-
`PermissionSetAssignment`, then assign on that user's per-user go-ahead in sub-step 4, in the
|
|
479
|
-
same write as their role set — `DUPLICATE_VALUE` = already assigned).
|
|
480
|
-
This requires the org's ARC org permission (Step 2) to already be provisioned —
|
|
481
|
-
`arc_permset` only grants the user-level permission, not the org-level one.
|
|
482
|
-
([Help: assign permissions](https://help.salesforce.com/s/articleView?id=ind.fsc_flexible_hierarchies_assign_permissions.htm))
|
|
483
|
-
6. **Set object permissions (optional).** To make Flexible Hierarchies usable and let admins manage
|
|
484
|
-
hierarchy types, a profile needs object-level access (CRUD) to the FH object
|
|
485
|
-
family. There are three objects — **`FlexibleHierarchy`**, **`FlexibleHierarchyNode`**, and
|
|
486
|
-
**`FlexibleHierarchyNodeRelation`** (provisioned on Core as the 40-char-truncated
|
|
487
|
-
`FlexibleHierarchyNodeRela` — use that API name in any query/describe) — but **only the master
|
|
488
|
-
`FlexibleHierarchy` carries its own object permissions.** `FlexibleHierarchyNode` and
|
|
489
|
-
`FlexibleHierarchyNodeRela` are **detail objects** (each has a master-detail field
|
|
490
|
-
`FlexibleHierarchyId` → `FlexibleHierarchy`, `relationshipOrder 0`), so they **inherit** object
|
|
491
|
-
access from the master and **cannot hold independent `<objectPermissions>`**. Granting CRUD on
|
|
492
|
-
`FlexibleHierarchy` alone gives the profile access across the whole hierarchy.
|
|
493
|
-
**This step grants object permissions via a PROFILE only** — the permission-set path is intentionally
|
|
494
|
-
out of scope here (users get their day-to-day access from the Step 5 role permission sets; this step
|
|
495
|
-
is specifically for granting object CRUD on the FH objects at the profile level). Because the target
|
|
496
|
-
is a `Profile`, **two different silent-failure modes are in play, and they have different causes —
|
|
497
|
-
don't conflate them.** In both, the `/headless/metadata` deploy returns "Succeeded"/"Created" for the
|
|
498
|
-
whole `Profile`; only a re-read of the live `ObjectPermissions` reveals what actually stuck. This is
|
|
499
|
-
the "a deploy result can lie" case from the transport discipline above, in two distinct forms:
|
|
500
|
-
|
|
501
|
-
- **Standard profiles reject the whole grant (nothing sticks).** Object permissions on a **standard**
|
|
502
|
-
profile (`System Administrator`, `Standard User`, `Minimum Access - Salesforce`, etc.) are **not
|
|
503
|
-
editable through the Metadata API at all** — the platform silently ignores the entire
|
|
504
|
-
`<objectPermissions>` block, master included, and still reports the deploy as succeeded. Confirmed
|
|
505
|
-
live: a Step-6-style grant against `Standard User` left `ObjectPermissions` with **zero rows** for
|
|
506
|
-
`FlexibleHierarchy` — the grant never applied. **You cannot grant FH object permissions on a
|
|
507
|
-
standard profile via this step; see the standard-profile branch in sub-step 1 for the remediation.**
|
|
508
|
-
- **Detail-object blocks are dropped on any profile (custom included).** Even on a **custom** profile
|
|
509
|
-
where the grant does apply, the two detail-object blocks are silently dropped because they're
|
|
510
|
-
detail objects that inherit (see above) — only the master `FlexibleHierarchy` block can stick.
|
|
511
|
-
Confirmed live: a grant against a custom profile ("Flexible Hierarchy Access") took `allowRead=true`
|
|
512
|
-
on `FlexibleHierarchy`; the detail objects never carried their own row (expected — they inherit).
|
|
513
|
-
|
|
514
|
-
So the deploy only does something real on a **custom** profile, and even there only the master block
|
|
515
|
-
matters. **Emit only the master `FlexibleHierarchy` block from the start** — don't add
|
|
516
|
-
`<objectPermissions>` for the detail objects (dropped regardless), and don't deploy against a
|
|
517
|
-
standard profile at all (the whole block is dropped).
|
|
518
|
-
|
|
519
|
-
**This step is optional — open it with a plain yes/no gate, and surface the profile-edit heads-up
|
|
520
|
-
in the prompt itself.** Many orgs already grant these object permissions through the Flexible
|
|
521
|
-
Hierarchy role permission sets assigned in Step 5, so ask first whether the admin wants to touch
|
|
522
|
-
profile object permissions at all, as a simple two-option yes/no. **Give the admin the heads-up up
|
|
523
|
-
front — a profile edit applies to every user assigned to that profile — so it's part of the
|
|
524
|
-
question they answer, not an aside the agent keeps to itself.** Ask this gate on its own, in its
|
|
525
|
-
own message — don't combine it with any other step's question:
|
|
526
|
-
|
|
527
|
-
> **Heads-up:** editing object permissions on a profile applies to **every user assigned to that
|
|
528
|
-
> profile**, not just one user. (Per-user access is handled by the Step 5 role permission sets.)
|
|
529
|
-
>
|
|
530
|
-
> Do you want to make changes to object permissions on the Flexible Hierarchy objects for any of
|
|
531
|
-
> the profiles?
|
|
532
|
-
> - **Yes**
|
|
533
|
-
> - **No**
|
|
534
|
-
|
|
535
|
-
On **No**, record `object_permissions` as skipped and move on — don't ask anything further. On
|
|
536
|
-
**Yes**, proceed to gather the details below. If they proceed, gather two
|
|
537
|
-
answers (these questions are this step's query — no separate per-write confirmation once answered).
|
|
538
|
-
**Never take the profile as bare free text** — profiles are a known, queryable set on the org, so
|
|
539
|
-
present them as options and resolve the real API name, same pick-from-a-query pattern Step 5 uses
|
|
540
|
-
for choosing a user:
|
|
541
|
-
1. **Which profile?** **Query profiles WITH their custom-vs-standard flag** — `Profile` itself has
|
|
542
|
-
no queryable `IsCustom` field (a `SELECT IsCustom FROM Profile` errors with no-such-column), so
|
|
543
|
-
read it through the profile-owned permission set instead:
|
|
544
|
-
|
|
545
|
-
```sql
|
|
546
|
-
SELECT ProfileId, Profile.Name, IsCustom FROM PermissionSet WHERE IsOwnedByProfile = true
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
Each row's `IsCustom` is that profile's flag — `false` = **standard** profile (grant will no-op),
|
|
550
|
-
`true` = **custom** profile (grant applies). (Verified live: standard profiles — `Standard User`,
|
|
551
|
-
`System Administrator`, `Minimum Access - Salesforce`, … — all return `IsCustom=false`.) Present
|
|
552
|
-
the results as a single-select showing `Name` **and whether each is standard or custom**, so the
|
|
553
|
-
admin sees up front which targets can actually take the grant. **Cap the picker: if there are
|
|
554
|
-
three or fewer, list them all; if more than three, show the closest three plus a fourth option
|
|
555
|
-
"Type the API name"** (an explicit type-it-in escape, also the fallback when the target isn't
|
|
556
|
-
among the shown three).
|
|
557
|
-
|
|
558
|
-
**When the admin TYPES a name (the "Type the API name" escape), validate then reconfirm — don't
|
|
559
|
-
deploy straight off a typed string.** Two gates, in order:
|
|
560
|
-
1. **Validate against the org.** Resolve the typed name against `Profile` (`SELECT Id, Name FROM
|
|
561
|
-
Profile WHERE Name = '<typed>'`) — it must exist. If it doesn't resolve, **tell the admin it
|
|
562
|
-
wasn't found and re-ask** — never deploy against an unresolved name. Resolve its `IsCustom` the
|
|
563
|
-
same way (`SELECT IsCustom FROM PermissionSet WHERE IsOwnedByProfile = true AND ProfileId =
|
|
564
|
-
'<resolved id>'`) so the standard-profile check below applies to typed names too.
|
|
565
|
-
2. **Reconfirm the resolved target before proceeding.** Once it validates, echo back the
|
|
566
|
-
**resolved `Name` (and Id)** and ask the admin to confirm it's the one they meant
|
|
567
|
-
before moving on to the access-level question — e.g. *"Found `<Name>` (`<Id>`). Grant
|
|
568
|
-
object permissions on this one? (yes / pick another)."* Only continue on an explicit yes; on
|
|
569
|
-
"pick another," re-open the picker/typed-entry. This reconfirm applies to the typed path
|
|
570
|
-
specifically — a name the admin typed is easy to fat-finger, so confirm the match before it
|
|
571
|
-
feeds the deploy. (Picking a shown option is already an explicit selection and needs no extra
|
|
572
|
-
reconfirm.)
|
|
573
|
-
|
|
574
|
-
**If the chosen profile is STANDARD (`IsCustom=false`), stop before deploying and offer the
|
|
575
|
-
remediation** — a Metadata API `<objectPermissions>` deploy against it silently no-ops (see the
|
|
576
|
-
two-failure-modes note above), so deploying anyway would look like it worked and change nothing.
|
|
577
|
-
Tell the admin plainly and offer the two real paths:
|
|
578
|
-
|
|
579
|
-
> `<Profile>` is a **standard profile**. Salesforce doesn't let object permissions on standard
|
|
580
|
-
> profiles be set through the API, so a grant here would silently do nothing. Two options:
|
|
581
|
-
> - **Use the Step 5 permission sets instead (recommended)** — assign `FlexibleHierarchyManager`
|
|
582
|
-
> or `FlexibleHierarchyAdmin` to the specific users; that grants FH object access per-user
|
|
583
|
-
> without touching the profile.
|
|
584
|
-
> - **Clone this standard profile to a custom one**, grant the object permissions on the clone,
|
|
585
|
-
> then reassign the affected users to it. Note: cloning does **not** move existing users —
|
|
586
|
-
> they stay on `<Profile>` until each is reassigned to the new custom profile (a base-profile
|
|
587
|
-
> change, heavier than a permission-set assignment).
|
|
588
|
-
|
|
589
|
-
Only proceed to a deploy on the clone path once the admin picks it and names/confirms the custom
|
|
590
|
-
clone (create it via a `Profile` MDAPI deploy or in Setup, then re-run the picker against the new
|
|
591
|
-
custom profile). Otherwise route them to Step 5 and record `object_permissions` as
|
|
592
|
-
redirected-to-permission-sets. **Never deploy `<objectPermissions>` against a standard profile.**
|
|
593
|
-
2. **Which access level** on the three objects (single-select):
|
|
594
|
-
- **Read-only** — `allowRead` only.
|
|
595
|
-
- **Full CRUD** — `allowRead` + `allowCreate` + `allowEdit` + `allowDelete`.
|
|
596
|
-
|
|
597
|
-
The chosen level is what lands on the master `FlexibleHierarchy`; the two detail objects inherit
|
|
598
|
-
it — so there's nothing to differ per object.
|
|
599
|
-
|
|
600
|
-
Deploy via `/headless/metadata` as a `Profile` component carrying a
|
|
601
|
-
`<objectPermissions>` block for **`FlexibleHierarchy`** only — with `<object>` set to the API name and the
|
|
602
|
-
`<allowRead>`/`<allowCreate>`/`<allowEdit>`/`<allowDelete>`/`<viewAllRecords>`/`<modifyAllRecords>`
|
|
603
|
-
booleans for the chosen level. **Emit only the master block — do NOT add `<objectPermissions>` blocks
|
|
604
|
-
for `FlexibleHierarchyNode`/`FlexibleHierarchyNodeRela`.** They're detail objects (see above): the
|
|
605
|
-
platform silently drops those blocks, so including them buys nothing and just makes the deploy look
|
|
606
|
-
like it granted more than it did. This isn't a try-all-three-then-retry situation — grant the master
|
|
607
|
-
in one deploy from the start. **Dry-run first**, deploy at the org's max
|
|
608
|
-
supported API version (Step 1), then **re-read** the deployed `Profile` and confirm
|
|
609
|
-
the `objectPermissions` for `FlexibleHierarchy` stuck — a deploy "Succeeded" is not proof (it will
|
|
610
|
-
report success whether the grant applied, was dropped as a detail block, or was wholesale-ignored on
|
|
611
|
-
a standard profile). The MDAPI profile re-read only
|
|
612
|
-
projects back `<objectPermissions>` for objects **also named in the retrieve manifest**, and it can
|
|
613
|
-
omit detail objects entirely; the authoritative live check is the **`ObjectPermissions` sObject**.
|
|
614
|
-
Query it for the master only — the two detail objects will never return a row, so don't treat their
|
|
615
|
-
absence as a failure:
|
|
616
|
-
|
|
617
|
-
```sql
|
|
618
|
-
SELECT SobjectType, PermissionsCreate, PermissionsRead, PermissionsEdit, PermissionsDelete
|
|
619
|
-
FROM ObjectPermissions
|
|
620
|
-
WHERE Parent.ProfileId = '<profileId>' AND SobjectType = 'FlexibleHierarchy'
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
**Read the result against the profile's custom-vs-standard flag — the two zero-row cases are NOT the
|
|
624
|
-
same failure:**
|
|
625
|
-
- **A `FlexibleHierarchy` row with the expected C/R/E/D booleans** → the grant applied. The absence
|
|
626
|
-
of `FlexibleHierarchyNode`/`FlexibleHierarchyNodeRela` rows is **expected** (they inherit) — not a
|
|
627
|
-
failure. This is the only success state, and it only happens on a **custom** profile.
|
|
628
|
-
- **Zero rows on a STANDARD profile** → the whole grant was silently ignored because standard-profile
|
|
629
|
-
object permissions aren't API-writable (the cause named in the two-failure-modes note above).
|
|
630
|
-
Don't retry the same deploy — it will keep no-op'ing. Route to the clone-to-custom or Step-5
|
|
631
|
-
permission-set remediation.
|
|
632
|
-
- **Zero rows on a CUSTOM profile** → a genuine deploy problem (bad object name, skipped dry-run fix,
|
|
633
|
-
wrong API version) — investigate the deploy, don't chalk it up to inheritance.
|
|
634
|
-
|
|
635
|
-
**Two query
|
|
636
|
-
traps that will make this fail — avoid both:** (a) `SobjectType` and the parent id take `=`, **never
|
|
637
|
-
`LIKE`** — `LIKE` on an id field errors with `invalid operator on id field`, and there's no need to
|
|
638
|
-
pattern-match when the only object that can carry a row is `FlexibleHierarchy`; (b) if you shell out
|
|
639
|
-
to the `sf` CLI, redirect stdout to a file and parse the file — the `NODE_TLS_REJECT_UNAUTHORIZED=0`
|
|
640
|
-
warning prints to stdout and corrupts inline JSON parsing. Report the resulting object permissions as
|
|
641
|
-
a small table (object → C/R/E/D) grounded in that read, noting that `FlexibleHierarchyNode`/
|
|
642
|
-
`FlexibleHierarchyNodeRela` inherit the master's access rather than carrying their own row.
|
|
643
|
-
|
|
644
|
-
**Object permissions here cover the hierarchy object family only — NOT the validation-job-run
|
|
645
|
-
objects.** The Flexible Hierarchy validation feature has its own objects — **`FlexHierVldJobRun`**
|
|
646
|
-
(validation job run) and **`FlexHierVldJobRunItm`** (its line items) — and they are **not** part of
|
|
647
|
-
the `FlexibleHierarchy` master/detail family, so granting `FlexibleHierarchy` object permissions in
|
|
648
|
-
this step does **nothing** for them (confirmed live: a `Standard User` grant showed zero
|
|
649
|
-
`FlexHierVldJobRun` rows, and a custom-profile `FlexibleHierarchy` grant doesn't reach them either).
|
|
650
|
-
**Access to these two objects comes from the Step 5 role permission sets, not this profile step:**
|
|
651
|
-
`FlexibleHierarchyManager` grants **Read** on the validation-job-run objects and
|
|
652
|
-
`FlexibleHierarchyAdmin` grants **full CRUD**. If a user needs to run or read hierarchy-validation
|
|
653
|
-
jobs, route them to the appropriate Step 5 permission set — don't try to add `FlexHierVldJobRun`/
|
|
654
|
-
`FlexHierVldJobRunItm` to a profile here.
|
|
655
|
-
(Help: the FSC "Set Tab Visibility and Object Permissions" step — link the real
|
|
656
|
-
`help.salesforce.com` article ID once confirmed; not yet verified during authoring.)
|
|
657
|
-
7. **Configure hierarchy node roles** — the `FlexibleHierarchyNode.Role` field is a
|
|
658
|
-
`DYNAMICENUM` flexField (`enum="FlexibleHierarchyNodeRole"` — confirmed in
|
|
659
|
-
`FlexibleHierarchyNode.entity.xml`) backed by the **`FlexibleHierarchyNodeRole`**
|
|
660
|
-
`StandardValueSet`, which ships **empty** — no `<standardValue>` entries — so there's nothing
|
|
661
|
-
to pick from until this step populates it. **Read the current values first via a REST
|
|
662
|
-
`describe`** — `GET /sobjects/FlexibleHierarchyNode/describe`, then read the `Role` field's
|
|
663
|
-
`picklistValues` (don't assume it's still empty — an earlier run or another admin may have added
|
|
664
|
-
values). **If it already has values, show them to the admin and ask whether more are needed
|
|
665
|
-
before asking for anything**:
|
|
666
|
-
|
|
667
|
-
> The hierarchy node-role picklist already has these values:
|
|
668
|
-
> - `<value 1>`
|
|
669
|
-
> - `<value 2>`
|
|
670
|
-
>
|
|
671
|
-
> Do you want to add more, or should I proceed to the next step?
|
|
672
|
-
|
|
673
|
-
If the admin says no
|
|
674
|
-
more are needed, **skip the deploy and move on** — the picklist is already populated; don't
|
|
675
|
-
re-write it or ask for values just to re-confirm what's there. Only when the set is empty, or the
|
|
676
|
-
admin wants to add values, do you **ask which role values they want on this picklist** — on its
|
|
677
|
-
own, in its own message, not combined with any other step's question.
|
|
678
|
-
|
|
679
|
-
**Ask this as an open, typed, free-text question — NOT a multiple-choice picker.** There is no
|
|
680
|
-
canonical or default set of role values; the admin invents them for their org, so you cannot offer
|
|
681
|
-
a fixed list of options to select from. Present it exactly as a fill-in-the-blank prompt where the
|
|
682
|
-
admin types their own values:
|
|
683
|
-
|
|
684
|
-
> What role values should the hierarchy node-role picklist have?
|
|
685
|
-
> **Type your own values as a comma-separated list** — one entry per role.
|
|
686
|
-
> For example, an org might use `Parent, Subsidiary, Branch`, but enter whatever roles fit your
|
|
687
|
-
> hierarchy.
|
|
688
|
-
> (I'll add these alongside any values already there.)
|
|
689
|
-
|
|
690
|
-
Make the comma-separated format explicit in the prompt, and be clear the example is **illustrative
|
|
691
|
-
only, not a suggested or default set** — don't present `Parent, Subsidiary, Branch` (or any other
|
|
692
|
-
fixed list) as options to pick from, and don't pre-fill or default to them if the admin gives no
|
|
693
|
-
answer (re-ask instead). Take the
|
|
694
|
-
answer as a comma-separated list rather than guessing or
|
|
695
|
-
defaulting to a fixed set, split on commas, trim whitespace per value, and echo the parsed list as
|
|
696
|
-
you collect it (asking for the values is this step's query — no separate approval of the parsed list
|
|
697
|
-
needed). **This picklist cannot be deployed through this skill's usual REST transport — deploy it
|
|
698
|
-
via a real Metadata API retrieve/deploy (`sf project retrieve` / `sf project deploy`) instead**; see
|
|
699
|
-
the confirmed facade-vs-MDAPI split below. Manual Setup entry is a fallback only, for when `sf` CLI
|
|
700
|
-
isn't available — it is **not** the primary path.
|
|
701
|
-
|
|
702
|
-
**⚠️ Confirmed live (re-verified 2026-09-29 against this org): the `/headless/metadata` dispatcher
|
|
703
|
-
facade blocks BOTH directions for this metadata type, but genuine MDAPI works for both.**
|
|
704
|
-
- **Facade READ is blocked — use REST `describe` instead.** `GET /sobjects/FlexibleHierarchyNode/describe`,
|
|
705
|
-
then read the `Role` field's `picklistValues` (each entry carries `value`/`label`/`active`). **The
|
|
706
|
-
dispatcher's `/headless/metadata` facade does not support reading a `StandardValueSet` at all** —
|
|
707
|
-
confirmed against a live org: `GET .../headless/metadata?type=StandardValueSet&fullName=FlexibleHierarchyNodeRole`
|
|
708
|
-
returns `400 UNSUPPORTED_OPERATION` — `"MetadataCrud does not support READ on type: StandardValueSet"`.
|
|
709
|
-
This is a facade-level restriction on the **type**, not specific to this StandardValueSet's name —
|
|
710
|
-
don't retry the same call with a different `fullName` expecting it to work.
|
|
711
|
-
- **Facade WRITE is blocked too, but that is a facade limitation, not a platform one.**
|
|
712
|
-
`updateMetadata` on `type=StandardValueSet`, `fullName=FlexibleHierarchyNodeRole` via
|
|
713
|
-
`/headless/metadata` ALSO returns `400 UNSUPPORTED_OPERATION` — `"MetadataCrud does not support
|
|
714
|
-
UPDATE on type: StandardValueSet"` — confirmed live. Don't retry this call expecting a different
|
|
715
|
-
`fullName`, API version, or payload shape to change the result — it won't.
|
|
716
|
-
- **Genuine MDAPI (`sf project retrieve` / `sf project deploy`) DOES write this type — confirmed
|
|
717
|
-
live.** This was previously untested and wrongly assumed to dead-end the same way as the facade.
|
|
718
|
-
Re-verified end-to-end on 2026-09-29: `sf project retrieve start --metadata
|
|
719
|
-
"StandardValueSet:FlexibleHierarchyNodeRole"` succeeds and returns the current `<standardValue>`
|
|
720
|
-
list (don't skip this — you need it to avoid dropping existing values, since the deploy replaces
|
|
721
|
-
the full component); edit the retrieved XML to add the admin's new values alongside the existing
|
|
722
|
-
ones; `sf project deploy start --metadata "StandardValueSet:FlexibleHierarchyNodeRole"` succeeds
|
|
723
|
-
(`status: Succeeded`); and — per this SOR's own "a deploy result can lie, always re-read" rule — a
|
|
724
|
-
follow-up `GET /sobjects/FlexibleHierarchyNode/describe` confirmed the new value actually landed in
|
|
725
|
-
`picklistValues`. Use the same `sfdx-project.json` scaffold this SOR already sets up once for the
|
|
726
|
-
Step 9 `RelationshipGraphDefinition` MDAPI deploy; no new transport is introduced. **This is now
|
|
727
|
-
the primary write path for this step — only fall back to the manual Setup hand-off below if `sf`
|
|
728
|
-
CLI genuinely isn't available in the environment.**
|
|
729
|
-
- **Manual fallback (only when `sf` CLI is unavailable):** tell the admin to add the values themselves
|
|
730
|
-
at **Setup → Object Manager → Flexible Hierarchy Node → Fields & Relationships → Role → New**.
|
|
731
|
-
|
|
732
|
-
Do **not** reach for the Tooling API (`/tooling/sobjects/...`, `/tooling/query`) or a
|
|
733
|
-
`StandardValueSet`/`GlobalValueSet` generic sObject to read or write these values — that surface does
|
|
734
|
-
**not** service this StandardValueSet and the attempt dead-ends the same way as the facade (this is
|
|
735
|
-
distinct from genuine MDAPI above, which is a different transport and does work). Step 9's
|
|
736
|
-
`RelationshipGraphDefinition` deploy is no longer the only MDAPI write in this skill — this step now
|
|
737
|
-
uses the same `sf` CLI MDAPI transport.
|
|
738
|
-
([Help: configure roles](https://help.salesforce.com/s/articleView?id=ind.fsc_flexible_hierarchies_configure_roles.htm))
|
|
739
|
-
8. **Add the hierarchy component to record pages.** The `flexible_hierarchy:flexibleHierarchyBase`
|
|
740
|
-
Lightning component is offered — **not required** (`isRequired: false` on every entry) — on
|
|
741
|
-
11 standard objects: Account, Contact, FinancialAccount, PartyRelationshipGroup, Opportunity,
|
|
742
|
-
Case, BranchUnit, FinancialDeal, Product2, InsurancePolicy, Lead.
|
|
743
|
-
|
|
744
|
-
**⚠️ You do NOT deploy or retrieve `flexible_hierarchy:flexibleHierarchyBase` as an LWC/Aura
|
|
745
|
-
bundle — and its absence from the org's LWC/Aura bundle list does NOT mean it's UI-only.** It is a
|
|
746
|
-
**platform/managed runtime component** provisioned by the FSC Flexible Hierarchy feature/license
|
|
747
|
-
(the same `fsc-license-provisioned` precondition that gates this whole skill) — exactly like
|
|
748
|
-
`force:highlightsPanel`, `force:relatedListContainer`, and `runtime_sales_activities:activityPanel`,
|
|
749
|
-
none of which are retrievable source bundles either. So do **not** query the Tooling API for a
|
|
750
|
-
`LightningComponentBundle`/`AuraDefinitionBundle`, try to `retrieve` the component, or conclude
|
|
751
|
-
"not available via API → add it in Lightning App Builder" when no bundle turns up — **that
|
|
752
|
-
conclusion is wrong.** You add it **by name** as a `<componentInstance>` inside a `FlexiPage` and
|
|
753
|
-
deploy the *FlexiPage* via MDAPI (the exact XML + placement is spelled out below). Once the feature
|
|
754
|
-
is provisioned the `flexible_hierarchy:flexibleHierarchyBase` reference resolves at deploy time; the
|
|
755
|
-
Lightning App Builder path in the Skip option below is a manual *fallback*, never the required path.
|
|
756
|
-
|
|
757
|
-
**Confirm the admin wants to do this step BEFORE asking which object(s) — a Yes/No gate first.**
|
|
758
|
-
Placing the component is optional (`isRequired: false` on every object), and modifying record pages
|
|
759
|
-
changes what users see, so don't jump straight into the object picker. Ask a simple go-ahead first,
|
|
760
|
-
on its own — don't combine it with any other step's question:
|
|
761
|
-
|
|
762
|
-
> Do you want to add the Flexible Hierarchy component to any record pages now?
|
|
763
|
-
> - **Yes** — I'll ask which object(s) to place it on.
|
|
764
|
-
> - **Skip this step** — no record-page changes; you can add the component later in Lightning App
|
|
765
|
-
> Builder.
|
|
766
|
-
|
|
767
|
-
Only on **Yes** do you proceed to the object picker below. On **Skip**, record
|
|
768
|
-
`record_page_objects` as skipped and move straight to the next step — don't show the object
|
|
769
|
-
multi-select at all. (Label the opt-out per the user-facing-language rule — "Skip this step", never
|
|
770
|
-
"Skip Step 8".)
|
|
771
|
-
|
|
772
|
-
On Yes, **ask which object(s) they want the component on** (this is the step's query):
|
|
773
|
-
|
|
774
|
-
> Which object(s) should get the Flexible Hierarchy component on their record page?
|
|
775
|
-
> It's supported on: Account, Contact, FinancialAccount, PartyRelationshipGroup, Opportunity,
|
|
776
|
-
> Case, BranchUnit, FinancialDeal, Product2, InsurancePolicy, Lead.
|
|
777
|
-
> (Most setups only need it on the hierarchy's node object — Account by default.)
|
|
778
|
-
|
|
779
|
-
**Present the 11 supported objects as a multiple-choice picker — NOT a free-text list.** The
|
|
780
|
-
objects are a **fixed, known set**, so the admin selects from them; there is no "Enter objects
|
|
781
|
-
(comma-separated)" / type-it-in option (that was a free-text answer this skill has since replaced —
|
|
782
|
-
a typed list here is a dead option that can only introduce an unsupported name). Because the admin
|
|
783
|
-
can want the component on *any subset*, present this as a **multi-select** over the 11 objects so
|
|
784
|
-
they can pick one, several, or all:
|
|
785
|
-
|
|
786
|
-
- The **11 supported objects** as selectable options: Account, Contact, FinancialAccount,
|
|
787
|
-
PartyRelationshipGroup, Opportunity, Case, BranchUnit, FinancialDeal, Product2, InsurancePolicy,
|
|
788
|
-
Lead. (`Account` is the default node object and the common single-object case — note it as the
|
|
789
|
-
typical pick, but don't pre-select or force it.)
|
|
790
|
-
- A **"Skip this step"** choice — placing the component is optional (`isRequired: false` on every
|
|
791
|
-
object), so this is the way out; labelled per the user-facing-language rule above (never "Skip
|
|
792
|
-
Step 8").
|
|
793
|
-
|
|
794
|
-
Do **not** add any free-text / "Other" option and do **not** enumerate pre-baked combos (e.g.
|
|
795
|
-
"Account + Contact") — a multi-select over the 11 already covers every subset. Selecting from the
|
|
796
|
-
fixed set makes an unsupported object **structurally impossible**, so there's no typed list to
|
|
797
|
-
parse, no allowlist re-check, and no reject-and-re-ask to perform — echo the chosen set back to the
|
|
798
|
-
admin and proceed to deploy to exactly those objects.
|
|
799
|
-
|
|
800
|
-
The config offers all 11, but a real
|
|
801
|
-
setup typically only needs it on the confirmed node object (Account by default). The component is
|
|
802
|
-
deployed as a standard MDAPI `FlexiPage` update, same pattern as other record-page component
|
|
803
|
-
placements in this corpus — but **how** it lands depends on what record pages the object already
|
|
804
|
-
has, so resolve that per object before deploying.
|
|
805
|
-
([Help: customize record pages](https://help.salesforce.com/s/articleView?id=ind.fsc_flexible_hierarchies_customize_record_pages.htm))
|
|
806
|
-
|
|
807
|
-
**Always clone the object's CURRENTLY-ACTIVE page — never edit any page in place.** For each object
|
|
808
|
-
the admin picked, determine its currently-active record page (its org-default `View` assignment —
|
|
809
|
-
the same `actionOverride` the activation gate below reads/writes), then **clone that active page
|
|
810
|
-
into a new `FlexiPage`** and add the component to the clone's **Related section**. This is the
|
|
811
|
-
single path for both cases — whether the active page is a **custom `FlexiPage`** or the
|
|
812
|
-
**system/out-of-box default**, you clone it rather than modifying it. Cloning (not in-place editing)
|
|
813
|
-
keeps the page users currently see untouched until the admin explicitly activates the new one, so
|
|
814
|
-
**the activation gate below always applies** (every chosen object produces a new, inactive page).
|
|
815
|
-
|
|
816
|
-
To clone: **retrieve the object's currently-active `FlexiPage` from the live org via MDAPI** — do
|
|
817
|
-
**not** copy from a baked-in sample or reconstruct the page from memory; the page users actually see
|
|
818
|
-
is the only correct source. Issue an MDAPI **retrieve** with a `package.xml` manifest that names the
|
|
819
|
-
active page as a `FlexiPage` member, e.g.:
|
|
820
|
-
|
|
821
|
-
```xml
|
|
822
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
823
|
-
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
824
|
-
<types>
|
|
825
|
-
<members>Account_Record_Page</members>
|
|
826
|
-
<name>FlexiPage</name>
|
|
827
|
-
</types>
|
|
828
|
-
<version>66.0</version>
|
|
829
|
-
</Package>
|
|
830
|
-
```
|
|
831
|
-
|
|
832
|
-
Use the actual active-page `DeveloperName` resolved from the `View` `actionOverride` as the
|
|
833
|
-
`<members>` value (add one `<members>` line per object when the admin picked several — the sample
|
|
834
|
-
manifest the admin may supply can list `Account_Record_Page`, `Contact_Record_Page`, etc.), and pin
|
|
835
|
-
`<version>` to the org's max supported API version (Step 1). Take the **retrieved** FlexiPage XML,
|
|
836
|
-
copy its regions/content into a new `FlexiPage` (new `DeveloperName`/`masterLabel`), append the
|
|
837
|
-
component to the Related section (see placement below), and deploy the clone. Never redeploy the
|
|
838
|
-
existing active page with the component added — always land the change on a fresh clone built from
|
|
839
|
-
the freshly-retrieved XML.
|
|
840
|
-
|
|
841
|
-
- **⚠️ Grounding caveat — the *system default* may not be retrievable to clone.** This skill has
|
|
842
|
-
confirmed against a live org that for objects like **Account, when the active page is the
|
|
843
|
-
*system* default, that out-of-box page is generally NOT retrievable/customizable as a `FlexiPage`**
|
|
844
|
-
— you can't clone what MDAPI won't hand you. When the active page is instead a **custom
|
|
845
|
-
`FlexiPage`** (e.g. Account's `sfa__Account_rec_L`), it **is** retrievable and clones cleanly — the
|
|
846
|
-
grounded example in the placement note below is exactly such a page. **If the active page can't be
|
|
847
|
-
retrieved for cloning** (the system-default case), **do NOT fall back to a bare FH-only page — build
|
|
848
|
-
a fresh COMPLETE `RecordPage` FlexiPage** (the grounded complete-page skeleton in the schema note
|
|
849
|
-
below): highlights panel + record details + related lists + a sidebar Activities panel, WITH the
|
|
850
|
-
Flexible Hierarchy component added to the Related tab. **A page carrying only the FH component would wipe the highlights panel,
|
|
851
|
-
record details, and related lists the system default showed — and activating that as the org
|
|
852
|
-
default is a destructive, org-wide UX regression** (this is a real bug the bare-page fallback
|
|
853
|
-
caused). The fallback must reproduce the standard record-page furniture, not just the FH component.
|
|
854
|
-
The fresh complete page is also inactive, so it runs the activation gate too — and because it is a
|
|
855
|
-
**brand-new page, not the admin's existing layout**, the activation gate carries an EXTRA alert (see
|
|
856
|
-
"Fallback case" in the activation gate below). What remains **not yet verified against the target
|
|
857
|
-
org** is cloning the *system default* specifically — treat that branch as `inferred` (the
|
|
858
|
-
complete-page skeleton itself is grounded from a real retrieved page on the same template), dry-run
|
|
859
|
-
the complete page, and verify on the next org-backed run.
|
|
860
|
-
|
|
861
|
-
Note inactive custom pages that are **not** the active page don't drive this — always clone whatever
|
|
862
|
-
page is *currently active* (the one users see), not some stray inactive page.
|
|
863
|
-
|
|
864
|
-
**⚠️ FlexiPage schema — get the region shape right or the deploy fails.** A `flexiPageRegions`
|
|
865
|
-
region places components **only** through `itemInstances > componentInstance`, and **every
|
|
866
|
-
`componentInstance` needs an `<identifier>`**. Do **not** put a bare `<componentInstances>` block
|
|
867
|
-
(a component directly under the region, no `itemInstances` wrapper) — that fails dry-run with
|
|
868
|
-
`Property 'componentInstances' not valid in version <n>.0` (confirmed against a live org). The
|
|
869
|
-
highlights panel is **`force:highlightsPanel`** and it belongs in a **`header` `<type>Region</type>`**
|
|
870
|
-
— do **not** use `flexipage:highlightsPanel` or drop a highlights panel into a plain content
|
|
871
|
-
`Region`, which fails with "couldn't retrieve design time component information" (confirmed against a
|
|
872
|
-
live org). Every page carries `<sobjectType>`,
|
|
873
|
-
`<template><name>flexipage:recordHomeTemplateDesktop</name></template>`, and `<type>RecordPage</type>`
|
|
874
|
-
— the root element is **`<type>`, never `<pageType>`** (a real deploy failure:
|
|
875
|
-
`Element pageType invalid at this location in type FlexiPage`), and the template name is
|
|
876
|
-
**exactly** `flexipage:recordHomeTemplateDesktop` — do **not** guess alternatives like
|
|
877
|
-
`force_base_layout:BaseManagedLayout`, `force_base_layout:BaseLayout`,
|
|
878
|
-
`lightning_record_page:RecordPageTemplate3Col`, or any `one:*` name; all of those have failed live
|
|
879
|
-
with `Template <name> doesn't exist`, and there is no metadata-list way to enumerate valid
|
|
880
|
-
templates (`FlexiPageTemplateBundle` isn't a real type) — they're platform-shipped, not
|
|
881
|
-
discoverable org content.
|
|
882
|
-
|
|
883
|
-
**Use the ready-to-copy sample instead of authoring this shape from prose.** A full,
|
|
884
|
-
deploy-shaped XML for this exact fallback skeleton — header/main/sidebar regions, both tabs, the
|
|
885
|
-
FH component placed in Related, every `<componentInstanceProperties>` filled in — is at
|
|
886
|
-
[`references/flexipage-record-page-sample.md`](references/flexipage-record-page-sample.md), along
|
|
887
|
-
with a table of every wrong template/element name that has actually failed a live deploy while
|
|
888
|
-
improvising this page. Copy that sample rather than reconstructing the shape from the bullets
|
|
889
|
-
below.
|
|
890
|
-
|
|
891
|
-
**Grounded complete-page skeleton — the fresh-fallback shape (build this, NOT a bare FH-only page).**
|
|
892
|
-
When you can't clone the active page and must build one (the system-default case above), reproduce
|
|
893
|
-
this full shape so the result is a normal record page. It is grounded from a real retrieved record
|
|
894
|
-
page on the same `recordHomeTemplateDesktop` template (`Security_Assurance_Team_Record_Page`), so it
|
|
895
|
-
deploys cleanly. Regions and their contents:
|
|
896
|
-
- `header` `<type>Region</type>` → `force:highlightsPanel` (identifier `force_highlightsPanel`)
|
|
897
|
-
- `main` `<type>Region</type>` → `flexipage:tabset` (identifier `flexipage_tabset`, property
|
|
898
|
-
`tabs=maintabs`)
|
|
899
|
-
- `maintabs` `<type>Facet</type>` → two `flexipage:tab`s: one with properties `title=Standard.Tab.detail`,
|
|
900
|
-
`body=detailTabContent`, `active=true`; one with `title=Standard.Tab.relatedLists`,
|
|
901
|
-
`body=relatedTabContent`
|
|
902
|
-
- `detailTabContent` `<type>Facet</type>` → `force:detailPanel` (identifier `force_detailPanel`)
|
|
903
|
-
- `relatedTabContent` `<type>Facet</type>` → `force:relatedListContainer` (identifier
|
|
904
|
-
`force_relatedListContainer`) **plus** `flexible_hierarchy:flexibleHierarchyBase` in its own
|
|
905
|
-
`itemInstances` block (identifier `flexible_hierarchy_flexibleHierarchyBase`)
|
|
906
|
-
- `sidebar` `<type>Region</type>` → `flexipage:tabset` (identifier `flexipage_tabset_sidebar`,
|
|
907
|
-
property `tabs=sidebartabs`) — the template's third (right-hand) region
|
|
908
|
-
- `sidebartabs` `<type>Facet</type>` → one `flexipage:tab`: `title=Activity`,
|
|
909
|
-
`body=activityTabContent`, `active=true`
|
|
910
|
-
- `activityTabContent` `<type>Facet</type>` → `runtime_sales_activities:activityPanel` (identifier
|
|
911
|
-
`runtime_sales_activities_activityPanel`) — the standard Activities panel (log a call, new
|
|
912
|
-
task/event, activity timeline)
|
|
913
|
-
|
|
914
|
-
**⚠️ Do NOT add `<mode>Replace</mode>` on any facet in this fresh-build skeleton.** `<mode>Replace</mode>`
|
|
915
|
-
is only valid when a page **overrides an existing parent template's region** — that's the clone case
|
|
916
|
-
below (§"Grounded example — the Related facet AFTER inserting the component"), where you're editing a
|
|
917
|
-
page retrieved from the org. A page built fully from scratch, like this fallback skeleton, has no
|
|
918
|
-
parent region to override, so `<mode>Replace</mode>` on one of its facets fails dry-run (confirmed
|
|
919
|
-
against a live org):
|
|
920
|
-
`The '<facet>' region (type Facet) specifies mode 'REPLACE' but a parent region enabling that mode
|
|
921
|
-
doesn't exist.` Omit `<mode>` entirely on every `flexiPageRegions` element you author fresh.
|
|
922
|
-
|
|
923
|
-
That reproduces the standard record page — highlights, a Details tab (record detail), a Related
|
|
924
|
-
tab (related lists) with the FH component in Related, and an **Activities panel in the right-hand
|
|
925
|
-
sidebar**. **Always include the sidebar Activities panel** — the full three-region shape above is the
|
|
926
|
-
fallback page to build; don't drop the sidebar. (Grounded: `runtime_sales_activities:activityPanel`
|
|
927
|
-
in a `sidebar`-region tabset facet passes a dry-run on a live org at the org's max API version;
|
|
928
|
-
the tab is titled `Activity` — a literal custom label, not the `Standard.Tab.activities` token.) A **Chatter** tab is deliberately NOT
|
|
929
|
-
included here — `forceChatter:feed` in that facet fails dry-run ("component isn't allowed in the
|
|
930
|
-
region … doesn't implement any of the region's allowed interfaces"), so the correct Chatter
|
|
931
|
-
component/placement is `inferred` and unverified; don't add a chatter tab to this skeleton until it's
|
|
932
|
-
grounded. The FH component still obeys the Related-facet placement rule below (resolve the facet from
|
|
933
|
-
the tab whose `title=Standard.Tab.relatedLists` via its `body`). Only if even this complete build
|
|
934
|
-
fails dry-run should you consider a reduced page — and if you do, say so in the activation alert.
|
|
935
|
-
|
|
936
|
-
**Place the component in the Related section — resolve the region by tab, not by guessing.** The
|
|
937
|
-
component goes into the cloned page's **Related** area — not the highlights panel, not a new
|
|
938
|
-
top-of-page region. On a real Account record page the Related area is **not** a top-level
|
|
939
|
-
`<type>Region</type>`; it's a **`<type>Facet</type>` region** whose content is surfaced through a
|
|
940
|
-
`flexipage:tab`. Resolve it deterministically in the retrieved/cloned FlexiPage:
|
|
941
|
-
|
|
942
|
-
1. Find the `flexipage:tab` `componentInstance` whose `title` property is
|
|
943
|
-
**`Standard.Tab.relatedLists`** (the Related tab). Read its **`body`** property — that value is
|
|
944
|
-
the **`name` of the facet `flexiPageRegions`** holding the Related content (commonly
|
|
945
|
-
`relatedTabContent`). Don't hardcode the name; read it from the tab's `body` (custom pages can
|
|
946
|
-
name the facet differently).
|
|
947
|
-
2. In that facet region, **append a new `<itemInstances>` block** carrying a single
|
|
948
|
-
`componentInstance` for `flexible_hierarchy:flexibleHierarchyBase` with its own unique
|
|
949
|
-
`<identifier>` (e.g. `flexible_hierarchy_flexibleHierarchyBase`). Each `componentInstance` is
|
|
950
|
-
wrapped in its **own** `<itemInstances>` element — that's the real shape (each related-area
|
|
951
|
-
component sits in a separate `itemInstances` sibling), not multiple `componentInstance`s under
|
|
952
|
-
one `itemInstances`.
|
|
953
|
-
|
|
954
|
-
Preserve every existing component carried over from the source page (the highlights panel, the
|
|
955
|
-
related-list container, activity panel, the tabset/tab wiring, etc.) — you're **adding** the
|
|
956
|
-
component to the Related facet, not replacing the region's contents or its `<mode>Replace</mode>`.
|
|
957
|
-
Keep the `itemInstances > componentInstance` shape and the `<identifier>` requirement from the rule
|
|
958
|
-
above for the added instance.
|
|
959
|
-
|
|
960
|
-
**Grounded example — the Related facet AFTER inserting the component into the retrieved page's XML**
|
|
961
|
-
(from a real retrieved Account page, `parentFlexiPage=sfa__Account_rec_L`). This is the *insertion
|
|
962
|
-
target*, not a page to author from scratch: you retrieve the live FlexiPage (above), locate its
|
|
963
|
-
`relatedTabContent` facet, and add the FH component's `itemInstances` block — shown here as the
|
|
964
|
-
first block, ahead of the page's existing merge-preview and related-list-container components, all
|
|
965
|
-
of which stay:
|
|
966
|
-
|
|
967
|
-
```xml
|
|
968
|
-
<flexiPageRegions>
|
|
969
|
-
<itemInstances>
|
|
970
|
-
<componentInstance>
|
|
971
|
-
<componentName>flexible_hierarchy:flexibleHierarchyBase</componentName>
|
|
972
|
-
<identifier>flexible_hierarchy_flexibleHierarchyBase</identifier>
|
|
973
|
-
</componentInstance>
|
|
974
|
-
</itemInstances>
|
|
975
|
-
<itemInstances>
|
|
976
|
-
<componentInstance>
|
|
977
|
-
<!-- existing related-list container, preserved -->
|
|
978
|
-
<componentName>force:relatedListContainer</componentName>
|
|
979
|
-
<identifier>force_relatedListContainer</identifier>
|
|
980
|
-
</componentInstance>
|
|
981
|
-
</itemInstances>
|
|
982
|
-
<mode>Replace</mode>
|
|
983
|
-
<name>relatedTabContent</name>
|
|
984
|
-
<type>Facet</type>
|
|
985
|
-
</flexiPageRegions>
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
That `relatedTabContent` facet is bound into the page by a `flexipage:tab`
|
|
989
|
-
(`title=Standard.Tab.relatedLists`, `body=relatedTabContent`) sitting in the `maintabs` facet, which
|
|
990
|
-
is the `tabs` of the `flexipage:tabset` in the page's `main` `<type>Region</type>` — so the resolve-
|
|
991
|
-
by-tab walk in step 1 above lands you here.
|
|
992
|
-
|
|
993
|
-
**Activation is a separate action from the deploy — confirm before activating.** Deploying the
|
|
994
|
-
`FlexiPage` only *creates* the page; because this step **always clones into a new page** (the clone,
|
|
995
|
-
or the fresh fallback page), the deployed page is always inactive and users still see the current
|
|
996
|
-
page until it's assigned. **The activation gate therefore always applies** — every chosen object
|
|
997
|
-
produced a new page. **After the deploy, always ask before activating** — activation is the one
|
|
998
|
-
write in this step that keeps an **extra** explicit confirm on top of the per-step
|
|
999
|
-
query-then-write-then-advance cycle (see the root skill's strict-sequential-mode section),
|
|
1000
|
-
because it changes what every user sees.
|
|
1001
|
-
|
|
1002
|
-
**This deploy-vs-activation split is internal mechanics — do NOT narrate it to the admin.** The
|
|
1003
|
-
paragraph above is authoring rationale for you, not a message to relay. Don't announce things like
|
|
1004
|
-
"Deploy only — activation is a separate confirmed step after," or explain that the deploy merely
|
|
1005
|
-
creates an inactive page; just perform the deploy quietly and go straight to the activation
|
|
1006
|
-
question below. The admin should see only the deploy result (done) and the activation Yes/No — not
|
|
1007
|
-
a lecture on why the two are separate.
|
|
1008
|
-
|
|
1009
|
-
**Before presenting the activation prompt — check for an existing higher-precedence
|
|
1010
|
-
assignment.** Activating only writes the object's **org-default** record-page assignment (the
|
|
1011
|
-
`View` `actionOverride` below), which is the *lowest* tier in Lightning's page-assignment
|
|
1012
|
-
precedence (App default > App + record type + profile > App + record type > App + profile >
|
|
1013
|
-
**Org default**). Every tier above org-default lives on a `CustomApplication`'s `Metadata`, as
|
|
1014
|
-
an entry with `actionName=View`, `type=Flexipage`, `pageOrSobjectType=<object>` — but **App
|
|
1015
|
-
Default and Profile Default are two separate sibling arrays, not one array split by an
|
|
1016
|
-
attribute**: `Metadata.actionOverrides` holds the App Default tier (no `profile` attribute) and
|
|
1017
|
-
the separate `Metadata.profileActionOverrides` array holds the Profile Default tier
|
|
1018
|
-
(admin-facing wording for the App + profile tier) — confirmed live as a distinct sibling field,
|
|
1019
|
-
not merged into `actionOverrides`; scanning only one misses a whole precedence tier. Rather than
|
|
1020
|
-
only caveating about this after the fact, check for one **before** asking the admin anything, via
|
|
1021
|
-
Tooling API SOQL (`GET /services/data/v66.0/tooling/query`) in two passes: (1) enumerate —
|
|
1022
|
-
`SELECT Id, DeveloperName FROM CustomApplication` with NO `Metadata` field and no `WHERE` clause
|
|
1023
|
-
(confirmed live: 200, returned all 31 apps in one call, unrestricted row count since `Metadata`
|
|
1024
|
-
wasn't selected); (2) per-app read — for each `DeveloperName` from pass 1, `SELECT Id,
|
|
1025
|
-
DeveloperName, Metadata FROM CustomApplication WHERE DeveloperName='<app>'` (confirmed live: 200,
|
|
1026
|
-
returns the app's full `Metadata` blob). Scan both `actionOverrides` and `profileActionOverrides`
|
|
1027
|
-
from pass 2 for a match on this object.
|
|
1028
|
-
|
|
1029
|
-
**Every other transport for this read was tried live and failed — do not rediscover this from
|
|
1030
|
-
scratch:** `/headless/metadata` `readMetadata` on `type=CustomApplication` is NOT a substitute
|
|
1031
|
-
for pass 2 above — confirmed live: it actually succeeds (`200`, full metadata) for standard
|
|
1032
|
-
apps, but only when `fullName` carries the Metadata API's `standard__` prefix (e.g.
|
|
1033
|
-
`standard__Sales`); the bare `DeveloperName` from pass 1 404s `INVALID_CROSS_REFERENCE_KEY`
|
|
1034
|
-
instead, and two custom-named apps tried the same way 404'd too, so no working `fullName`
|
|
1035
|
-
convention for custom apps is confirmed. Since that prefix isn't derivable from the
|
|
1036
|
-
enumeration step, use the two-pass Tooling SOQL above instead of this transport.
|
|
1037
|
-
`/headless/metadata?type=CustomApplication` with no `fullName` (a bare list) 400s `INVALID_INPUT`
|
|
1038
|
-
("Query parameters 'type' and 'fullName' are required") — no list-without-a-name mode either.
|
|
1039
|
-
`ActionOverride` is NOT a queryable sObject/Tooling type on its own — confirmed live: `400
|
|
1040
|
-
INVALID_TYPE` ("sObject type 'ActionOverride' is not supported"); it only exists nested inside
|
|
1041
|
-
`CustomApplication`/`CustomObject` `Metadata`. A bare bulk Tooling query selecting `Metadata` (or
|
|
1042
|
-
`FullName`) across every `CustomApplication` row at once, with no `WHERE` narrowing to one row,
|
|
1043
|
-
400s `MALFORMED_QUERY` ("query qualifications must specify no more than one row for retrieval")
|
|
1044
|
-
— either field forces exactly one row, hence the two-pass split above. Never call the `sf` CLI
|
|
1045
|
-
directly as the served step, and never scaffold a local DX project (`sfdx-project.json`, a
|
|
1046
|
-
`package.xml` manifest, a `retrieved/` output dir) to do this read — confirmed live: `sf project
|
|
1047
|
-
retrieve start --manifest package.xml` outside a DX project gets `InvalidProjectWorkspaceError`,
|
|
1048
|
-
and a full-org `sf` retrieve of every app also timed out/got killed live. None of these problems
|
|
1049
|
-
exist on the two-pass Tooling SOQL query above.
|
|
1050
|
-
|
|
1051
|
-
- **No match found** → nothing to check; go straight to the standard/fallback prompt below.
|
|
1052
|
-
- **One or more matches found** → surface the conflict to the admin BEFORE the standard prompt
|
|
1053
|
-
(skip straight to the conflict prompt, don't show the plain org-default question first). If
|
|
1054
|
-
matches exist at more than one app/tier, lead with the highest-precedence one found (App
|
|
1055
|
-
Default before Profile Default) and just mention the others exist.
|
|
1056
|
-
|
|
1057
|
-
> Heads-up: `<object>` already has a page activated as the **App Default for `<App Name>`**
|
|
1058
|
-
> (or: **Profile Default for `<Profile Name>` on `<App Name>`**, whichever was found).
|
|
1059
|
-
> Activating the new page as the **org default** won't change that — those users keep seeing
|
|
1060
|
-
> the existing page, not this one.
|
|
1061
|
-
> Do you want to **override** that assignment so it shows the new page instead, or just set
|
|
1062
|
-
> the **org default** (the new page will only show for users who don't already have a
|
|
1063
|
-
> more-specific assignment)?
|
|
1064
|
-
> - **Override the app/profile default** — ⚠️ this replaces the page currently assigned there;
|
|
1065
|
-
> any configuration specific to that existing assignment is lost, and the change affects
|
|
1066
|
-
> every user under that app/profile, not just you.
|
|
1067
|
-
> - **Just set the org default** — leaves the existing app/profile assignment untouched; those
|
|
1068
|
-
> users won't see the new page.
|
|
1069
|
-
> - **Neither** — skip activation; the new page stays deployed but inactive.
|
|
1070
|
-
|
|
1071
|
-
- **Override** → retrieve the matched `CustomApplication`'s current metadata, replace that one
|
|
1072
|
-
matched `actionOverrides` entry's `content` with the newly-deployed page's `DeveloperName`
|
|
1073
|
-
(keep its existing `profile`/`recordType`/`formFactor` attributes as-is — only `content`
|
|
1074
|
-
changes), leave every other entry in the array untouched, redeploy, then re-retrieve and
|
|
1075
|
-
confirm the entry now reads `content=<the new page>` before reporting success.
|
|
1076
|
-
- **Just set the org default** → fall through to the standard/fallback prompt below exactly as
|
|
1077
|
-
if no conflict had been found.
|
|
1078
|
-
- **Neither** → stop here; report the page as deployed-but-inactive, same as declining the
|
|
1079
|
-
standard prompt below.
|
|
1080
|
-
|
|
1081
|
-
**Fallback case — when the page was freshly built because the active page couldn't be cloned, the
|
|
1082
|
-
activation question MUST carry an extra alert.** For a *cloned* page the admin is activating a copy of
|
|
1083
|
-
what they already had plus the FH component, so the standard prompt below is fine. But for the
|
|
1084
|
-
*system-default fallback*, the deployed page is a **brand-new complete page**, not the admin's
|
|
1085
|
-
existing layout — so before the Yes/No, tell them plainly what happened and what activating will do.
|
|
1086
|
-
This "couldn't clone, so I built X" disclosure is the one thing to surface in the fallback case (it
|
|
1087
|
-
is admin-facing, unlike the deploy-vs-activation mechanics above, which stay unnarrated). Use the
|
|
1088
|
-
fallback prompt instead of the standard one:
|
|
1089
|
-
> Heads-up: `<object>`'s current record page is the Salesforce **system default**, which can't be
|
|
1090
|
-
> retrieved to clone — so I built a **fresh complete page** (highlights panel, record details,
|
|
1091
|
-
> related lists, an Activities panel, plus the Flexible Hierarchy component). Activating it as the org default will
|
|
1092
|
-
> **replace** the current layout for every `<object>` user.
|
|
1093
|
-
> ⚠️ **Heads-up:** this sets the page as **`<object>`'s org default** — the lowest-precedence
|
|
1094
|
-
> tier. That only changes what's shown to users who don't already have a more-specific app- or
|
|
1095
|
-
> profile-level assignment (checked above); if one exists and you'd rather change that instead,
|
|
1096
|
-
> decline here and pick the override choice above, or use Lightning App Builder → **Activation**
|
|
1097
|
-
> later.
|
|
1098
|
-
> Activate this new page as the **org default** for `<object>` now?
|
|
1099
|
-
> - **Yes** — every `<object>` user sees this new page instead of the system default.
|
|
1100
|
-
> - **No** — it stays deployed but inactive and the system default stays in place; you can activate
|
|
1101
|
-
> it later in Lightning App Builder.
|
|
1102
|
-
|
|
1103
|
-
For the cloned-page case, the standard prompt applies:
|
|
1104
|
-
> The `<object>` record page is deployed, but it isn't active yet.
|
|
1105
|
-
> ⚠️ **Heads-up:** this sets the page as **`<object>`'s org default** — the lowest-precedence
|
|
1106
|
-
> tier. That only changes what's shown to users who don't already have a more-specific app- or
|
|
1107
|
-
> profile-level assignment (checked above); if one exists and you'd rather change that instead,
|
|
1108
|
-
> decline here and pick the override choice above, or use Lightning App Builder → **Activation**
|
|
1109
|
-
> later.
|
|
1110
|
-
> Activate it as the **org default** record page for `<object>` now?
|
|
1111
|
-
> - **Yes** — every `<object>` user sees this page.
|
|
1112
|
-
> - **No** — it stays deployed but inactive; you can activate it later in Lightning App Builder.
|
|
1113
|
-
- **No** (the default posture) → stop here; report the page as deployed-but-inactive and note it
|
|
1114
|
-
can be activated later in Lightning App Builder → Activation.
|
|
1115
|
-
- **Yes** → assign the deployed page as the **org default** record page for that object. The
|
|
1116
|
-
org-default assignment is **not** a field on the `FlexiPage` or a standalone metadata type —
|
|
1117
|
-
do NOT add an `<activations>` element to the `FlexiPage` XML itself (confirmed live: MDAPI
|
|
1118
|
-
deploy rejects it — `"Error parsing file: Element {http://soap.sforce.com/2006/04/metadata}
|
|
1119
|
-
activations invalid at this location in type FlexiPage"`). It
|
|
1120
|
-
is the object's **`View` `actionOverride`** on its `CustomObject`. Deploy a decomposed
|
|
1121
|
-
`CustomObject` fragment for the object carrying an `actionOverrides` block with
|
|
1122
|
-
`actionName=View`, `type=Flexipage`, `content=<the FlexiPage DeveloperName>` (App Builder's
|
|
1123
|
-
"Assign as Org Default" for desktop flips the `formFactor=Large` View override; set that one and
|
|
1124
|
-
leave the `Small`/phone override alone unless the admin asks). Scope it to the confirmed object
|
|
1125
|
-
only — do not touch app-, profile-, or record-type-level assignments. Dry-run first, deploy at
|
|
1126
|
-
the org's max supported API version (discovered in Step 1), then **re-read the object's `View` `actionOverride` and confirm it
|
|
1127
|
-
now reads `type=Flexipage` with `content` = the deployed page** — a deploy "Succeeded" is not
|
|
1128
|
-
proof it took (verified against a live org: after the CustomObject deploy, the Account `Large`
|
|
1129
|
-
View override re-read as `type=Flexipage`, `content=Account_Flexible_Hierarchy_Record_Page`,
|
|
1130
|
-
while the untouched form factors stayed `type=Default`). If the re-read still shows
|
|
1131
|
-
`type=Default`, report it as not activated and direct the admin to Lightning App Builder →
|
|
1132
|
-
Activation rather than reporting success.
|
|
1133
|
-
9. **Create hierarchy type(s)** — deploy a **`RelationshipGraphDefinition`** metadata component.
|
|
1134
|
-
This is where the confirmed hierarchy type gets created.
|
|
1135
|
-
|
|
1136
|
-
**Modality gate FIRST, before anything else in this step — Bespoke vs. Rule-Based.** Check
|
|
1137
|
-
`rule_based_pref_state`: only when it is `already-on` or `enabled` (i.e. `enableRuleBasedHierarchyPref`
|
|
1138
|
-
is actually on), ask the admin a multiple-choice modality question **before** the Path A/Path B
|
|
1139
|
-
fork below — on its own, in its own message, not combined with any other step's question:
|
|
1140
|
-
|
|
1141
|
-
> This org has the Rule-Based Hierarchy preference enabled. How do you want to create this
|
|
1142
|
-
> hierarchy type?
|
|
1143
|
-
> - **Bespoke Configuration** — author nodes and relationships directly (the existing flow).
|
|
1144
|
-
> - **Rule Based Configuration** — author role-based rules (filters + automatic parent/child
|
|
1145
|
-
> expansion) on top of the node list.
|
|
1146
|
-
|
|
1147
|
-
When `rule_based_pref_state` is anything else (`skipped`, `declined-at-confirm`, or the pref was
|
|
1148
|
-
never reached because Step 4 was version-gated out), **skip this question entirely** — proceed
|
|
1149
|
-
straight to Bespoke exactly as before. Never ask the modality question when the preference isn't
|
|
1150
|
-
actually on.
|
|
1151
|
-
|
|
1152
|
-
- **Bespoke Configuration chosen (or the question was skipped because the pref is off):**
|
|
1153
|
-
proceed exactly as documented below — no change from today's behavior.
|
|
1154
|
-
- **Rule Based Configuration chosen:** delegate instead to
|
|
1155
|
-
**`delegates_to: fsc-darksaber/fsc-flexible-hierarchy-configure-fsc-flexible-hierarchy-rule-based-graph-config-create`**
|
|
1156
|
-
(the fsc-flexible-hierarchy-rule-based-graph-config-create sub-skill) in place of the bespoke delegation below. It
|
|
1157
|
-
captures the same node list this step's bespoke path would, **plus** the `rules.graph.rootNode`
|
|
1158
|
-
rule tree (role, qualifying filters, and OneToMany/ManyToMany child relationships) before the
|
|
1159
|
-
same confirm-then-deploy-then-read-back flow. Record which modality was used in
|
|
1160
|
-
`hierarchy_type` for the end-of-step report. See
|
|
1161
|
-
[`../fsc-flexible-hierarchy-rule-based-graph-config-create/SKILL.md`](../fsc-flexible-hierarchy-rule-based-graph-config-create/SKILL.md) for
|
|
1162
|
-
the full flow and
|
|
1163
|
-
[`../fsc-flexible-hierarchy-rule-based-graph-config-create/references/rule-based-hierarchy-payload.md`](../fsc-flexible-hierarchy-rule-based-graph-config-create/references/rule-based-hierarchy-payload.md)
|
|
1164
|
-
for the payload schema — grounded in an admin-provided sample, not an exhaustively validated
|
|
1165
|
-
schema (see that reference's Grounding section).
|
|
1166
|
-
|
|
1167
|
-
**⚠️ Do NOT compose or present a deploy plan yourself right after the admin picks Rule Based
|
|
1168
|
-
Configuration.** The very next turn is the sub-skill's own "Do you already have a Rule-Based
|
|
1169
|
-
hierarchy config ready to deploy, or should I build one with you?" fork — confirmed live: a run
|
|
1170
|
-
skipped straight from the modality choice to presenting a deploy summary with invented values
|
|
1171
|
-
(developer name, root object) and never asked that fork question at all. If you're about to
|
|
1172
|
-
describe field values for the hierarchy type without having asked it first, stop and ask it now.
|
|
1173
|
-
|
|
1174
|
-
**The rest of this step (Bespoke path) is unchanged:** **Ask the "have a config or build one?"
|
|
1175
|
-
(Path A / Path B) fork FIRST, before asking for a name** — a Path A config already carries its
|
|
1176
|
-
`masterLabel`, so a name is only asked when building from scratch (Path B), never defaulted (there
|
|
1177
|
-
is no default hierarchy type). **The one write in this step — the `RelationshipGraphDefinition`
|
|
1178
|
-
deploy — is gated by an explicit confirm immediately before it** (the sub-skill shows the name +
|
|
1179
|
-
root object and asks for a go-ahead just before deploying). `RelationshipGraphDefinition`
|
|
1180
|
-
is a deployable MDAPI type (`metadataApiName="RelationshipGraphDefinition"`, `manageable`,
|
|
1181
|
-
`keyPrefix="06J"`), but this is always a **create** (never an update), and creation is the one
|
|
1182
|
-
write in this skill that does **not** go through the generic `/headless/metadata` facet used
|
|
1183
|
-
everywhere else — that facet's PUT is update-only for this type and 400s with
|
|
1184
|
-
`INVALID_CROSS_REFERENCE_KEY` ("Component does not exist") against a `DeveloperName` that doesn't
|
|
1185
|
-
exist yet (confirmed against a live org). The Tooling API's generic-sObject POST is
|
|
1186
|
-
`createable: true` for this type via `GET .../tooling/sobjects/RelationshipGraphDefinition/describe`,
|
|
1187
|
-
but for `GraphType: "FlexibleHierarchy"` specifically that POST is unreliable — confirmed live
|
|
1188
|
-
failing 5+ identical retries with `INVALID_FIELD_FOR_INSERT_UPDATE` on `GraphType`, on an org where
|
|
1189
|
-
the Setup UI and an MDAPI deploy of the identical payload both succeeded immediately after.
|
|
1190
|
-
**Create it via MDAPI deploy instead:** `sf project deploy start --source-dir <path>` against a
|
|
1191
|
-
`relationshipGraphDefinitions/<DeveloperName>.relationshipGraphDefinition-meta.xml` component with
|
|
1192
|
-
the same field shape JSON would carry, HTML-escaped into XML — see
|
|
1193
|
-
[`../graph-config-create/references/hierarchy-type-payload.md`](../graph-config-create/references/hierarchy-type-payload.md)
|
|
1194
|
-
for the exact shape and full transport-failure writeup. Not a Java service call either way. There is no
|
|
1195
|
-
`FlexibleHierarchyType` sObject despite the `FlexibleHierarchySetup` Setup node's name; a
|
|
1196
|
-
`FlexibleHierarchy` instance's `HierarchyTypeReferenceId` is a lookup to this record — creating
|
|
1197
|
-
the actual `FlexibleHierarchy` instance is out of scope for this skill.
|
|
1198
|
-
|
|
1199
|
-
**Read-back — query only the sObject's queryable columns.** When you verify the deployed
|
|
1200
|
-
component by SOQL, `RelationshipGraphDefinition` exposes just `Id`, `IsDeleted`, `DeveloperName`,
|
|
1201
|
-
`Language`, `MasterLabel`, `NamespacePrefix`, and the audit fields
|
|
1202
|
-
(`CreatedDate`/`CreatedById`/`LastModifiedDate`/`LastModifiedById`/`SystemModstamp`) — confirmed against a live org. **`GraphType`, `RootObject`, and `IsActive` are NOT queryable columns** (they
|
|
1203
|
-
live inside `relationshipGraphDefVersions`/`graphDefinition`); selecting or filtering on them fails
|
|
1204
|
-
with `INVALID_FIELD` ("No such column"). Verify existence with
|
|
1205
|
-
`SELECT Id, DeveloperName, MasterLabel FROM RelationshipGraphDefinition WHERE DeveloperName='<Name>'`
|
|
1206
|
-
— don't reach for `GraphType`/`RootObject`/`IsActive` in the read-back.
|
|
1207
|
-
|
|
1208
|
-
**Build the bespoke config — delegate, do not re-author it here.** On the **Bespoke
|
|
1209
|
-
Configuration** branch of the modality gate above (the only branch when the Rule-Based preference
|
|
1210
|
-
isn't on), this step
|
|
1211
|
-
**`delegates_to: fsc-darksaber/fsc-flexible-hierarchy-configure-graph-config-create`** (the
|
|
1212
|
-
graph-config-create sub-skill) — nodes and relations authored directly. See the out-of-scope note
|
|
1213
|
-
in the End state below for what's still deferred outside the two modality branches above. That
|
|
1214
|
-
sub-skill owns the whole bespoke flow: the Path A
|
|
1215
|
-
(admin brings a config) / Path B (build from scratch) branch **asked first** (Path A reads the type
|
|
1216
|
-
name from the config's own `masterLabel`; only Path B asks for a name — no description either way,
|
|
1217
|
-
that element is invalid on `RelationshipGraphDefinition`),
|
|
1218
|
-
root/node object selection from the 11-object allowlist, per-object graph/grid
|
|
1219
|
-
view fields, node-relationship definition, the `flexibleHierarchy`-placement pitfall, the confirm
|
|
1220
|
-
shown right before the deploy, the deploy-and-read-back of the `RelationshipGraphDefinition`
|
|
1221
|
-
component, and the full per-field
|
|
1222
|
-
checklist in [`../graph-config-create/references/hierarchy-type-payload.md`](../graph-config-create/references/hierarchy-type-payload.md).
|
|
1223
|
-
Invoke it, don't inline the config-building logic — this keeps Step 9 a thin gate over the reusable
|
|
1224
|
-
sub-skill rather than duplicating (and drifting from) it.
|
|
1225
|
-
([Help: create hierarchy types](https://help.salesforce.com/s/articleView?id=ind.fsc_flexible_hierarchies_create_hierarchy_types.htm))
|
|
1226
|
-
|
|
1227
|
-
## End state
|
|
1228
|
-
|
|
1229
|
-
- Org connectivity confirmed and prerequisites (edition, Flexible Hierarchy license/org
|
|
1230
|
-
permission, ARC license/org permission, admin access) reported as an
|
|
1231
|
-
itemized ✅/❌ checklist, even when all pass
|
|
1232
|
-
- Flexible Hierarchies feature enabled — `IndustriesSettings.enableFlexibleHierarchyPref`
|
|
1233
|
-
confirmed `true` by re-read, not just a reported deploy. This preference is not reversible
|
|
1234
|
-
(no supported way to turn it back off), so the deploy only happens after a single explicit
|
|
1235
|
-
go-ahead confirm
|
|
1236
|
-
- (Optional, irreversible) Rule-Based Hierarchy preference — `enableRuleBasedHierarchyPref` — handled
|
|
1237
|
-
per the admin's choice: either **skipped** at the opt-in gate, reported **already-on** by the
|
|
1238
|
-
check-before-write read, **declined** at the "cannot be disabled" double-confirm, or **enabled** and
|
|
1239
|
-
confirmed `true` by re-read. Never turned on without both the opt-in Yes and the explicit
|
|
1240
|
-
irreversibility confirmation. Authoring the actual `rules.graph.rootNode` tree — role labels,
|
|
1241
|
-
filters, and OneToMany/ManyToMany child relationships — is now in scope, but only as Step 9's
|
|
1242
|
-
Rule-Based branch (see below); Step 4 itself only flips the org preference, it does not author
|
|
1243
|
-
any rule content
|
|
1244
|
-
- Existing permission-set assignments surfaced to the admin up front and confirmed as-is when no
|
|
1245
|
-
changes are needed (the step is skipped in that case); otherwise, for every target user
|
|
1246
|
-
individually: the permission set they need (one of exactly `FlexibleHierarchiesUser` /
|
|
1247
|
-
`FlexibleHierarchyManager` / `FlexibleHierarchyAdmin` — a fixed three-option pick, no typed/other
|
|
1248
|
-
option) collected via the per-user query — never all three, and never a permission set applied to a
|
|
1249
|
-
user who wasn't individually asked. Each user is **confirmed with a single per-user go-ahead
|
|
1250
|
-
immediately before that user's assignment is written** (pick → role → ARC → confirm → write, then
|
|
1251
|
-
offer the next user) — a simple yes/change/skip right before each write, not a batched plan-review
|
|
1252
|
-
of everyone at once
|
|
1253
|
-
- ARC access treated as **required** for every user to work with hierarchies, defaulted to Yes and
|
|
1254
|
-
assigned per-user via whichever permission set (`FSCSales` / `FSCService` /
|
|
1255
|
-
`FinancialServicesCloudExtension`) is actually present on this org — resolved once up front, not
|
|
1256
|
-
assumed to be `FSCSales` (same check-then-assign discipline as the Flexible Hierarchy permission
|
|
1257
|
-
set), unless the admin explicitly declined it for a specific user
|
|
1258
|
-
- (Optional) Object permissions granted to the admin-chosen **profile** via
|
|
1259
|
-
`<objectPermissions>` on the master **`FlexibleHierarchy`** (the detail objects
|
|
1260
|
-
`FlexibleHierarchyNode`/`FlexibleHierarchyNodeRela` inherit it and can't carry their own), confirmed
|
|
1261
|
-
by an `ObjectPermissions` read — or the step skipped by the admin (the Step 5 role sets already cover
|
|
1262
|
-
master-object CRUD). This step grants via a profile only; the permission-set path is out of scope
|
|
1263
|
-
- Existing hierarchy node-role picklist values surfaced to the
|
|
1264
|
-
admin and confirmed as-is when no more are needed (the deploy is skipped in that case) —
|
|
1265
|
-
otherwise new values collected from the admin (comma-separated) and merged onto the existing
|
|
1266
|
-
`FlexibleHierarchyNodeRole` `StandardValueSet` via `updateMetadata`
|
|
1267
|
-
- Hierarchy type created for the confirmed type (e.g. Legal Entity) — **Bespoke** by default, or
|
|
1268
|
-
**Rule-Based** when `rule_based_pref_state` is `already-on`/`enabled` and the admin picked it at
|
|
1269
|
-
the modality gate (`hierarchy_config_mode`). Either way, the Path A / Path B fork is asked first (a
|
|
1270
|
-
name is only asked when building from scratch, since a Path A config carries its own
|
|
1271
|
-
`masterLabel`), and a `RelationshipGraphDefinition` component **deployed only after an explicit
|
|
1272
|
-
confirm shown right before the deploy** (name + root object) via **MDAPI deploy**
|
|
1273
|
-
(`sf project deploy start --source-dir <path>`) — not the Tooling API POST, which fails
|
|
1274
|
-
unreliably for `GraphType: "FlexibleHierarchy"` — from the admin's own config or one
|
|
1275
|
-
built with them, confirmed by read-back. The Rule-Based path additionally builds the
|
|
1276
|
-
`rules.graph.rootNode` tree (role, filters, OneToMany/ManyToMany child relationships) before that
|
|
1277
|
-
same confirm-then-deploy
|
|
1278
|
-
- Hierarchy view component placement decided with the admin (multi-select over the 11 supported
|
|
1279
|
-
objects) and, per chosen object, added to the **Related section** of a **clone of the object's
|
|
1280
|
-
currently-active page** (whether that active page is custom or the system default; falling back to a
|
|
1281
|
-
fresh page when the active page can't be cloned) — never editing any page in place. Because every
|
|
1282
|
-
chosen object produces a new page, activation is always confirmed with the admin — first checking
|
|
1283
|
-
every `CustomApplication` for an existing App Default / Profile Default assignment on that object
|
|
1284
|
-
and, if one exists, letting the admin choose to override it there instead of (or as well as) the
|
|
1285
|
-
org default. Whichever assignment was written is verified by re-read to confirm it points at the
|
|
1286
|
-
deployed page (left deployed-but-inactive when the admin declined activation entirely)
|
|
1287
|
-
|
|
1288
|
-
## Gotchas learned from the Setup Discovery config
|
|
1289
|
-
|
|
1290
|
-
- **Feature enablement is two layers, not one.** The **Flexible Hierarchy** org permission is a
|
|
1291
|
-
license/provisioning-controlled org permission — not something this skill or an admin can
|
|
1292
|
-
flip; it comes from SKU/entitlement. `OrgPreferences.FlexibleHierarchyPref` is the genuine
|
|
1293
|
-
admin-toggleable preference (`editAccess` requires the org permission + admin + `ViewSetup`),
|
|
1294
|
-
and it's what Step 3 actually deploys. If the org permission is missing, the preference's
|
|
1295
|
-
access gate blocks the deploy from taking effect even though the deploy itself may report
|
|
1296
|
-
"Changed" — always re-read the setting after deploying to confirm it actually stuck. This
|
|
1297
|
-
preference is also **not reversible** — once turned on, there is no supported way to turn it
|
|
1298
|
-
back off — so Step 3 asks a single go-ahead confirm before deploying (lighter than Step 4's
|
|
1299
|
-
double-confirm, since Step 4 gates a second, independently-irreversible preference stacked on
|
|
1300
|
-
top of this one).
|
|
1301
|
-
- **Rule-Based Hierarchy is a SECOND, one-way preference sitting beside the base feature.**
|
|
1302
|
-
`OrgPreferences.RuleBasedHierarchyPref` / `IndustriesSettings.enableRuleBasedHierarchyPref` is a
|
|
1303
|
-
sibling of `enableFlexibleHierarchyPref` in the same `IndustriesSettings` metadata, but the two do
|
|
1304
|
-
not surface at the same API version: `enableFlexibleHierarchyPref` (Step 3) is present in the
|
|
1305
|
-
retrieved xmlRep from **v66.0+**, whereas `enableRuleBasedHierarchyPref` appears only from **v68.0+**
|
|
1306
|
-
and is absent from the xmlRep entirely at v66.0/v67.0 (grounded live: retrieving the same FSC org at
|
|
1307
|
-
v68 returned both `<enableFlexibleHierarchyPref>true</enableFlexibleHierarchyPref>` and
|
|
1308
|
-
`<enableRuleBasedHierarchyPref>false</enableRuleBasedHierarchyPref>`, while the v66.0 and v67.0
|
|
1309
|
-
retrieves returned only the `enableFlexibleHierarchyPref` element). So don't assume RBH is queryable
|
|
1310
|
-
wherever the base feature is — it follows Step 4's version gate: available only when the org's pinned
|
|
1311
|
-
max version is **v68.0 or higher**, silently skipped at v66.0/v67.0. Two things warrant an
|
|
1312
|
-
*extra* gate here beyond Step 3's single confirm, even though both preferences are equally
|
|
1313
|
-
irreversible: (1) this one is **optional** — many admins don't need Rule-Based mode at all — so
|
|
1314
|
-
Step 4 requires an explicit double-confirm (opt-in, then a second confirm naming the
|
|
1315
|
-
irreversibility) to guard against accidentally opting into a permanent, org-wide mode change
|
|
1316
|
-
that wasn't actually wanted; Step 3's base feature isn't optional in that sense (nearly every
|
|
1317
|
-
Flexible Hierarchy setup needs it), so one confirm suffices there; and (2) an org that already has
|
|
1318
|
-
`FlexibleHierarchyPref` on can (rarely) already have this on too, so Step 4 does a
|
|
1319
|
-
check-before-write MDAPI read and skips the deploy when it's already `true`. This step only flips the
|
|
1320
|
-
preference; authoring rule configuration itself happens later, conditionally, at Step 9's modality
|
|
1321
|
-
gate (see [`../fsc-flexible-hierarchy-rule-based-graph-config-create/SKILL.md`](../fsc-flexible-hierarchy-rule-based-graph-config-create/SKILL.md)).
|
|
1322
|
-
- **ARC has no enablement preference at all — it's permission-only.** The **ARC** org permission
|
|
1323
|
-
gates the `RelationshipGraphDefinition` object and the user-level ARC permission directly, with
|
|
1324
|
-
no `OrgPreferences.*` toggle sitting on top the way `FlexibleHierarchyPref` does for Flexible
|
|
1325
|
-
Hierarchy. That's why Step 2 only *checks* for it (report ✅/❌) rather than Step 3 having a
|
|
1326
|
-
matching "enable ARC" sub-step — there's nothing to toggle; it's provisioned or it isn't. The
|
|
1327
|
-
user-level grant itself is headless too — Step 5 assigns whichever standard permission set
|
|
1328
|
-
(`FSCSales` / `FSCService` / `FinancialServicesCloudExtension`) actually grants it on this org,
|
|
1329
|
-
resolved dynamically rather than assumed to be `FSCSales` — not a Setup-UI-only action.
|
|
1330
|
-
(Assuming `FSCSales` unconditionally is a real failure mode: orgs provisioned via
|
|
1331
|
-
the `FSCServiceAddon` SKU carry `FSCService` instead and have no `FSCSales` permission set at
|
|
1332
|
-
all, so a hardcoded check fails Step 5's pre-check outright on those orgs.)
|
|
1333
|
-
- **Not everything here is `dispatch`-dispatchable, but fewer steps are Setup-UI-only than
|
|
1334
|
-
the original config implied.** This config describes a Setup UI checklist, not a headless API
|
|
1335
|
-
contract, and See [`../../PLAN.md`](../../PLAN.md)'s step-type → transport mapping table for
|
|
1336
|
-
the full picture — but two steps originally modeled as bare `setup_discovery__Url` deep links
|
|
1337
|
-
turned out to have confirmed headless mechanisms during authoring: ARC access (Step 5, via
|
|
1338
|
-
whichever ARC-granting permission set is resolved present on the org) and hierarchy node roles
|
|
1339
|
-
(Step 7, via `updateMetadata` on the
|
|
1340
|
-
`FlexibleHierarchyNodeRole` `StandardValueSet`). `setup_discovery__UserAssignment`,
|
|
1341
|
-
`setup_discovery__RecordPage`, and `setup_discovery__OrgPreference` steps were already
|
|
1342
|
-
concretely automatable.
|
|
1343
|
-
- **Object permissions (`EnhancedProfiles`) are an optional step (Step 6), not out of scope.**
|
|
1344
|
-
Object CRUD is authored as `<objectPermissions>` on a **`Profile`** (this step grants via a profile
|
|
1345
|
-
only — the permission-set path is intentionally out of scope here); the step is skippable. A profile
|
|
1346
|
-
edit is heavier than a permission-set change — it hits every user assigned to that profile — so the
|
|
1347
|
-
offer says so and defaults to letting the admin skip. If they skip, the Step 5 role sets already
|
|
1348
|
-
cover master-object CRUD. **Object CRUD only lands on the master `FlexibleHierarchy`.** `FlexibleHierarchyNode` and
|
|
1349
|
-
`FlexibleHierarchyNodeRela` are master-detail children of `FlexibleHierarchy` (`FlexibleHierarchyId`,
|
|
1350
|
-
`relationshipOrder 0`), so they inherit object access from the master and can't hold their own
|
|
1351
|
-
`<objectPermissions>` — a deploy carrying detail-object blocks reports success but silently drops
|
|
1352
|
-
them (confirmed against a live org). Grant CRUD on the master and verify via the `ObjectPermissions`
|
|
1353
|
-
sObject, not the deploy response.
|
|
1354
|
-
- **OWD sharing (`SecuritySharing`) is out of scope — it can't be set headlessly for
|
|
1355
|
-
`FlexibleHierarchy`.** OWD is the `<sharingModel>` element inside the object's own `CustomObject`
|
|
1356
|
-
metadata, but `FlexibleHierarchy` is a **non-customizable standard entity**: the CustomObject MDAPI
|
|
1357
|
-
channel rejects both retrieve and deploy for it (`Can't deploy non-customizable CustomObject named:
|
|
1358
|
-
FlexibleHierarchy`, confirmed against a live org), and there is no "SecuritySharing" MDAPI type
|
|
1359
|
-
(that string is only the Setup UI node id). The current OWD value is *readable* via
|
|
1360
|
-
`EntityDefinition.InternalSharingModel` but not *writable* headlessly — changing it is a Setup →
|
|
1361
|
-
Sharing Settings UI action, so this skill does not attempt it. (The detail objects read as
|
|
1362
|
-
`ControlledByParent` and follow the master's OWD regardless.)
|
|
1363
|
-
**`PermSets` is still not part of this skill** — it's used only by the deferred
|
|
1364
|
-
`manageDataCloudObjectPermissions` step in `unlockAdvancedFunctionality` (granting Flexible
|
|
1365
|
-
Hierarchy object permissions to the Data Cloud integration permission set), which stays out of scope.
|
|
1366
|
-
- **`isRequired: false` on every record-page object** — the config offers placement on 11
|
|
1367
|
-
objects but mandates none of them. Don't deploy the component to all 11 by default; confirm
|
|
1368
|
-
scope with the admin first.
|
|
1369
|
-
|
|
1370
|
-
## Permission sets this skill may assign (from the per-user permission-set query)
|
|
1371
|
-
|
|
1372
|
-
Three role permission sets exist — `FlexibleHierarchiesUser`, `FlexibleHierarchyManager`,
|
|
1373
|
-
`FlexibleHierarchyAdmin` — but a given user needs exactly **one**, matching their intended role.
|
|
1374
|
-
When there are multiple target users, **ask the permission set separately for each user** — different users
|
|
1375
|
-
on the same request can legitimately need different permission sets; don't assign more than one per
|
|
1376
|
-
user, and don't apply one answer to the whole batch. These three are a **fixed, complete set** — the
|
|
1377
|
-
per-user role picker presents exactly them, with no typed/"Other" fourth option. For each user,
|
|
1378
|
-
gather their role + ARC choice, **confirm that one user with a per-user go-ahead, and assign them
|
|
1379
|
-
immediately before moving to the next user** (Step 5's per-user confirm-then-write) — a simple
|
|
1380
|
-
yes/change/skip right before each write, not a batched plan-review of everyone at once. No further
|
|
1381
|
-
canonical-list reference doc exists yet for this skill (unlike `icm-setup`, which has a
|
|
1382
|
-
dedicated `licensing-and-permission-sets.md`); these three names are the complete set per the
|
|
1383
|
-
Setup Discovery config's `assignmentSources`.
|
|
1384
|
-
|
|
1385
|
-
Separately, an ARC-granting permission set is assigned per user for ARC access — it's not a
|
|
1386
|
-
Flexible Hierarchy role permission set, but ARC is **required** to work with hierarchies, so it's
|
|
1387
|
-
defaulted to Yes and assigned alongside the user's role permission set unless the admin explicitly
|
|
1388
|
-
declines it for that user (Step 5). **Which permission set that is varies by org/SKU — resolve it,
|
|
1389
|
-
don't hardcode it.** `FSCSales` (label "FSC Sales") is the common case, but an org provisioned via
|
|
1390
|
-
the `FSCServiceAddon` SKU carries `FSCService` instead and has no `FSCSales` permission set at
|
|
1391
|
-
all; `FinancialServicesCloudExtension` is a third known carrier. Step 5 queries which of these
|
|
1392
|
-
three exist on the org once, up front (`arc_permset`) — using the one present, asking the admin to
|
|
1393
|
-
pick when more than one is, and reporting the gap as blocked if none is — rather than assuming
|
|
1394
|
-
`FSCSales`.
|
|
1395
|
-
|
|
1396
|
-
Mechanically: check via `SELECT Id FROM PermissionSetAssignment WHERE AssigneeId = :userId AND
|
|
1397
|
-
PermissionSetId = :permSetId`; assign via a `PermissionSetAssignment` create
|
|
1398
|
-
(`AssigneeId`/`PermissionSetId`) on that user's per-user go-ahead (the Step 5 per-user confirm right
|
|
1399
|
-
before each write is the one gate — no separate batched plan-review on top). `DUPLICATE_VALUE`
|
|
1400
|
-
on that create = already assigned = success, not an error.
|
|
1401
|
-
|
|
1402
|
-
<!-- skill-validate: ignore-start -->
|
|
1403
|
-
<!-- codey:operations start -->
|
|
1404
|
-
## Operations Reference
|
|
1405
|
-
|
|
1406
|
-
Operations this skill uses — routing and dependency reference.
|
|
1407
|
-
|
|
1408
|
-
| Operation | Purpose | Status | Call | Depends on |
|
|
1409
|
-
|-----------|---------|--------|------|------------|
|
|
1410
|
-
| `step-1-confirm-org-connectivity` | discovery | — | `GET /services/data/` | — |
|
|
1411
|
-
| `step-2-validate-prerequisites` | validate | — | `GET /services/data/v66.0/query` | `step-1-confirm-org-connectivity` |
|
|
1412
|
-
| `step-3-enable-flexible-hierarchy-pref` | write | — | `PUT /services/data/v66.0/headless/metadata` | `step-2-validate-prerequisites` |
|
|
1413
|
-
| `step-3-verify-flexible-hierarchy-pref` | verify | — | `GET /services/data/v66.0/headless/metadata?type=IndustriesSettings&fullName=Industries` | `step-3-enable-flexible-hierarchy-pref` |
|
|
1414
|
-
| `step-4-enable-rule-based-hierarchy-pref` | write | — | `PUT /services/data/v68.0/headless/metadata` | `step-3-verify-flexible-hierarchy-pref` |
|
|
1415
|
-
| `step-4-verify-rule-based-hierarchy-pref` | verify | — | `GET /services/data/v68.0/headless/metadata?type=IndustriesSettings&fullName=Industries` | `step-4-enable-rule-based-hierarchy-pref` |
|
|
1416
|
-
| `step-5-resolve-arc-permission-set` | discovery | — | `GET /services/data/v66.0/query` | `step-2-validate-prerequisites` |
|
|
1417
|
-
| `step-5-assign-user-permission-sets` | write | — | `POST /services/data/v66.0/sobjects/PermissionSetAssignment` | `step-5-resolve-arc-permission-set`, `step-3-verify-flexible-hierarchy-pref` |
|
|
1418
|
-
| `step-6-grant-object-permissions` | write | — | `PUT /services/data/v66.0/headless/metadata` | `step-5-assign-user-permission-sets` |
|
|
1419
|
-
| `step-6-verify-object-permissions` | verify | — | `GET /services/data/v66.0/query` | `step-6-grant-object-permissions` |
|
|
1420
|
-
| `step-7-read-node-role-picklist` | discovery | — | `GET /sobjects/FlexibleHierarchyNode/describe` | `step-3-verify-flexible-hierarchy-pref` |
|
|
1421
|
-
| `step-7-configure-node-role-picklist` | write | — | `FlexibleHierarchyNode.Role.configure` | `step-7-read-node-role-picklist` |
|
|
1422
|
-
| `step-8-add-record-page-component` | write | — | `POST /services/data/v66.0/headless/metadata` | `step-3-verify-flexible-hierarchy-pref` |
|
|
1423
|
-
| `step-8-check-existing-app-profile-default` | discovery | — | `GET /services/data/v66.0/tooling/query` | `step-8-add-record-page-component` |
|
|
1424
|
-
| `step-8-activate-record-page-component` | write | — | `PUT /services/data/v66.0/headless/metadata` | `step-8-add-record-page-component`, `step-8-check-existing-app-profile-default` |
|
|
1425
|
-
| `step-8-verify-record-page-activation` | verify | — | `GET /services/data/v66.0/headless/metadata?type=CustomObject&fullName={object}` | `step-8-activate-record-page-component` |
|
|
1426
|
-
| `step-8-override-app-profile-default` | write | — | `PUT /services/data/v66.0/headless/metadata` | `step-8-check-existing-app-profile-default` |
|
|
1427
|
-
| `step-8-verify-app-profile-override` | verify | — | `GET /services/data/v66.0/tooling/query` | `step-8-override-app-profile-default` |
|
|
1428
|
-
| `step-9-check-existing-hierarchy-types` | discovery | — | `GET /services/data/v66.0/tooling/query` | `step-3-verify-flexible-hierarchy-pref` |
|
|
1429
|
-
<!-- codey:operations end -->
|
|
1430
|
-
<!-- skill-validate: ignore-end -->
|