sf-flow-development
Skill15 starsChanged 7 months agoMITView on GitHub
Salesforce Flow development — flow types, patterns, bulkification, error handling, testing, subflows, Flow vs Apex. Use when building or reviewing Flows. Do NOT use for pure Apex or Platform Event architecture.
In this repository58 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- asideSkill
- checkpointSkill
- configure-sccSkill
- continuous-agent-loopSkill
- mcp-server-patternsSkill
- model-routeSkill
- prompt-optimizerSkill
- refactor-cleanSkill
- resume-sessionSkill
- save-sessionSkill
- search-firstSkill
- security-scanSkill
- sessionsSkill
- sf-2gp-security-reviewSkill
- sf-agentforce-developmentSkill
- sf-agentforce-mcp-actionsSkill
- sf-apex-async-patternsSkill
- sf-apex-best-practicesSkill
- sf-apex-constraintsSkill
- sf-apex-cursorSkill
- sf-apex-enterprise-patternsSkill
- sf-apex-testingSkill
- sf-api-designSkill
- sf-approval-processesSkill
- sf-aura-developmentSkill
- sf-build-fixSkill
- sf-cli-referenceSkill
- sf-data-modelingSkill
- sf-debuggingSkill
- sf-deployment-constraintsSkill
- sf-deploymentSkill
- sf-devops-ci-cdSkill
- sf-docs-lookupSkill
- sf-e2e-testingSkill
- sf-experience-cloudSkill
- sf-governor-limitsSkill
- sf-harness-auditSkill
- sf-helpSkill
- sf-integrationSkill
- sf-lwc-constraintsSkill
- sf-lwc-developmentSkill
- sf-lwc-testingSkill
- sf-metadata-managementSkill
- sf-platform-events-cdcSkill
- sf-quickstartSkill
- sf-security-constraintsSkill
- sf-securitySkill
- sf-soql-constraintsSkill
- sf-soql-optimizationSkill
- sf-tdd-workflowSkill
- sf-testing-constraintsSkill
- sf-trigger-constraintsSkill
- sf-trigger-frameworksSkill
- sf-visualforce-developmentSkill
- strategic-compactSkill
- update-docsSkill
- update-platform-docsSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 139
Every element that can fail should have a fault connector.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Salesforce Flow Development
Procedures for building, testing, and maintaining Salesforce Flows. Flow type details, governor limits, bulkification rules, and the Flow vs Apex decision matrix live in the reference file.
@../_reference/FLOW_PATTERNS.md
When to Use
- Building or debugging Salesforce Flows (record-triggered, screen, scheduled, autolaunched, orchestration)
- Deciding between Flow and Apex for automation
- Configuring fault paths, bulkification, or governor-safe flow patterns
- Implementing subflows, versioning, or modular flow design
- Migrating from Process Builder to Record-Triggered Flows
Before Save: Field Updates (Recommended Pattern)
Flow: ACC_SetAccountPriority (Before Save, Account, before insert OR before update)
Entry Condition: {!$Record.AnnualRevenue} >= 1000000
Steps:
1. Assignment: {!$Record.Priority__c} = "High"
2. Assignment: {!$Record.Tier__c} = "Enterprise"
Notes:
- No Get Records, Update Records, or Create Records elements allowed
- No DML of any kind
- Very fast — runs in memory before DB writeAfter Save: Related Record Creation
Flow: OPP_CreateNegotiationTask (After Save, Opportunity, after update)
Entry Condition: {!$Record.StageName} = "Negotiation"
AND {!$Record.StageName} <> {!$Record__Prior.StageName}
Steps:
1. Get Records: User WHERE Id = {!$Record.OwnerId}
2. Create Records: Task (
Subject = "Review negotiation checklist"
WhatId = {!$Record.Id}
OwnerId = {!$Record.OwnerId}
ActivityDate = TODAY() + 3
Priority = "High"
)Before Save vs After Save Decision
Need to update the SAME record's fields?
-> Before Save (no DML counted, faster)
Note: Before Save flows cannot use Get Records or DML elements,
but CAN access parent fields via cross-object formula references
(e.g., {!$Record.Account.Name}).
Need to create/update OTHER records?
-> After Save (can do DML on other objects)
Need to send emails or call external services?
-> After Save (outbound actions need committed record)Bulkification Patterns
DML Outside the Loop (Critical)
BAD:
Loop: For each Contact in {!Contacts}
|
+-> Update Records: Contact <- DML inside loop = 1 DML per record
GOOD:
Loop: For each Contact in {!Contacts}
|
+-> Assignment: Add to contactsToUpdate collection
Update Records: {!contactsToUpdate} <- Single DML for entire collectionSOQL Outside the Loop
BAD:
Loop: For each Opportunity in {!Opportunities}
|
+-> Get Records: Account WHERE Id = {!loopVar.AccountId} <- SOQL per record
GOOD:
Get Records: Account WHERE Id IN {!opportunityAccountIds} <- single query
Loop: For each Opportunity in {!Opportunities}
|
+-> (Use data from pre-fetched collection, no SOQL)
Heap warning: If pre-fetch returns 10K+ records, the collection may
exceed the heap size limit (see @../_reference/GOVERNOR_LIMITS.md). Filter aggressively, or move to Batch Apex.Subflows: Modular Design
Parent Flow: SCR_CustomerOnboarding (Screen Flow)
|
+-- Subflow: VAL_ValidateAddress (Autolaunched)
| Input: {!streetAddress}, {!city}, {!state}
| Output: {!isValidAddress}, {!normalizedAddress}
|
+-- Subflow: INT_CreateCRMAccount (Autolaunched)
| Input: {!accountData}
| Output: {!newAccountId}
|
+-- Subflow: NOT_SendWelcomeEmail (Autolaunched)
Input: {!accountId}, {!contactEmail}Variables passed between parent and subflow must be marked as available for input/output in the subflow definition.
Error Handling: Fault Connectors
Every element that can fail should have a fault connector.
[Update Records: Update Account]
|
+-(SUCCESS)-> [Next Step]
|
+-(FAULT)-> [Assignment: errorMessage =
"Failed: " + {!$Flow.FaultMessage}]
|
+-> [Screen: Display Error to User]
OR
+-> [Create Records: Error_Log__c]
OR
+-> [Custom Notification: Notify Admin]Get Records Best Practices
Element: Get Records
Object: Contact
Filter: AccountId = {!$Record.Id} AND IsActive__c = true
Store All Records: No (when you need just one) / Yes (for a collection)
Tips:
- Add filter conditions to reduce records returned
- Select only the fields you need
- Use "Only the first record" when you need a single result
- Filter on indexed fields when possible (Id, OwnerId, ExternalId__c)Custom Labels and Custom Metadata in Flows
Custom Labels
Formula Resource:
Name: FormattedMessage
Data Type: Text
Value: {!$Label.Welcome_Message} & " " & {!ContactRecord.FirstName}Custom Metadata Types
Get Records:
Object: Service_Config__mdt
Filter: DeveloperName = "Production"
Fields: Endpoint_URL__c, Timeout_Ms__cTesting Flows
Apex Test Coverage for Record-Triggered Flows
@IsTest
public class OppNegotiationFlowTest {
@TestSetup
static void setup() {
Account acc = TestDataFactory.createAccount('Test Account');
insert acc;
}
@IsTest
static void testNegotiationTask_stageChanged_createsTask() {
Account acc = [SELECT Id FROM Account LIMIT 1];
Opportunity opp = new Opportunity(
Name = 'Test Opp',
AccountId = acc.Id,
StageName = 'Prospecting',
CloseDate = Date.today().addDays(30),
Amount = 50000
);
insert opp;
Test.startTest();
opp.StageName = 'Negotiation';
update opp;
Test.stopTest();
List<Task> tasks = [SELECT Subject, Priority
FROM Task WHERE WhatId = :opp.Id];
System.assertEquals(1, tasks.size());
System.assertEquals('Review negotiation checklist', tasks[0].Subject);
}
@IsTest
static void testNegotiationTask_bulk_createsTasksForAll() {
Account acc = [SELECT Id FROM Account LIMIT 1];
List<Opportunity> opps = new List<Opportunity>();
for (Integer i = 0; i < 200; i++) {
opps.add(new Opportunity(
Name = 'Bulk Opp ' + i,
AccountId = acc.Id,
StageName = 'Prospecting',
CloseDate = Date.today().addDays(30),
Amount = 1000 * i
));
}
insert opps;
Test.startTest();
for (Opportunity opp : opps) { opp.StageName = 'Negotiation'; }
update opps;
Test.stopTest();
Integer taskCount = [SELECT COUNT() FROM Task WHERE WhatId IN :opps];
System.assertEquals(200, taskCount);
}
}New Screen Flow Components (Spring '26)
Five native Screen Flow components that eliminate the need for custom LWC in common patterns:
| Component | Best For |
| Kanban Board | Stage/status reassignment wizards, visual prioritization |
| Message | Confirmation prompts, warnings before destructive steps |
| File Preview | Document review steps in approval flows |
| Integrated Approval | Wizard-based approval flows where reps submit and track |
| Editable Data Table | Mass-edit child records within a guided wizard |
Record-Triggered Flows on Files (Spring '26)
Record-Triggered Flows now support ContentVersion as a triggering object.
Object: ContentVersion
Trigger: A record is created or updated
Entry Conditions:
- {!$Record.FileExtension} = 'pdf'
- {!$Record.Title} Does NOT Contain 'DRAFT'
Use cases:
- Auto-tag documents based on filename patterns
- Notify a team when a contract document is uploaded
- Create audit log when a sensitive file type is uploadedOrchestration Flow Design
Orchestration Flows manage long-running, multi-step processes spanning hours or days.
Orchestration Flow: Employee_Onboarding
+-- Stage 1: "System Setup"
| +-- Background Step: Create user account (Autolaunched Flow)
| +-- Background Step: Provision email (Autolaunched Flow)
+-- Stage 2: "HR Review"
| +-- Interactive Step: Complete onboarding form (Screen Flow -> HR Manager)
+-- Stage 3: "Equipment & Access"
| +-- Interactive Step: Order equipment (Screen Flow -> IT Team queue)
| +-- Background Step: Grant system permissions (Autolaunched Flow)
+-- Stage 4: "Orientation"
+-- Interactive Step: Schedule orientation (Screen Flow -> Employee)Key Design Principles
- Stages execute sequentially -- Stage 2 waits for all Stage 1 steps
- Steps within a stage can run in parallel
- Interactive steps pause the orchestration until the assigned user completes the Screen Flow
- Background steps run automatically using Autolaunched Flows
- Define fault paths on background steps to prevent stalled orchestrations
Flow Versioning and Activation
Each Flow has:
- Multiple versions (v1, v2, v3...)
- Only ONE active version at a time
- Inactive versions can be tested without activating
Deployment:
- Deploying creates a new version
- Set status: Active in Flow metadata to auto-activate:<status>Active</status>sf project deploy start \
--metadata "Flow:OPP_CreateNegotiationTask" \
--target-org myOrgProcess Builder Migration
1. IDENTIFY — List all active Process Builders
sf data query -q "SELECT Id, MasterLabel, ProcessType FROM Flow
WHERE ProcessType = 'Workflow' AND Status = 'Active'" --json
2. ANALYZE — Document trigger object, criteria, and actions
3. CREATE — Build equivalent Record-Triggered Flow:
- Before Save Flow for field updates
- After Save Flow for create records, email alerts
4. TEST — Deploy to sandbox, test with bulk data (200+ records)
5. DEACTIVATE — Turn off Process Builder, monitor 1-2 weeks
6. CLEANUP — Delete via destructiveChanges.xmlRelated
- Agent:
sf-flow-agent-- for interactive, in-depth guidance - Constraints: sf-apex-constraints (for Apex-invoked flows)
- Reference: @../_reference/FLOW_PATTERNS.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

