Apex Controllers
The Keelstone Samples package includes three Apex controllers that back the sample LWC components. You can use these directly, extend them, or use them as reference implementations for your own controllers.
ExcelTemplateController
Manages reading and writing Excel template files in Salesforce Files (ContentDocument).
Used by: excelTemplate LWC
getTemplate(contentDocumentId)
Fetches the latest version of a file from Salesforce Files and returns its content as a base64 string.
@AuraEnabled
public static String getTemplate(Id contentDocumentId)
| Parameter | Type | Description |
|---|---|---|
contentDocumentId | Id | The ContentDocumentId of the Excel template file |
Returns: Base64-encoded file content (String)
Example:
// LWC
import getTemplate from '@salesforce/apex/ExcelTemplateController.getTemplate';
const templateBase64 = await getTemplate({ contentDocumentId: this.templateId });
saveDocument(base64Body, filename, linkedEntityId)
Saves a generated Excel file back to Salesforce Files and links it to a record.
@AuraEnabled
public static Id saveDocument(String base64Body, String filename, Id linkedEntityId)
| Parameter | Type | Description |
|---|---|---|
base64Body | String | Base64-encoded merged Excel file |
filename | String | Filename for the saved file (e.g., "Acme - Report.xlsx") |
linkedEntityId | Id | Record to attach the file to (Account, Opportunity, etc.) |
Returns: ContentDocumentId of the newly saved file
What it does:
- Creates a
ContentVersionrecord from the base64 content - Retrieves the auto-generated
ContentDocumentId - Creates a
ContentDocumentLinkwithShareType: 'V'(Viewer) andVisibility: 'AllUsers'
Example:
// LWC — call after receiving base64 from server
import saveDocument from '@salesforce/apex/ExcelTemplateController.saveDocument';
const docId = await saveDocument({
base64Body: mergedBase64,
filename: 'Acme Corp - Report.xlsx',
linkedEntityId: this.accountId
});
console.log('Saved to SF Files:', docId);
AccountSearchController
Provides SOQL-backed account search and contact fetching for the accountSearch component.
Used by: accountSearch LWC
searchAccounts(searchTerm)
@AuraEnabled(cacheable=true)
public static List<Account> searchAccounts(String searchTerm)
Returns up to 20 accounts whose names contain searchTerm (case-insensitive LIKE match).
Fields returned: Id, Name, Phone, Website, BillingCity, BillingState, Owner.Name
Example:
import searchAccounts from '@salesforce/apex/AccountSearchController.searchAccounts';
const results = await searchAccounts({ searchTerm: 'acme' });
// [{ Id: '001...', Name: 'Acme Corp', BillingCity: 'San Francisco', ... }]
getContacts(accountId)
@AuraEnabled(cacheable=true)
public static List<Contact> getContacts(Id accountId)
Returns up to 50 contacts for a given account, ordered by LastName then FirstName.
Fields returned: Id, FirstName, LastName, Title, Email, Phone
Example:
import getContacts from '@salesforce/apex/AccountSearchController.getContacts';
const contacts = await getContacts({ accountId: '001...' });
// [{ Id: '003...', FirstName: 'John', LastName: 'Doe', ... }]
QueryBuilderController
Provides dynamic SObject and field discovery plus SOQL execution with USER_MODE security enforcement.
Used by: queryBuilderLwc LWC
getObjects()
@AuraEnabled(cacheable=true)
public static List<SObjectInfo> getObjects()
Returns all queryable, accessible SObjects in the org.
Returns: List<SObjectInfo>
public class SObjectInfo {
@AuraEnabled public String name; // API name, e.g. "Account"
@AuraEnabled public String label; // Display label, e.g. "Accounts"
@AuraEnabled public Boolean queryable;
}
getFields(sobjectName)
@AuraEnabled(cacheable=true)
public static List<FieldInfo> getFields(String sobjectName)
Returns all accessible fields on the given SObject.
Returns: List<FieldInfo>
public class FieldInfo {
@AuraEnabled public String name; // Field API name, e.g. "BillingCity"
@AuraEnabled public String label; // Display label, e.g. "Billing City"
@AuraEnabled public String type; // e.g. "STRING", "CURRENCY", "REFERENCE"
}
Throws AuraHandledException if the SObject name is not recognized.
runQuery(soql)
@AuraEnabled
public static List<SObject> runQuery(String soql)
Executes an arbitrary SOQL query using AccessLevel.USER_MODE, which enforces field-level security and sharing rules.
| Parameter | Type | Description |
|---|---|---|
soql | String | Complete SOQL query string |
Returns: List<SObject> — records matching the query
Security: AccessLevel.USER_MODE means results are automatically filtered by the running user's FLS and sharing — users cannot retrieve records or fields they don't have access to.
Example:
import runQuery from '@salesforce/apex/QueryBuilderController.runQuery';
const records = await runQuery({
soql: 'SELECT Id, Name, AnnualRevenue FROM Account ORDER BY Name LIMIT 50'
});
Throws AuraHandledException if SOQL is blank or the query fails.