SfSkills Domains Docs GitHub

Home / architect / solution-design-patterns

solution-design-patterns

Use when selecting the right automation layer (Flow, Apex, LWC) for a new feature, reviewing an existing design for technical debt, or troubleshooting a mismatched automation architecture.

Open the skill folder on GitHub


Use this skill when choosing the right automation layer for a Salesforce requirement, reviewing an existing design for hidden complexity or technical debt, or troubleshooting a system that mixes automation tools in conflicting or redundant ways. This skill covers the structural decision-making layer — it does not replace role-specific skills for building individual features.


Before Starting


Core Concepts

The Layered Automation Model

Salesforce provides three primary automation layers. They form a hierarchy: start at the top and only drop to a lower layer when the requirements genuinely cannot be met at the current layer.

Flow (declarative)
   ↓ escalate only when Flow cannot satisfy the requirement
Apex (programmatic logic)
   ↓ escalate only when Apex alone cannot handle the UI requirement
LWC (custom user interface)

This is not a ranking of capability — it is a ranking of maintainability and blast radius. Flow changes are deployable by trained admins and visible in a visual interface. Apex changes require code review, test classes, and deployment pipelines. LWC adds DOM rendering complexity. Each step down adds specialization and maintenance cost.

When to Use Flow

Use Flow when:

Flow governor limits to know:

When to Use Apex

Escalate to Apex when Flow cannot satisfy the requirement:

Apex trigger order of execution (simplified, per record save):

  1. System validation rules (required fields, field type enforcement)
  2. Before-save record-triggered Flows
  3. Before Apex triggers
  4. Record saved to database (in memory — not yet committed)
  5. After Apex triggers
  6. Assignment rules, auto-response rules, workflow rules (legacy — do not add new)
  7. After-save record-triggered Flows
  8. Escalation rules, entitlement rules

This ordering matters when both Flow and Apex handle the same object: a before-save Flow fires before an Apex before trigger, so Flow field writes are visible to the Apex before trigger.

When to Use LWC

Add LWC when the standard Salesforce UI cannot deliver the user experience the requirement demands:

LWC vs. Aura: Aura is legacy. Do not create new Aura components. All net-new custom UI work should use LWC. Aura components and LWC can coexist — Aura can contain LWC, but LWC cannot contain Aura.

Future-Proofing Principles

Regardless of layer chosen, apply these principles to avoid design rot:

  1. No hard-coded IDs. Record IDs, user IDs, profile IDs, and queue IDs change between sandboxes and orgs. Store configurable values in Custom Labels or Custom Metadata Types (CMDT).
  2. Use Custom Metadata Types for configuration. CMDT records are deployable, queryable without SOQL limits (cached after first access), and version-controllable. Use them for routing rules, threshold values, and feature flags.
  3. Do not use Process Builder for new automation. Process Builder is scheduled for deprecation. Migrate existing Process Builders to Flow using the Migration Tool in Setup.
  4. Do not use Workflow Rules for new automation. Workflow Rules were deprecated in Summer '23. No new Workflow Rules can be activated; all remaining ones should be migrated to Flow.
  5. One automation owner per trigger event. Avoid a pattern where a Record-Triggered Flow and an Apex trigger both react to the same after insert event on the same object doing similar things. This creates hidden coupling and makes execution order non-obvious.

Mode 1: Design a Solution from Scratch

Use this mode when a new feature or requirement needs a recommended automation approach before any build starts.

Step 1 — Classify the trigger type

TriggerRecommended starting layer
User clicks a button or completes a formScreen Flow
Record is created or updatedRecord-Triggered Flow (before or after save)
Time passes since a record eventScheduled Path in Record-Triggered Flow
Nightly or scheduled batch jobScheduled Flow or Scheduled Apex
Platform Event receivedApex trigger on the platform event (or Flow if logic is simple)
External system pushes dataApex REST endpoint (custom REST API via @RestResource)

Step 2 — Apply the escalation criteria

Ask each question in order. Stop at the first "yes":

  1. Can the logic be expressed entirely with Flow formulas and standard actions? → Use Flow.
  2. Does the logic require a same-transaction HTTP callout? → Use Apex.
  3. Does the logic require bulk-safe processing of more than ~200 records in one transaction with explicit governor limit control? → Use Apex.
  4. Does the logic require a custom UI that standard components cannot provide? → Use LWC (backed by Apex if data access is needed).
  5. Can the custom UI use Lightning Data Service for reads and standard actions for writes? → Use LWC without Apex.

Step 3 — Apply future-proofing checks


Mode 2: Review an Existing Design

Use this mode when reviewing a design document, a completed build, or an inherited org for design quality.

#

Step-by-step instructions for an AI agent or practitioner activating this skill:

  1. Gather context — confirm the org edition, relevant objects, and current configuration state
  2. Review official sources — check the references in this skill's well-architected.md before making changes
  3. Implement or advise — apply the patterns from Core Concepts and Common Patterns sections above
  4. Validate — run the skill's checker script and verify against the Review Checklist below
  5. Document — record any deviations from standard patterns and update the template if needed

Review Checklist


Mode 3: Troubleshoot an Automation Design Problem

Use this mode when an existing org has automation that behaves unexpectedly, fails intermittently, or produces governor limit errors.

Diagnostic Questions

SymptomLikely causeWhere to look
Duplicate records createdTwo automations react to the same after insert eventSetup → Flows + object's Apex triggers
Governor limit hit unexpectedlyFlow and Apex both perform SOQL in the same transactionDebug log — check LIMIT_USAGE_FOR_NS entries
Field update from Flow overwritten by ApexExecution order misunderstood; after-save Flow fires after Apex triggersReview order of execution; move one to before-save
Automation works in sandbox but not productionHard-coded IDs that differ between orgsSearch Flow conditions and Apex for literal record IDs
Process Builder action not firingProcess Builder is deprecated; active PBs may behave unpredictablyMigrate to Flow immediately
Intermittent timeout in Record-Triggered FlowExternal callout attempted from Flow after record saveFlow cannot callout after save — move to Apex Queueable with callout
Config value wrong in one orgHard-coded in Apex or Flow formulaMove to Custom Metadata Type

Design Tradeoffs Reference

DimensionFlowApexLWC
MaintainabilityHigh — visual, admin-friendlyMedium — requires developer + test classLower — requires developer, DOM knowledge
FlexibilityMedium — constrained to available actionsHigh — full Salesforce API accessHigh — full DOM, JavaScript, Wire adapters
TestabilityLimited — Flow tests via debug run; no unit test frameworkHigh — full Apex test framework with assertionsMedium — Jest for unit, manual for integration
DeployabilityMetadata API / Change SetsMetadata API / Change SetsMetadata API / Change Sets
Governor limit transparencyLow — limits are shared, less visibleHigh — explicit bulkification patternsN/A for UI layer
Mobile supportFull (Screen Flow on Mobile)N/A (server-side)Full (LWC) / Partial (Aura — legacy)

Package files