Salesforce Apex & Solution Architecture
Write production-grade Apex code with correct governor limit awareness, proper
bulkification, sharing model compliance, and comprehensive test coverage. Design
end-to-end solutions combining Apex, Visualforce, Flows, and Quick Actions.
Before Writing Any Apex
Determine the sharing context. Use with sharing by default. Only use
without sharing when explicitly justified (e.g., guest user data access,
system-level operations). Use inherited sharing for utility classes.
Read reference/apex-fundamentals/apex-fundamentals.md.
Check governor limits. Know the transaction limits before designing:
| Limit |
Number |
| SOQL queries |
100 (200 async) |
| DML statements |
150 |
| Records retrieved (SOQL) |
50,000 |
| Records processed (DML) |
10,000 |
| CPU time |
10,000 ms (60,000 ms async) |
| Heap size |
6 MB (12 MB async) |
| Callouts |
100 |
| Single emails per transaction |
10 |
| Single emails per day (org) |
5,000 |
Plan the architecture. For anything beyond a simple trigger or class:
Read reference/solution-architecture/solution-architecture-patterns.md.
PDF Generation via Visualforce
When generating PDFs from Salesforce:
- Create a Visualforce page with
renderAs="pdf" and use applyBodyTag="false"
and applyHtmlTag="false" for full layout control
- Use inline CSS only — external stylesheets don't reliably render in PDFs
- Generate the PDF blob in Apex via
PageReference.getContentAsPDF()
getContentAsPDF() counts as a callout — no DML before it in the same transaction
- Save as
ContentVersion + ContentDocumentLink to attach to a record
Read reference/visualforce-pdf/visualforce-pdf-generation.md for complete code.
Email with PDF Attachment
When sending emails with PDF attachments:
- Use
Messaging.SingleEmailMessage with Messaging.EmailFileAttachment
- Use
setTargetObjectId() (Contact/Lead ID) for merge fields and activity logging,
NOT setToAddresses() (which doesn't log activities)
- Use org-wide email addresses for professional sender identity
- Always check
Messaging.SendEmailResult — sendEmail() doesn't throw on failure
- Limit: 10 SingleEmailMessage per transaction, 5,000 per day per org
Read reference/email-services/email-with-attachments.md for complete code.
Quick Action → Screen Flow → Apex Pattern
The standard pattern for user-initiated Apex actions:
- Quick Action (type: Flow) on the custom object launches a Screen Flow
- Screen Flow receives
recordId automatically, collects user input
- @InvocableMethod Apex class does the heavy lifting
- Flow displays success/error to the user
This pattern separates UI (Flow) from business logic (Apex) and is the recommended
approach for actions like "Send PO Email," "Generate Invoice," etc.
Read reference/quick-actions/quick-actions-and-screen-flows.md for quick action setup
and reference/apex-fundamentals/invocable-methods.md for the Apex side.
Purchase Order PDF Workflow
The complete end-to-end pattern for the PO email workflow:
Quick Action → Screen Flow (select Contact) → Invocable Apex:
1. Query Purchase Order + line items
2. Generate PDF via PageReference.getContentAsPDF()
3. Create SingleEmailMessage with PDF attachment
4. Send email to selected Contact
5. Log as Task (setSaveAsActivity=true)
6. Stamp PO: "Digital Authorization from {Authorizer_Name__c}"
Read reference/solution-architecture/purchase-order-pdf-workflow.md for complete
working code for every component.
Invocable Methods
When calling Apex from Flow:
- Use
@InvocableMethod with List<Request> input and List<Result> output
- Always use the inner class pattern (
Request / Result with @InvocableVariable)
- The method MUST handle
List<> — Flow batches multiple interviews into one call
- Invocable methods share the calling flow's governor limits (same transaction)
- Use
callout=true if the method makes HTTP callouts or calls getContentAsPDF()
Read reference/apex-fundamentals/invocable-methods.md.
Apex Testing
- Minimum 75% coverage required for production deployment, aim for 90%+
- Use
@TestSetup for shared test data creation
- Use
Test.startTest() / Test.stopTest() to reset governor limits
- Assert specific outcomes:
System.assertEquals(expected, actual, 'message')
- Test bulk scenarios (200+ records)
getContentAsPDF() returns empty blob in tests — assert no exception, not content
Messaging.sendEmail() in tests doesn't deliver — check SendEmailResult only
Code Style
When generating Apex for this developer:
- Comments:
// with one space, disembodied narrator tone
- Every method: document params and return value
- Debug statements: at key decision points
- No single-line conditionals except ternary
?. Always use if { with the body on a new line and the closing } on its own line. Never if (x) doThing();
- Sharing:
with sharing by default, document why if without sharing
- Bulkification: all triggers and invocable methods handle collections
- Variable names: meaningful in context, not
temp or data
- Valid Apex: not Java.
System.debug() not System.out.println()
Reference Docs
Read the relevant reference doc BEFORE generating code:
| Topic |
File |
| Apex Fundamentals (sharing, limits, triggers, testing, async) |
reference/apex-fundamentals/apex-fundamentals.md |
| Apex Design Patterns (trigger handler, service, selector, domain, UoW, factory, strategy, singleton, batch) |
reference/apex-fundamentals/apex-design-patterns.md |
| Invocable Methods (Flow-to-Apex bridge) |
reference/apex-fundamentals/invocable-methods.md |
| Visualforce PDF Generation |
reference/visualforce-pdf/visualforce-pdf-generation.md |
| Visualforce Controllers & Security (types, sharing, components, Lightning) |
reference/visualforce-pdf/visualforce-controllers-and-security.md |
| Email Services with Attachments |
reference/email-services/email-with-attachments.md |
| Apex Email Patterns (outbound, inbound, templates, logging, batch, testing) |
reference/email-services/apex-email-patterns.md |
| Quick Actions & Screen Flows |
reference/quick-actions/quick-actions-and-screen-flows.md |
| Solution Architecture Patterns |
reference/solution-architecture/solution-architecture-patterns.md |
| Purchase Order PDF Workflow (end-to-end) |
reference/solution-architecture/purchase-order-pdf-workflow.md |
| Flow + Apex Coexistence (order of execution, error handling) |
reference/flows-and-automation/flow-apex-coexistence.md |
| Record-Triggered Flows (before/after/async, Flow vs Apex trigger decision) |
reference/flows-and-automation/record-triggered-flows.md |
| Flow Elements & Resources (Transform, all elements, formulas, Flow vs Apex table) |
reference/flows-and-automation/flow-elements-and-resources.md |
| Screen Flows (distribution, custom LWC, Apex integration, reactive screens) |
reference/flows-and-automation/screen-flows.md |
| Scheduled, Autolaunched & Platform Event Flows (async patterns, Apex alternatives) |
reference/flows-and-automation/scheduled-and-platform-event-flows.md |
| Flow Governor Limits (shared Flow+Apex limits, Transform, structural limits) |
reference/flows-and-automation/flow-governor-limits.md |
| Flow Security, Testing & Null Handling (run context, Flow.Interview, null vs blank) |
reference/flows-and-automation/flow-security-and-testing.md |
| Visualforce + PDF Deployment (dependency ordering, testing, profiles) |
reference/deployment/visualforce-deployment.md |
| Apex Deployment & CI/CD |
reference/deployment/apex-deployment.md |
Clean Code Book Reference
Distilled chapter notes from Clean Code by Robert C. Martin (Prentice Hall, 2008).
⚠ Important: Salesforce platform requirements ALWAYS override Clean Code principles
when they conflict. DML must come before callouts. No SOQL/DML in loops. Bulkification
beats "small functions that do one thing." Every chapter doc has a Salesforce/Apex
Caveats section listing these conflicts.
| Chapter |
File |
| Ch 1: Clean Code |
reference/clean-code-book/ch01-clean-code.md |
| Ch 2: Meaningful Names |
reference/clean-code-book/ch02-meaningful-names.md |
| Ch 3: Functions |
reference/clean-code-book/ch03-functions.md |
| Ch 4: Comments |
reference/clean-code-book/ch04-comments.md |
| Ch 5: Formatting |
reference/clean-code-book/ch05-formatting.md |
| Ch 6: Objects and Data Structures |
reference/clean-code-book/ch06-objects-and-data-structures.md |
| Ch 7: Error Handling |
reference/clean-code-book/ch07-error-handling.md |
| Ch 8: Boundaries |
reference/clean-code-book/ch08-boundaries.md |
| Ch 9: Unit Tests |
reference/clean-code-book/ch09-unit-tests.md |
| Ch 10: Classes |
reference/clean-code-book/ch10-classes.md |
| Ch 11: Systems |
reference/clean-code-book/ch11-systems.md |
| Ch 12: Emergence |
reference/clean-code-book/ch12-emergence.md |
| Ch 13: Concurrency (adapted to Apex async model) |
reference/clean-code-book/ch13-concurrency.md |
| Ch 17: Smells and Heuristics |
reference/clean-code-book/ch17-smells-and-heuristics.md |
DevOps Book Reference
Distilled chapter notes from Mastering Salesforce DevOps by Andrew Davis (Apress, 2019):
| Chapter |
File |
| Ch 1: Introduction |
reference/devops-book/ch01-introduction.md |
| Ch 2: Salesforce |
reference/devops-book/ch02-salesforce.md |
| Ch 3: DevOps |
reference/devops-book/ch03-devops.md |
| Ch 4: Developing on Salesforce |
reference/devops-book/ch04-developing-on-salesforce.md |
| Ch 5: Application Architecture |
reference/devops-book/ch05-application-architecture.md |
| Ch 6: Environment Management |
reference/devops-book/ch06-environment-management.md |
| Ch 7: The Delivery Pipeline |
reference/devops-book/ch07-delivery-pipeline.md |
| Ch 8: Quality and Testing |
reference/devops-book/ch08-quality-and-testing.md |
| Ch 9: Deploying |
reference/devops-book/ch09-deploying.md |
| Ch 10: Releasing to Users |
reference/devops-book/ch10-releasing-to-users.md |
| Ch 11-13: Ops & Conclusion |
reference/devops-book/ch11-13-ops-and-conclusion.md |
Checklists
| Checklist |
File |
| (coming soon) |
|
1---2name: sf-apex-development3description: Write production-grade Salesforce Apex code, design solution architecture, and build end-to-end automation patterns. Use this skill whenever the user mentions Apex class, Apex trigger, Visualforce, PDF generation, renderAs PDF, getContentAsPDF, email attachment, SingleEmailMessage, quick action, invocable method, InvocableMethod, InvocableVariable, Apex deployment, sf project deploy, test coverage, governor limits, SOQL, DML, sharing keywords, with sharing, without sharing, trigger handler pattern, service layer, Apex testing, @isTest, Test.startTest, Queueable, Batch Apex, Schedulable, @future, ContentVersion, ContentDocumentLink, Messaging.sendEmail, EmailFileAttachment, org-wide email address, Approval.ProcessSubmitRequest, AuraHandledException, Platform Events from Apex, or any Salesforce server-side development. Also trigger when the user asks to generate a PDF, email a PDF, create a quick action that calls Apex, build a purchase order workflow, stamp a digital authorization, or design a Salesforce solut4---56# Salesforce Apex & Solution Architecture78Write production-grade Apex code with correct governor limit awareness, proper9bulkification, sharing model compliance, and comprehensive test coverage. Design10end-to-end solutions combining Apex, Visualforce, Flows, and Quick Actions.1112## Before Writing Any Apex13141. **Determine the sharing context.** Use `with sharing` by default. Only use15 `without sharing` when explicitly justified (e.g., guest user data access,16 system-level operations). Use `inherited sharing` for utility classes.17 Read `reference/apex-fundamentals/apex-fundamentals.md`.18192. **Check governor limits.** Know the transaction limits before designing:2021 | Limit | Number |22 |---|---|23 | SOQL queries | 100 (200 async) |24 | DML statements | 150 |25 | Records retrieved (SOQL) | 50,000 |26 | Records processed (DML) | 10,000 |27 | CPU time | 10,000 ms (60,000 ms async) |28 | Heap size | 6 MB (12 MB async) |29 | Callouts | 100 |30 | Single emails per transaction | 10 |31 | Single emails per day (org) | 5,000 |32333. **Plan the architecture.** For anything beyond a simple trigger or class:34 Read `reference/solution-architecture/solution-architecture-patterns.md`.3536## PDF Generation via Visualforce3738When generating PDFs from Salesforce:39401. Create a Visualforce page with `renderAs="pdf"` and use `applyBodyTag="false"`41 and `applyHtmlTag="false"` for full layout control422. Use **inline CSS only** — external stylesheets don't reliably render in PDFs433. Generate the PDF blob in Apex via `PageReference.getContentAsPDF()`444. `getContentAsPDF()` counts as a callout — no DML before it in the same transaction455. Save as `ContentVersion` + `ContentDocumentLink` to attach to a record4647Read `reference/visualforce-pdf/visualforce-pdf-generation.md` for complete code.4849## Email with PDF Attachment5051When sending emails with PDF attachments:52531. Use `Messaging.SingleEmailMessage` with `Messaging.EmailFileAttachment`542. Use `setTargetObjectId()` (Contact/Lead ID) for merge fields and activity logging,55 NOT `setToAddresses()` (which doesn't log activities)563. Use org-wide email addresses for professional sender identity574. Always check `Messaging.SendEmailResult` — `sendEmail()` doesn't throw on failure585. Limit: 10 SingleEmailMessage per transaction, 5,000 per day per org5960Read `reference/email-services/email-with-attachments.md` for complete code.6162## Quick Action → Screen Flow → Apex Pattern6364The standard pattern for user-initiated Apex actions:65661. **Quick Action** (type: Flow) on the custom object launches a Screen Flow672. **Screen Flow** receives `recordId` automatically, collects user input683. **@InvocableMethod** Apex class does the heavy lifting694. Flow displays success/error to the user7071This pattern separates UI (Flow) from business logic (Apex) and is the recommended72approach for actions like "Send PO Email," "Generate Invoice," etc.7374Read `reference/quick-actions/quick-actions-and-screen-flows.md` for quick action setup75and `reference/apex-fundamentals/invocable-methods.md` for the Apex side.7677## Purchase Order PDF Workflow7879The complete end-to-end pattern for the PO email workflow:8081```82Quick Action → Screen Flow (select Contact) → Invocable Apex:83 1. Query Purchase Order + line items84 2. Generate PDF via PageReference.getContentAsPDF()85 3. Create SingleEmailMessage with PDF attachment86 4. Send email to selected Contact87 5. Log as Task (setSaveAsActivity=true)88 6. Stamp PO: "Digital Authorization from {Authorizer_Name__c}"89```9091Read `reference/solution-architecture/purchase-order-pdf-workflow.md` for complete92working code for every component.9394## Invocable Methods9596When calling Apex from Flow:9798- Use `@InvocableMethod` with `List<Request>` input and `List<Result>` output99- Always use the inner class pattern (`Request` / `Result` with `@InvocableVariable`)100- The method MUST handle `List<>` — Flow batches multiple interviews into one call101- Invocable methods share the calling flow's governor limits (same transaction)102- Use `callout=true` if the method makes HTTP callouts or calls `getContentAsPDF()`103104Read `reference/apex-fundamentals/invocable-methods.md`.105106## Apex Testing107108- Minimum 75% coverage required for production deployment, aim for 90%+109- Use `@TestSetup` for shared test data creation110- Use `Test.startTest()` / `Test.stopTest()` to reset governor limits111- Assert specific outcomes: `System.assertEquals(expected, actual, 'message')`112- Test bulk scenarios (200+ records)113- `getContentAsPDF()` returns empty blob in tests — assert no exception, not content114- `Messaging.sendEmail()` in tests doesn't deliver — check `SendEmailResult` only115116## Code Style117118When generating Apex for this developer:119120- **Comments**: `// ` with one space, disembodied narrator tone121- **Every method**: document params and return value122- **Debug statements**: at key decision points123- **No single-line conditionals** except ternary `?`. Always use `if {` with the body on a new line and the closing `}` on its own line. Never `if (x) doThing();`124- **Sharing**: `with sharing` by default, document why if `without sharing`125- **Bulkification**: all triggers and invocable methods handle collections126- **Variable names**: meaningful in context, not `temp` or `data`127- **Valid Apex**: not Java. `System.debug()` not `System.out.println()`128129## Reference Docs130131Read the relevant reference doc BEFORE generating code:132133| Topic | File |134|---|---|135| Apex Fundamentals (sharing, limits, triggers, testing, async) | `reference/apex-fundamentals/apex-fundamentals.md` |136| Apex Design Patterns (trigger handler, service, selector, domain, UoW, factory, strategy, singleton, batch) | `reference/apex-fundamentals/apex-design-patterns.md` |137| Invocable Methods (Flow-to-Apex bridge) | `reference/apex-fundamentals/invocable-methods.md` |138| Visualforce PDF Generation | `reference/visualforce-pdf/visualforce-pdf-generation.md` |139| Visualforce Controllers & Security (types, sharing, components, Lightning) | `reference/visualforce-pdf/visualforce-controllers-and-security.md` |140| Email Services with Attachments | `reference/email-services/email-with-attachments.md` |141| Apex Email Patterns (outbound, inbound, templates, logging, batch, testing) | `reference/email-services/apex-email-patterns.md` |142| Quick Actions & Screen Flows | `reference/quick-actions/quick-actions-and-screen-flows.md` |143| Solution Architecture Patterns | `reference/solution-architecture/solution-architecture-patterns.md` |144| Purchase Order PDF Workflow (end-to-end) | `reference/solution-architecture/purchase-order-pdf-workflow.md` |145| Flow + Apex Coexistence (order of execution, error handling) | `reference/flows-and-automation/flow-apex-coexistence.md` |146| Record-Triggered Flows (before/after/async, Flow vs Apex trigger decision) | `reference/flows-and-automation/record-triggered-flows.md` |147| Flow Elements & Resources (Transform, all elements, formulas, Flow vs Apex table) | `reference/flows-and-automation/flow-elements-and-resources.md` |148| Screen Flows (distribution, custom LWC, Apex integration, reactive screens) | `reference/flows-and-automation/screen-flows.md` |149| Scheduled, Autolaunched & Platform Event Flows (async patterns, Apex alternatives) | `reference/flows-and-automation/scheduled-and-platform-event-flows.md` |150| Flow Governor Limits (shared Flow+Apex limits, Transform, structural limits) | `reference/flows-and-automation/flow-governor-limits.md` |151| Flow Security, Testing & Null Handling (run context, Flow.Interview, null vs blank) | `reference/flows-and-automation/flow-security-and-testing.md` |152| Visualforce + PDF Deployment (dependency ordering, testing, profiles) | `reference/deployment/visualforce-deployment.md` |153| Apex Deployment & CI/CD | `reference/deployment/apex-deployment.md` |154155## Clean Code Book Reference156157Distilled chapter notes from *Clean Code* by Robert C. Martin (Prentice Hall, 2008).158**⚠ Important:** Salesforce platform requirements ALWAYS override Clean Code principles159when they conflict. DML must come before callouts. No SOQL/DML in loops. Bulkification160beats "small functions that do one thing." Every chapter doc has a Salesforce/Apex161Caveats section listing these conflicts.162163| Chapter | File |164|---|---|165| Ch 1: Clean Code | `reference/clean-code-book/ch01-clean-code.md` |166| Ch 2: Meaningful Names | `reference/clean-code-book/ch02-meaningful-names.md` |167| Ch 3: Functions | `reference/clean-code-book/ch03-functions.md` |168| Ch 4: Comments | `reference/clean-code-book/ch04-comments.md` |169| Ch 5: Formatting | `reference/clean-code-book/ch05-formatting.md` |170| Ch 6: Objects and Data Structures | `reference/clean-code-book/ch06-objects-and-data-structures.md` |171| Ch 7: Error Handling | `reference/clean-code-book/ch07-error-handling.md` |172| Ch 8: Boundaries | `reference/clean-code-book/ch08-boundaries.md` |173| Ch 9: Unit Tests | `reference/clean-code-book/ch09-unit-tests.md` |174| Ch 10: Classes | `reference/clean-code-book/ch10-classes.md` |175| Ch 11: Systems | `reference/clean-code-book/ch11-systems.md` |176| Ch 12: Emergence | `reference/clean-code-book/ch12-emergence.md` |177| Ch 13: Concurrency (adapted to Apex async model) | `reference/clean-code-book/ch13-concurrency.md` |178| Ch 17: Smells and Heuristics | `reference/clean-code-book/ch17-smells-and-heuristics.md` |179180## DevOps Book Reference181182Distilled chapter notes from *Mastering Salesforce DevOps* by Andrew Davis (Apress, 2019):183184| Chapter | File |185|---|---|186| Ch 1: Introduction | `reference/devops-book/ch01-introduction.md` |187| Ch 2: Salesforce | `reference/devops-book/ch02-salesforce.md` |188| Ch 3: DevOps | `reference/devops-book/ch03-devops.md` |189| Ch 4: Developing on Salesforce | `reference/devops-book/ch04-developing-on-salesforce.md` |190| Ch 5: Application Architecture | `reference/devops-book/ch05-application-architecture.md` |191| Ch 6: Environment Management | `reference/devops-book/ch06-environment-management.md` |192| Ch 7: The Delivery Pipeline | `reference/devops-book/ch07-delivery-pipeline.md` |193| Ch 8: Quality and Testing | `reference/devops-book/ch08-quality-and-testing.md` |194| Ch 9: Deploying | `reference/devops-book/ch09-deploying.md` |195| Ch 10: Releasing to Users | `reference/devops-book/ch10-releasing-to-users.md` |196| Ch 11-13: Ops & Conclusion | `reference/devops-book/ch11-13-ops-and-conclusion.md` |197198## Checklists199200| Checklist | File |201|---|---|202| (coming soon) | |