Compare commits

...

3 Commits

Author SHA1 Message Date
Sébastien Varoteaux-Lavigne
55378c81c0
Merge dcc73dbeaa into abe0d620a4 2026-07-10 14:57:45 +02:00
Hemant Singh Bisht
abe0d620a4
docs(W-23363336): add stability disclaimer to README (#307)
Add stability disclaimer to README

Skills are under active development and don't carry GA-level stability
guarantees. This note sets expectations for developers who fork or sync
the repo that skill names, structure, and availability may change without
notice.

Signed-off-by: Hemant Singh Bisht <hsinghbisht@salesforce.com>
2026-07-09 21:34:02 +05:30
Lord SVL
dcc73dbeaa feat: add building-flow-approval-process skill
Adds a new skill for Salesforce Flow Approval Processes
(processType: ApprovalWorkflow), a distinct flow type not covered
by the existing generating-flow skill.

Key contributions:
- Full architecture guide: orchestration, Background Steps, Approval
  Steps, Screen Flows, WebLink trigger, Lightning page components
- Explicit delegation rule: AutoLaunched and Screen Flows are generated
  via the generating-flow MCP pipeline; only the ApprovalWorkflow
  orchestration XML is written manually
- Hard-stop constraints mapped to known deployment/runtime errors
- XML reference patterns in references/xml-patterns.md
- Common errors quick reference table with root causes and fixes
- Required deployment order to avoid dependency failures
2026-06-12 11:40:51 +02:00
3 changed files with 416 additions and 0 deletions

View File

@ -4,6 +4,8 @@ This repository provides a curated collection of Salesforce agent skills for bui
The skills are contributed by Salesforce and the broader community. Its optimized for Agentforce Vibes and can be used with any AI tool that supports skills.
> ⚠️ **Expect frequent changes.** The Salesforce skills library is evolving rapidly as we refine patterns and incorporate feedback. Skills may be renamed, restructured, or removed between releases — they do not follow the same stability guarantees as GA platform APIs. If youve forked or synced the repository, be prepared for upstream changes that may conflict with local modifications. This repository is always the source of truth.
## 🗂️ Structure
```

View File

@ -0,0 +1,175 @@
---
name: building-flow-approval-process
description: "Build Salesforce Flow Approval Processes (processType: ApprovalWorkflow). Use when the user wants to 'create a flow approval process', 'build an ApprovalWorkflow', 'set up multi-level approval with flows', 'configure approval orchestration', 'add approval stages to a flow', or encounters errors such as 'Submit for Approval doesn\\'t work with Flow Approval Processes' or 'Outputs reference doesn\\'t exist'. Not for Classic Approval Processes (Setup > Approval Processes)."
metadata:
version: "1.0"
---
## Goal
Design, implement, and deploy Salesforce Flow Approval Processes (`processType: ApprovalWorkflow`), covering the full stack: orchestration flow, background steps, approval steps, screen flows, WebLink triggers, and required Lightning page components.
## When to Use This Skill
Activate this skill for:
- Creating a new multi-level approval process using Flows (not Classic Approval Processes)
- Configuring `orchestratedStages`, Background Steps, and Approval Steps in an `ApprovalWorkflow` flow
- Setting up the WebLink button that launches the orchestration
- Debugging errors specific to Flow Approval Processes (`Submit for Approval not supported`, output reference syntax failures, subflow restrictions)
- Adding `Flow Orchestration Work Guide` and `Approval Trace` components to a record page
**Delegate elsewhere** for Classic Approval Processes (Setup > Approval Processes), record-triggered flows, or Apex-based approval routing.
## Classic vs. Flow Approval Process — Critical Distinction
| | Classic Approval Process | Flow Approval Process |
|---|---|---|
| Setup location | Setup > Approval Processes | Setup > Flows (`processType: ApprovalWorkflow`) |
| Trigger | `Submit for Approval` action | WebLink URL button → `/flow/FlowApiName?params` |
| Entry conditions | Record criteria | Background Step + Evaluation Flow |
| Steps | Linear steps | `orchestratedStages` containing `stageSteps` |
**Never use the "Submit for Approval" Flow action with an ApprovalWorkflow.** Salesforce documentation states explicitly: *"This action doesn't submit a record for approval using Flow Approval Processes."*
## Flow Generation — Mandatory Delegation
An ApprovalWorkflow solution involves multiple flows. Apply this rule for each:
| Flow type | How to generate |
|---|---|
| AutoLaunched flows (calculation, evaluation, status update) | **Use `generating-flow` skill** — 3-step MCP pipeline (`fetchGroundedObjectMetadata` → `flowElementSelection``flowElementGeneration`). Never write XML manually. |
| Screen Flow (approver review UI) | **Use `generating-flow` skill** — same 3-step MCP pipeline. |
| ApprovalWorkflow orchestration (`processType: ApprovalWorkflow`) | **Write XML manually** — the MCP pipeline does not support this processType. Use the XML patterns in `references/xml-patterns.md`. |
Generate all component flows **before** the orchestration. The orchestration references them by API name in `actionName` attributes.
## Core Workflow
1. **Define entry variables** — declare the 4 mandatory input variables on the orchestration
2. **Generate supporting flows** — use the `generating-flow` skill to create each AutoLaunched flow and the Screen Flow via the MCP pipeline
3. **Design orchestration stages** — model each approval level as an `orchestratedStage` with Background Steps and Approval Steps
4. **Wire decision routing** — use Decision elements between stages, referencing Background Step outputs via `{!StepName.Outputs.variableName}` syntax
5. **Write the ApprovalWorkflow orchestration XML** — using patterns from `references/xml-patterns.md`
6. **Create the WebLink trigger** — build the URL button on the object; add to the page layout
7. **Add Lightning components** — place Flow Orchestration Work Guide and Approval Trace on the record page
8. **Deploy in order** — follow the required deployment sequence to avoid dependency failures
9. **Validate** — submit a test record and verify each stage transitions correctly
## Architecture Pattern
```
WebLink Button
└── /flow/ApprovalOrchestration?recordId=...&submitter={!$User.Id}&retURL=...
└── ApprovalWorkflow (processType: ApprovalWorkflow)
├── Background Step → AutoLaunched Flow (calculate level / init status)
├── Decision (route by level output)
├── Stage N1
│ ├── Approval Step (Screen Flow — approver UI)
│ └── Background Step (update status)
├── Decision (Approve / Reject)
├── Stage N2 — same pattern
└── Stage N3 — same pattern
```
## Required Orchestration Variables
Declare these 4 input variables on every ApprovalWorkflow orchestration:
| Variable | dataType | isInput |
|---|---|---|
| `recordId` | String | true |
| `submitter` | String | true |
| `submissionComments` | String | true |
| `firstApprover` | String | true |
Missing any of these causes runtime errors even if the variable is not used in the flow logic.
## Step Types Reference
### Background Step
- `actionType: stepBackground` / `stepSubtype: BackgroundStep`
- Calls an AutoLaunched flow (`TriggerType: None`)
- `requiresAsyncProcessing: false`, `runAsUser: false`, `shouldLock: false`
- Inputs accept variable references or string literals only — no calculated expressions
### Approval Step
- `actionType: stepApproval` / `stepSubtype: ApprovalStep`
- Calls a Screen Flow for the approver UI
- `requiresAsyncProcessing: true`, `runAsUser: true`, `shouldLock: true`
- `assigneeType`: `Queue`, `User`, or `Group`
- Output `approvalDecision` must be exactly `"Approve"` or `"Reject"` (case-sensitive)
## Output Reference Syntax
Reference Background Step outputs in downstream elements:
```
{!StepName.Outputs.variableName}
```
- In a Decision element: `<leftValueReference>CalcLevel.Outputs.approvalLevel</leftValueReference>`
- In a subsequent Background Step input: `<elementReference>CalcLevel.Outputs.approvalLevel</elementReference>`
- Approval decision: `<leftValueReference>Approbation_N1.Outputs.approvalDecision</leftValueReference>`
## Screen Flow — Required Variables
The approver Screen Flow must declare these variables with exact names:
**Inputs:** `approvalInformation` (String), `recordId` (String)
**Outputs:** `approvalDecision` (String) — value must be exactly `"Approve"` or `"Reject"`; `approvalComments` (String)
Add a `faultConnector` on every `recordLookups` element displaying `{!$Flow.FaultMessage}`.
## Hard-Stop Constraints
These cause deployment or runtime failures:
- **No `<subflows>` element** in an ApprovalWorkflow — use Background Steps instead
- **No Custom Error elements** in AutoLaunched flows called by Background Steps (`TriggerType: None`)
- **No calculated expressions** as Background Step inputs — variable references and string literals only
- **No `Submit for Approval` action** to trigger an ApprovalWorkflow — WebLink URL only
- **No** `hasMenubar`, `height`, `position`, `isResizable` on a WebLink with `openType: replace`
- **Deletion via Metadata API fails** when the flow has execution history — delete from Setup UI
## Required Lightning Page Components
Add both components to the record page via Lightning App Builder:
1. **Flow Orchestration Work Guide** — shows pending work items to approvers
2. **Approval Trace** — shows approval history
Without these, approvers have no interface to process their work items.
## Deployment Order
Deploy in this sequence to avoid dependency errors:
1. Custom objects and fields
2. AutoLaunched flows (calculation, evaluation, status update)
3. Screen Flow (approver review UI)
4. ApprovalWorkflow orchestration
5. WebLink + page layout
```bash
SF_LOG_FILE=/dev/null sf project deploy start -m "Flow:MyFlowName" --ignore-conflicts -o my-org
```
## Common Errors Quick Reference
| Error | Cause | Fix |
|---|---|---|
| `This action doesn't submit a record for approval using Flow Approval Processes` | Classic "Submit for Approval" action used | Replace with WebLink URL button |
| `CalcLevel.approvalLevel doesn't exist` | Missing `Outputs.` in reference syntax | Use `CalcLevel.Outputs.approvalLevel` |
| `firstApprover / submissionComments received nothing` | Required orchestration variables missing | Declare all 4 mandatory input variables |
| `Flows of type ApprovalWorkflow can't include Subflow elements` | Subflow element used | Replace with Background Step |
| `Can't include Custom Error elements when TriggerType is None` | Custom Error in AutoLaunched flow | Remove Custom Error; let fault propagate |
| `insufficient access rights on cross-reference id` on delete | Flow has execution history | Delete from Setup UI, not Metadata API |
| WebLink deployment failure with `openType: replace` | Forbidden properties included | Remove `hasMenubar`, `hasScrollbars`, `height`, `position`, `isResizable` |
## Additional Resources
### Reference Files
For complete XML patterns and templates, consult:
- **`references/xml-patterns.md`** — Full XML for orchestration variables, WebLink, Background Step, Approval Step, and Screen Flow variables

View File

@ -0,0 +1,239 @@
# XML Patterns — Flow Approval Process
Complete XML reference for all components of a Flow Approval Process.
---
## Orchestration — Required Input Variables
```xml
<variables>
<name>recordId</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
<variables>
<name>submitter</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
<variables>
<name>submissionComments</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
<variables>
<name>firstApprover</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
```
---
## WebLink — Only Valid Trigger
```xml
<WebLink>
<fullName>LaunchApproval</fullName>
<availability>online</availability>
<displayType>button</displayType>
<linkType>url</linkType>
<openType>replace</openType>
<protected>false</protected>
<url>/flow/MyOrchestration?recordId={!Object__c.Id}&amp;submitter={!$User.Id}&amp;retURL=/{!Object__c.Id}</url>
</WebLink>
```
Add to the page layout as `actionType: CustomButton`.
**Do not include** `hasMenubar`, `hasScrollbars`, `height`, `position`, `isResizable` — these are forbidden with `openType: replace` and cause deployment failures.
---
## Background Step
Calls an AutoLaunched flow. Use for calculations, evaluations, and status updates.
```xml
<stageSteps>
<name>CalcLevel</name>
<actionName>MyAutoLaunchedFlow</actionName>
<actionType>stepBackground</actionType>
<stepSubtype>BackgroundStep</stepSubtype>
<inputParameters>
<name>recordId</name>
<value>
<elementReference>recordId</elementReference>
</value>
</inputParameters>
<outputConfigParams>
<name>approvalLevel</name>
<!-- Must match the output variable name in the called flow -->
<value xsi:nil="true"/>
</outputConfigParams>
<requiresAsyncProcessing>false</requiresAsyncProcessing>
<runAsUser>false</runAsUser>
<shouldLock>false</shouldLock>
<label>Calculate Level</label>
</stageSteps>
```
**Input constraints:** only variable references (`<elementReference>`) or string literals (`<stringValue>1</stringValue>`) are valid. Expressions and merge fields are not supported.
---
## Approval Step
Calls a Screen Flow for the approver UI.
```xml
<stageSteps>
<name>Approval_N1</name>
<actionName>Review_Approval_Screen_Flow</actionName>
<actionType>stepApproval</actionType>
<stepSubtype>ApprovalStep</stepSubtype>
<assignees>
<assignee>
<stringValue>MyQueueDeveloperName</stringValue>
</assignee>
<assigneeType>Queue</assigneeType>
<!-- Valid values: Queue | User | Group -->
</assignees>
<outputConfigParams>
<name>approvalDecision</name>
<value xsi:nil="true"/>
</outputConfigParams>
<requiresAsyncProcessing>true</requiresAsyncProcessing>
<runAsUser>true</runAsUser>
<shouldLock>true</shouldLock>
<label>Approval Level 1</label>
</stageSteps>
```
---
## Decision Element — Routing After Background Step
Reference Background Step outputs using the `Outputs.` prefix:
```xml
<decisions>
<name>RouteByLevel</name>
<label>Route by Approval Level</label>
<rules>
<name>Level1</name>
<conditionLogic>and</conditionLogic>
<conditions>
<leftValueReference>CalcLevel.Outputs.approvalLevel</leftValueReference>
<operator>EqualTo</operator>
<rightValue>
<stringValue>1</stringValue>
</rightValue>
</conditions>
<connector>
<targetReference>Stage_N1</targetReference>
</connector>
<label>Level 1</label>
</rules>
</decisions>
```
Decision after an Approval Step — check the `approvalDecision` output:
```xml
<leftValueReference>Approval_N1.Outputs.approvalDecision</leftValueReference>
<!-- Valid values: "Approve" or "Reject" — case-sensitive -->
```
---
## Screen Flow — Required Variables
The approver Screen Flow must expose these variables with the exact names shown.
```xml
<!-- Inputs -->
<variables>
<name>approvalInformation</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
<variables>
<name>recordId</name>
<dataType>String</dataType>
<isInput>true</isInput>
</variables>
<!-- Outputs — exact names required by the orchestration -->
<variables>
<name>approvalDecision</name>
<dataType>String</dataType>
<isOutput>true</isOutput>
<value>
<elementReference>ApprovalRadioButtons</elementReference>
</value>
</variables>
<!-- Radio button choices must produce exactly "Approve" or "Reject" -->
<variables>
<name>approvalComments</name>
<dataType>String</dataType>
<isOutput>true</isOutput>
</variables>
```
Add a `faultConnector` on every `recordLookups` element leading to a screen that displays `{!$Flow.FaultMessage}`.
---
## Orchestrated Stage — Full Structure
```xml
<orchestratedStages>
<name>Stage_N1</name>
<label>Stage Level 1</label>
<exitConditionLogic>and</exitConditionLogic>
<stageSteps>
<!-- Approval Step first -->
<name>Approval_N1</name>
<actionName>Review_Approval_Screen_Flow</actionName>
<actionType>stepApproval</actionType>
<stepSubtype>ApprovalStep</stepSubtype>
<assignees>
<assignee><stringValue>MyQueue</stringValue></assignee>
<assigneeType>Queue</assigneeType>
</assignees>
<outputConfigParams>
<name>approvalDecision</name>
<value xsi:nil="true"/>
</outputConfigParams>
<requiresAsyncProcessing>true</requiresAsyncProcessing>
<runAsUser>true</runAsUser>
<shouldLock>true</shouldLock>
<label>Approval N1</label>
</stageSteps>
<stageSteps>
<!-- Background Step for status update, runs after approval -->
<name>UpdateStatus_N1</name>
<actionName>UpdateApprovalStatusFlow</actionName>
<actionType>stepBackground</actionType>
<stepSubtype>BackgroundStep</stepSubtype>
<inputParameters>
<name>recordId</name>
<value><elementReference>recordId</elementReference></value>
</inputParameters>
<inputParameters>
<name>status</name>
<value><stringValue>PendingN2</stringValue></value>
</inputParameters>
<requiresAsyncProcessing>false</requiresAsyncProcessing>
<runAsUser>false</runAsUser>
<shouldLock>false</shouldLock>
<label>Update Status N1</label>
</stageSteps>
<connector>
<targetReference>RouteAfterN1</targetReference>
</connector>
</orchestratedStages>
```