Salesforce Developer Core Workflow 1. Analyze requirements - Understand business needs, data model, governor limits, scalability 2. Design solution - Choose declarative vs programmatic, plan bulkification, design integrations 3. Implement - Write Apex classes, LWC components, SOQL queries with best practices 4. Validate governor limits - Verify SOQL/DML counts, heap size, and CPU time stay within platform limits before proceeding 5. Test thoroughly - Write test classes with 90%+ coverage, test bulk scenarios (200-record batches) 6. Deploy - Use Salesforce DX, scratch orgs, CI/CD for metadata…

+ totalRevenue);\n}\n```\n\n### GROUP BY with ROLLUP and CUBE\n\n```apex\n// GROUP BY ROLLUP - hierarchical subtotals\nList\u003cAggregateResult> results = [\n SELECT Industry, Type,\n COUNT(Id) cnt,\n SUM(AnnualRevenue) revenue\n FROM Account\n GROUP BY ROLLUP(Industry, Type)\n];\n\n// GROUP BY CUBE - all combinations\nList\u003cAggregateResult> results = [\n SELECT Industry, Rating,\n COUNT(Id) cnt\n FROM Account\n GROUP BY CUBE(Industry, Rating)\n];\n```\n\n### COUNT_DISTINCT\n\n```apex\n// Count unique values\nList\u003cAggregateResult> results = [\n SELECT COUNT_DISTINCT(Industry) uniqueIndustries,\n COUNT_DISTINCT(OwnerId) uniqueOwners\n FROM Account\n];\n```\n\n---\n\n## Dynamic SOQL\n\n### Building Queries Dynamically\n\n```apex\npublic class DynamicQueryBuilder {\n\n public static List\u003cSObject> search(\n String objectName,\n List\u003cString> fields,\n Map\u003cString, Object> filters,\n String orderBy,\n Integer limitCount\n ) {\n // Build SELECT clause\n String query = 'SELECT ' + String.join(fields, ', ');\n query += ' FROM ' + String.escapeSingleQuotes(objectName);\n\n // Build WHERE clause\n List\u003cString> conditions = new List\u003cString>();\n for (String field : filters.keySet()) {\n Object value = filters.get(field);\n\n if (value instanceof String) {\n conditions.add(field + ' = \\'' + String.escapeSingleQuotes((String)value) + '\\'');\n } else if (value instanceof Set\u003cId>) {\n conditions.add(field + ' IN :filterIds');\n } else if (value instanceof Date) {\n conditions.add(field + ' = ' + ((Date)value).format());\n } else if (value != null) {\n conditions.add(field + ' = ' + value);\n }\n }\n\n if (!conditions.isEmpty()) {\n query += ' WHERE ' + String.join(conditions, ' AND ');\n }\n\n // Add ORDER BY\n if (String.isNotBlank(orderBy)) {\n query += ' ORDER BY ' + String.escapeSingleQuotes(orderBy);\n }\n\n // Add LIMIT\n if (limitCount != null && limitCount > 0) {\n query += ' LIMIT ' + limitCount;\n }\n\n System.debug('Dynamic Query: ' + query);\n\n // Execute query\n return Database.query(query);\n }\n}\n\n// Usage\nMap\u003cString, Object> filters = new Map\u003cString, Object>{\n 'Industry' => 'Technology',\n 'AnnualRevenue' => 1000000\n};\n\nList\u003cAccount> accounts = (List\u003cAccount>)DynamicQueryBuilder.search(\n 'Account',\n new List\u003cString>{'Id', 'Name', 'Industry'},\n filters,\n 'Name ASC',\n 100\n);\n```\n\n### Security with Dynamic SOQL\n\n```apex\npublic with sharing class SecureDynamicQuery {\n\n public static List\u003cSObject> queryWithFLS(\n String objectName,\n List\u003cString> fields,\n String whereClause\n ) {\n // Check object accessibility\n Schema.DescribeSObjectResult objDescribe =\n Schema.getGlobalDescribe().get(objectName).getDescribe();\n\n if (!objDescribe.isAccessible()) {\n throw new SecurityException('No access to object: ' + objectName);\n }\n\n // Filter to accessible fields only\n Map\u003cString, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();\n List\u003cString> accessibleFields = new List\u003cString>();\n\n for (String field : fields) {\n Schema.SObjectField fieldToken = fieldMap.get(field);\n if (fieldToken != null && fieldToken.getDescribe().isAccessible()) {\n accessibleFields.add(field);\n }\n }\n\n if (accessibleFields.isEmpty()) {\n throw new SecurityException('No accessible fields');\n }\n\n String query = 'SELECT ' + String.join(accessibleFields, ', ');\n query += ' FROM ' + String.escapeSingleQuotes(objectName);\n\n if (String.isNotBlank(whereClause)) {\n query += ' WHERE ' + whereClause;\n }\n\n // WITH SECURITY_ENFORCED ensures FLS/CRUD\n query += ' WITH SECURITY_ENFORCED';\n\n return Database.query(query);\n }\n}\n```\n\n---\n\n## SOSL (Salesforce Object Search Language)\n\n### Basic SOSL Syntax\n\n```apex\n// Search across multiple objects\nList\u003cList\u003cSObject>> searchResults = [\n FIND 'Acme*' IN ALL FIELDS\n RETURNING\n Account(Id, Name, Industry WHERE Industry = 'Technology'),\n Contact(Id, FirstName, LastName, Email),\n Opportunity(Id, Name, Amount)\n LIMIT 100\n];\n\nList\u003cAccount> accounts = (List\u003cAccount>)searchResults[0];\nList\u003cContact> contacts = (List\u003cContact>)searchResults[1];\nList\u003cOpportunity> opportunities = (List\u003cOpportunity>)searchResults[2];\n```\n\n### Search Scope Options\n\n```apex\n// ALL FIELDS - Search all searchable text fields\nFIND 'Acme' IN ALL FIELDS\n\n// NAME FIELDS - Search only name fields\nFIND 'Acme' IN NAME FIELDS\n\n// EMAIL FIELDS - Search only email fields\nFIND '[email protected]' IN EMAIL FIELDS\n\n// PHONE FIELDS - Search only phone fields\nFIND '555-1234' IN PHONE FIELDS\n\n// SIDEBAR FIELDS - Search fields displayed in sidebar\nFIND 'Acme' IN SIDEBAR FIELDS\n```\n\n### Search Term Syntax\n\n```apex\n// Wildcard search (trailing only for SOSL)\nFIND 'Acme*'\n\n// Phrase search (exact match)\nFIND '\"Acme Corporation\"'\n\n// Boolean operators\nFIND 'Acme AND Technology'\nFIND 'Acme OR Technology'\nFIND 'Acme AND NOT Closed'\n\n// Grouping\nFIND '(Acme OR Globex) AND Technology'\n```\n\n### Dynamic SOSL\n\n```apex\npublic class GlobalSearch {\n\n public static Map\u003cString, List\u003cSObject>> search(\n String searchTerm,\n List\u003cString> objectNames\n ) {\n if (String.isBlank(searchTerm) || searchTerm.length() \u003c 2) {\n return new Map\u003cString, List\u003cSObject>>();\n }\n\n // Sanitize search term\n String sanitized = String.escapeSingleQuotes(searchTerm);\n\n // Build RETURNING clause\n List\u003cString> returningClauses = new List\u003cString>();\n for (String objName : objectNames) {\n returningClauses.add(objName + '(Id, Name LIMIT 20)');\n }\n\n String sosl = 'FIND \\'' + sanitized + '*\\' IN ALL FIELDS RETURNING ' +\n String.join(returningClauses, ', ') +\n ' LIMIT 100';\n\n List\u003cList\u003cSObject>> results = Search.query(sosl);\n\n // Map results to object names\n Map\u003cString, List\u003cSObject>> resultMap = new Map\u003cString, List\u003cSObject>>();\n for (Integer i = 0; i \u003c objectNames.size(); i++) {\n resultMap.put(objectNames[i], results[i]);\n }\n\n return resultMap;\n }\n}\n\n// Usage\nMap\u003cString, List\u003cSObject>> results = GlobalSearch.search(\n 'Acme',\n new List\u003cString>{'Account', 'Contact', 'Opportunity'}\n);\n```\n\n---\n\n## Performance Patterns\n\n### Avoiding Common Anti-Patterns\n\n```apex\n// ANTI-PATTERN 1: SOQL in loops\n// BAD\nfor (Contact c : contacts) {\n Account acc = [SELECT Id FROM Account WHERE Id = :c.AccountId];\n}\n\n// GOOD\nMap\u003cId, Account> accounts = new Map\u003cId, Account>([\n SELECT Id FROM Account WHERE Id IN :contactAccountIds\n]);\n\n// ANTI-PATTERN 2: Querying all fields\n// BAD\nList\u003cAccount> accounts = [SELECT FIELDS(ALL) FROM Account LIMIT 100];\n\n// GOOD - Query only needed fields\nList\u003cAccount> accounts = [SELECT Id, Name, Industry FROM Account LIMIT 100];\n\n// ANTI-PATTERN 3: Not using bind variables\n// BAD - Risk of SOQL injection\nString query = 'SELECT Id FROM Account WHERE Name = \\'' + userInput + '\\'';\n\n// GOOD - Use bind variables\nString accountName = userInput;\nList\u003cAccount> accounts = [SELECT Id FROM Account WHERE Name = :accountName];\n\n// ANTI-PATTERN 4: Querying without limits on unbounded queries\n// BAD\nList\u003cAccount> allAccounts = [SELECT Id FROM Account];\n\n// GOOD\nList\u003cAccount> accounts = [SELECT Id FROM Account LIMIT 10000];\n```\n\n### Large Data Volume Strategies\n\n```apex\npublic class LargeDataVolumeQuery {\n\n // Strategy 1: Query with date ranges\n public static List\u003cAccount> getRecentAccounts() {\n return [\n SELECT Id, Name\n FROM Account\n WHERE CreatedDate = LAST_N_DAYS:30\n ORDER BY CreatedDate DESC\n LIMIT 1000\n ];\n }\n\n // Strategy 2: Use QueryLocator for batch processing\n public Database.QueryLocator getQueryLocator() {\n return Database.getQueryLocator([\n SELECT Id, Name, Industry\n FROM Account\n WHERE Industry = 'Technology'\n ]);\n }\n\n // Strategy 3: Skinny tables for specific fields\n // (Must be enabled by Salesforce Support for the object)\n\n // Strategy 4: Custom indexes on frequently queried fields\n // (Request via Salesforce Support)\n\n // Strategy 5: Archive old records\n // Use Big Objects for historical data\n}\n```\n\n### Query Locator vs List\n\n```apex\n// Use QueryLocator for Batch Apex (up to 50 million records)\npublic Database.QueryLocator start(Database.BatchableContext bc) {\n return Database.getQueryLocator([\n SELECT Id, Name FROM Account\n ]);\n}\n\n// Use List for smaller datasets (up to 50,000 records)\npublic List\u003cAccount> start(Database.BatchableContext bc) {\n return [SELECT Id, Name FROM Account LIMIT 50000];\n}\n```\n\n---\n\n## Date Functions and Literals\n\n### Date Literals\n\n```apex\n// Relative date literals\nWHERE CreatedDate = TODAY\nWHERE CreatedDate = YESTERDAY\nWHERE CreatedDate = TOMORROW\nWHERE CreatedDate = LAST_WEEK\nWHERE CreatedDate = THIS_WEEK\nWHERE CreatedDate = NEXT_WEEK\nWHERE CreatedDate = LAST_MONTH\nWHERE CreatedDate = THIS_MONTH\nWHERE CreatedDate = NEXT_MONTH\nWHERE CreatedDate = LAST_90_DAYS\nWHERE CreatedDate = NEXT_90_DAYS\nWHERE CreatedDate = LAST_N_DAYS:30\nWHERE CreatedDate = NEXT_N_DAYS:30\nWHERE CreatedDate = THIS_QUARTER\nWHERE CreatedDate = LAST_QUARTER\nWHERE CreatedDate = NEXT_QUARTER\nWHERE CreatedDate = THIS_YEAR\nWHERE CreatedDate = LAST_YEAR\nWHERE CreatedDate = NEXT_YEAR\nWHERE CreatedDate = THIS_FISCAL_QUARTER\nWHERE CreatedDate = THIS_FISCAL_YEAR\n```\n\n### Date Functions\n\n```apex\n// Calendar functions in GROUP BY\nSELECT CALENDAR_MONTH(CreatedDate) month, COUNT(Id) cnt\nFROM Account\nGROUP BY CALENDAR_MONTH(CreatedDate)\n\nSELECT CALENDAR_YEAR(CloseDate) year, SUM(Amount) total\nFROM Opportunity\nWHERE IsWon = true\nGROUP BY CALENDAR_YEAR(CloseDate)\n\n// Fiscal functions\nSELECT FISCAL_QUARTER(CloseDate) quarter, SUM(Amount)\nFROM Opportunity\nGROUP BY FISCAL_QUARTER(CloseDate)\n\n// Week functions\nSELECT WEEK_IN_MONTH(CreatedDate) week, COUNT(Id)\nFROM Lead\nGROUP BY WEEK_IN_MONTH(CreatedDate)\n\n// Hour functions (for DateTime fields)\nSELECT HOUR_IN_DAY(CreatedDate) hour, COUNT(Id)\nFROM Case\nGROUP BY HOUR_IN_DAY(CreatedDate)\n```\n\n---\n\n## When to Use\n\n- **SOQL**: Retrieving specific records with known criteria\n- **SOSL**: Full-text search across multiple objects\n- **Aggregate queries**: Reports, dashboards, summary calculations\n- **Dynamic SOQL**: User-configurable queries, generic utilities\n- **Relationship queries**: Parent-child data in single query\n\n## When NOT to Use\n\n- **SOQL in loops**: Always bulkify outside loops\n- **SELECT ***: Query only needed fields\n- **Non-selective queries**: Add indexed field filters\n- **SOSL for exact matches**: Use SOQL for precise criteria\n- **Aggregate for single records**: Use standard queries for individual records\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":17018,"content_sha256":"3f357e9a104cd4927ad7cf28d49bdd381fbdbacf15fde6772f671784bf0a85a2"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Salesforce Developer","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Workflow","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyze requirements","type":"text","marks":[{"type":"strong"}]},{"text":" - Understand business needs, data model, governor limits, scalability","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Design solution","type":"text","marks":[{"type":"strong"}]},{"text":" - Choose declarative vs programmatic, plan bulkification, design integrations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement","type":"text","marks":[{"type":"strong"}]},{"text":" - Write Apex classes, LWC components, SOQL queries with best practices","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validate governor limits","type":"text","marks":[{"type":"strong"}]},{"text":" - Verify SOQL/DML counts, heap size, and CPU time stay within platform limits before proceeding","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test thoroughly","type":"text","marks":[{"type":"strong"}]},{"text":" - Write test classes with 90%+ coverage, test bulk scenarios (200-record batches)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deploy","type":"text","marks":[{"type":"strong"}]},{"text":" - Use Salesforce DX, scratch orgs, CI/CD for metadata deployment","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Guide","type":"text"}]},{"type":"paragraph","content":[{"text":"Load detailed guidance based on context:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Topic","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reference","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Load When","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Apex Development","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/apex-development.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Classes, triggers, async patterns, batch processing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Lightning Web Components","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/lightning-web-components.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"LWC framework, component design, events, wire service","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SOQL/SOSL","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/soql-sosl.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Query optimization, relationships, governor limits","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Integration Patterns","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/integration-patterns.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"REST/SOAP APIs, platform events, external services","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Deployment & DevOps","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"references/deployment-devops.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Salesforce DX, CI/CD, scratch orgs, metadata API","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Constraints","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"MUST DO","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bulkify Apex code — collect IDs/records before loops, query/DML outside loops","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Write test classes with minimum 90% code coverage, including bulk scenarios","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use selective SOQL queries with indexed fields; leverage relationship queries","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use appropriate async processing (batch, queueable, future) for long-running work","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement proper error handling and logging; use ","type":"text"},{"text":"Database.update(scope, false)","type":"text","marks":[{"type":"code_inline"}]},{"text":" for partial success","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use Salesforce DX for source-driven development and metadata deployment","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"MUST NOT DO","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Execute SOQL/DML inside loops (governor limit violation — see bulkified trigger pattern below)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hard-code IDs or credentials in code","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Create recursive triggers without safeguards","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Skip field-level security and sharing rules checks","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use deprecated Salesforce APIs or components","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Code Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Bulkified Trigger (Correct Pattern)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"apex"},"content":[{"text":"// CORRECT: collect IDs, query once outside the loop\ntrigger AccountTrigger on Account (before insert, before update) {\n AccountTriggerHandler.handleBeforeInsert(Trigger.new);\n}\n\npublic class AccountTriggerHandler {\n public static void handleBeforeInsert(List\u003cAccount> newAccounts) {\n Set\u003cId> parentIds = new Set\u003cId>();\n for (Account acc : newAccounts) {\n if (acc.ParentId != null) parentIds.add(acc.ParentId);\n }\n Map\u003cId, Account> parentMap = new Map\u003cId, Account>(\n [SELECT Id, Name FROM Account WHERE Id IN :parentIds]\n );\n for (Account acc : newAccounts) {\n if (acc.ParentId != null && parentMap.containsKey(acc.ParentId)) {\n acc.Description = 'Child of: ' + parentMap.get(acc.ParentId).Name;\n }\n }\n }\n}","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"apex"},"content":[{"text":"// INCORRECT: SOQL inside loop — governor limit violation\ntrigger AccountTrigger on Account (before insert) {\n for (Account acc : Trigger.new) {\n Account parent = [SELECT Id, Name FROM Account WHERE Id = :acc.ParentId]; // BAD\n acc.Description = 'Child of: ' + parent.Name;\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Batch Apex","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"apex"},"content":[{"text":"public class ContactBatchUpdate implements Database.Batchable\u003cSObject> {\n public Database.QueryLocator start(Database.BatchableContext bc) {\n return Database.getQueryLocator([SELECT Id, Email FROM Contact WHERE Email = null]);\n }\n public void execute(Database.BatchableContext bc, List\u003cContact> scope) {\n for (Contact c : scope) {\n c.Email = '[email protected]';\n }\n Database.update(scope, false); // partial success allowed\n }\n public void finish(Database.BatchableContext bc) {\n // Send notification or chain next batch\n }\n}\n// Execute: Database.executeBatch(new ContactBatchUpdate(), 200);","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Test Class","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"apex"},"content":[{"text":"@IsTest\nprivate class AccountTriggerHandlerTest {\n @TestSetup\n static void makeData() {\n Account parent = new Account(Name = 'Parent Co');\n insert parent;\n Account child = new Account(Name = 'Child Co', ParentId = parent.Id);\n insert child;\n }\n\n @IsTest\n static void testBulkInsert() {\n Account parent = [SELECT Id FROM Account WHERE Name = 'Parent Co' LIMIT 1];\n List\u003cAccount> children = new List\u003cAccount>();\n for (Integer i = 0; i \u003c 200; i++) {\n children.add(new Account(Name = 'Child ' + i, ParentId = parent.Id));\n }\n Test.startTest();\n insert children;\n Test.stopTest();\n\n List\u003cAccount> updated = [SELECT Description FROM Account WHERE ParentId = :parent.Id];\n System.assert(!updated.isEmpty(), 'Children should have descriptions set');\n System.assert(updated[0].Description.startsWith('Child of:'), 'Description format mismatch');\n }\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"SOQL Best Practices","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"apex"},"content":[{"text":"// Selective query — use indexed fields in WHERE clause\nList\u003cOpportunity> opps = [\n SELECT Id, Name, Amount, StageName\n FROM Opportunity\n WHERE AccountId IN :accountIds // indexed field\n AND CloseDate >= :Date.today() // indexed field\n ORDER BY CloseDate ASC\n LIMIT 200\n];\n\n// Relationship query to avoid extra round-trips\nList\u003cAccount> accounts = [\n SELECT Id, Name,\n (SELECT Id, LastName, Email FROM Contacts WHERE Email != null)\n FROM Account\n WHERE Id IN :accountIds\n];","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Lightning Web Component (Counter Example)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"html"},"content":[{"text":"\u003c!-- counterComponent.html -->\n\u003ctemplate>\n \u003clightning-card title=\"Counter\">\n \u003cdiv class=\"slds-p-around_medium\">\n \u003cp>Count: {count}\u003c/p>\n \u003clightning-button label=\"Increment\" onclick={handleIncrement}>\u003c/lightning-button>\n \u003c/div>\n \u003c/lightning-card>\n\u003c/template>","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"javascript"},"content":[{"text":"// counterComponent.js\nimport { LightningElement, track } from 'lwc';\nexport default class CounterComponent extends LightningElement {\n @track count = 0;\n handleIncrement() {\n this.count += 1;\n }\n}","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"xml"},"content":[{"text":"\u003c!-- counterComponent.js-meta.xml -->\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003cLightningComponentBundle xmlns=\"http://soap.sforce.com/2006/04/metadata\">\n \u003capiVersion>59.0\u003c/apiVersion>\n \u003cisExposed>true\u003c/isExposed>\n \u003ctargets>\n \u003ctarget>lightning__AppPage\u003c/target>\n \u003ctarget>lightning__RecordPage\u003c/target>\n \u003c/targets>\n\u003c/LightningComponentBundle>","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Documentation","type":"text","marks":[{"type":"link","attrs":{"href":"https://jeffallan.github.io/claude-skills/skills/platform/salesforce-developer/","title":null}}]}]}]},"metadata":{"date":"2026-06-05","name":"salesforce-developer","author":"@skillopedia","source":{"stars":9549,"repo_name":"claude-skills","origin_url":"https://github.com/jeffallan/claude-skills/blob/HEAD/skills/salesforce-developer/SKILL.md","repo_owner":"jeffallan","body_sha256":"29466756484aadaeea274bb11ce68b0fb889fe8acd845e95a5b5a9a4127d1cba","cluster_key":"05ccfe077a4abf102dccc11ff2ff8178348850418c5125ca8bcb0f340d3c6bc6","clean_bundle":{"format":"clean-skill-bundle-v1","source":"jeffallan/claude-skills/skills/salesforce-developer/SKILL.md","attachments":[{"id":"a9892cf2-3d5a-5969-9376-28274fec87b6","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/a9892cf2-3d5a-5969-9376-28274fec87b6/attachment.md","path":"references/apex-development.md","size":23559,"sha256":"b948446a06ef78f28314987e921cb24b55c320f0603f236910343ef2494f4efe","contentType":"text/markdown; charset=utf-8"},{"id":"e8fb4fe1-d99e-529b-b1ed-f7cfbf8ae092","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e8fb4fe1-d99e-529b-b1ed-f7cfbf8ae092/attachment.md","path":"references/deployment-devops.md","size":21321,"sha256":"eb26d4ca83b353999bc904805eeeed8080376ed926223a291faba8ea70032a86","contentType":"text/markdown; charset=utf-8"},{"id":"f188acd8-1576-50cf-9772-c85c32b92298","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f188acd8-1576-50cf-9772-c85c32b92298/attachment.md","path":"references/integration-patterns.md","size":27872,"sha256":"7c4a711b23a7a3eb2c7305ef7d9d13293d19106dd85d583547ed4f511ef67e49","contentType":"text/markdown; charset=utf-8"},{"id":"6664c857-7d3d-549d-af61-367dccfda4f9","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6664c857-7d3d-549d-af61-367dccfda4f9/attachment.md","path":"references/lightning-web-components.md","size":24090,"sha256":"180edf8dd336657c05cecf6df156a4dca1382439f1f340c8d597a2e81d1a6f37","contentType":"text/markdown; charset=utf-8"},{"id":"db9e9357-bf17-5ede-8415-dd051e23f9dd","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/db9e9357-bf17-5ede-8415-dd051e23f9dd/attachment.md","path":"references/soql-sosl.md","size":17018,"sha256":"3f357e9a104cd4927ad7cf28d49bdd381fbdbacf15fde6772f671784bf0a85a2","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"ab4fba82515ee7204840aa46a332e7f7a24ba5e2eddbe44cd03c62753d385fdb","attachment_count":5,"text_attachments":5,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/salesforce-developer/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"devops-infrastructure","category_label":"DevOps"},"exact_dupes_collapsed_into_this":0},"license":"MIT","version":"v1","category":"devops-infrastructure","metadata":{"role":"expert","scope":"implementation","author":"https://github.com/Jeffallan","domain":"platform","version":"1.1.0","triggers":"Salesforce, Apex, Lightning Web Components, LWC, SOQL, SOSL, Visualforce, Salesforce DX, governor limits, triggers, platform events, CRM integration, Sales Cloud, Service Cloud","output-format":"code","related-skills":"api-designer, java-architect, cloud-architect, devops-engineer"},"import_tag":"clean-skills-v1","description":"Writes and debugs Apex code, builds Lightning Web Components, optimizes SOQL queries, implements triggers, batch jobs, platform events, and integrations on the Salesforce platform. Use when developing Salesforce applications, customizing CRM workflows, managing governor limits, bulk processing, or setting up Salesforce DX and CI/CD pipelines."}},"renderedAt":1782979532412}

Salesforce Developer Core Workflow 1. Analyze requirements - Understand business needs, data model, governor limits, scalability 2. Design solution - Choose declarative vs programmatic, plan bulkification, design integrations 3. Implement - Write Apex classes, LWC components, SOQL queries with best practices 4. Validate governor limits - Verify SOQL/DML counts, heap size, and CPU time stay within platform limits before proceeding 5. Test thoroughly - Write test classes with 90%+ coverage, test bulk scenarios (200-record batches) 6. Deploy - Use Salesforce DX, scratch orgs, CI/CD for metadata…