Salesforce reference architecture
Skill jeremylongshore/claude-code-plugins-plus-skills/skills/.curated/salesforce-reference-architecture
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill salesforce-reference-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Implement Salesforce integration reference architecture with jsforce, SFDX, and event-driven patterns.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.6 KB, as published. Nobody here has run it
Salesforce Reference Architecture
Overview
Production-ready architecture patterns for Salesforce integrations, covering Node.js integration apps, SFDX metadata projects, and event-driven sync architectures.
Prerequisites
- Understanding of layered architecture
- jsforce and Salesforce CLI experience
- TypeScript project setup
- Decision on sync model (polling vs event-driven)
Project Structure
Node.js Integration App
my-sf-integration/
├── src/
│ ├── salesforce/
│ │ ├── connection.ts # Singleton jsforce connection with auto-refresh
│ │ ├── types.ts # Typed sObject interfaces (Account, Contact, etc.)
│ │ ├── queries.ts # SOQL query builders
│ │ ├── mutations.ts # Create/update/delete operations
│ │ └── events.ts # CDC and Platform Event subscribers
│ ├── services/
│ │ ├── account-sync.ts # Business logic for Account sync
│ │ ├── contact-sync.ts # Business logic for Contact sync
│ │ └── opportunity-sync.ts # Pipeline/forecast sync
│ ├── api/
│ │ ├── routes.ts # Express/Fastify routes
│ │ └── health.ts # Health check with SF connectivity
│ ├── jobs/
│ │ ├── full-sync.ts # Scheduled full data sync
│ │ └── incremental-sync.ts # CDC-based incremental sync
│ └── index.ts
├── tests/
│ ├── unit/ # Mocked jsforce tests
│ └── integration/ # Live sandbox tests
├── config/
│ ├── default.json # Shared config
│ └── production.json # Production overrides
└── package.json
SFDX Metadata Project (Apex, LWC, Triggers)
my-sf-app/
├── force-app/main/default/
│ ├── classes/ # Apex classes
│ │ ├── AccountTriggerHandler.cls
│ │ ├── ContactService.cls
│ │ └── IntegrationService.cls
│ ├── triggers/ # Apex triggers
│ │ └── AccountTrigger.trigger
│ ├── lwc/ # Lightning Web Components
│ │ └── accountList/
│ ├── objects/ # Custom object metadata
│ │ └── Integration_Log__c/
│ ├── permissionsets/
│ │ └── Integration_API_Access.permissionset-meta.xml
│ └── flows/ # Screen/record-triggered flows
├── scripts/apex/ # Anonymous Apex scripts
├── config/
│ └── project-scratch-def.json
└── sfdx-project.json
Integration Patterns
Pattern A: Polling-Based Sync
┌─────────────┐ SOQL Query ┌─────────────┐
│ Your App │ ──────────────────▶ │ Salesforce │
│ (cron job) │ SELECT ... WHERE │ Org │
│ │ ◀────────────────── │ │
│ │ JSON Records │ │
└─────────────┘ └─────────────┘
Pros: Simple, works with any edition
Cons: Latency (polling interval), wastes API calls on empty polls
Use: Small data volumes, non-real-time requirements
Pattern B: Event-Driven Sync (Recommended)
┌─────────────┐ ┌─────────────┐
│ Your App │ ◀─── CDC Events ─── │ Salesforce │
│ (listener) │ /data/Change* │ Org │
│ │ │ │
│ │ ── REST API ───────▶ │ │
│ │ Write-back │ │
└─────────────┘ └─────────────┘
Pros: Real-time, no wasted API calls, scalable
Cons: Requires Enterprise+, CDC setup, event replay handling
Use: Real-time sync, high-volume changes
Pattern C: Bi-Directional Sync (Heroku Connect)
┌─────────────┐ SQL Queries ┌─────────────┐
│ Your App │ ──────────────────▶ │ Postgres │
│ │ ◀────────────────── │ (Heroku DB) │
└─────────────┘ └──────┬───────┘
│
Heroku Connect
(automatic sync)
│
┌──────▼───────┐
│ Salesforce │
│ Org │
└─────────────┘
Pros: Zero API calls from your app, automatic bi-directional sync
Cons: Heroku cost, 10-min sync delay, limited to standard objects
Use: Heavy read/write, SQL-friendly teams
Key Architecture Decisions
| Decision | Recommendation | Rationale |
|---|---|---|
| Connection management | Singleton with auto-refresh | 1 connection per process, handles token expiry |
| SOQL queries | Typed query builders | Prevents field name typos, enables refactoring |
| Bulk operations | Bulk API 2.0 for 10K+, Collections for <200 | Optimizes API call consumption |
| Error handling | Map SF error codes to domain errors | INVALID_FIELD → SchemaError, etc. |
| Real-time sync | CDC over polling | No wasted API calls, sub-second latency |
| Data mapping | Explicit field mapping layer | Decouples app schema from SF schema |
| Testing | Mock jsforce in unit tests | Fast tests without org dependency |
Data Mapping Layer
// src/salesforce/mappers.ts
// Decouple your app's domain model from Salesforce field names
interface AppContact {
id: string;
firstName: string;
lastName: string;
email: string;
companyId: string;
}
function fromSalesforceContact(sf: any): AppContact {
return {
id: sf.Id,
firstName: sf.FirstName || '',
lastName: sf.LastName,
email: sf.Email || '',
companyId: sf.AccountId || '',
};
}
function toSalesforceContact(app: Partial<AppContact>): Record<string, any> {
const sf: Record<string, any> = {};
if (app.firstName !== undefined) sf.FirstName = app.firstName;
if (app.lastName !== undefined) sf.LastName = app.lastName;
if (app.email !== undefined) sf.Email = app.email;
if (app.companyId !== undefined) sf.AccountId = app.companyId;
return sf;
}
Output
- Node.js integration project with layered architecture
- SFDX metadata project structure
- Integration pattern selected (polling, event-driven, or Heroku Connect)
- Data mapping layer decoupling app from SF schema
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Tight coupling to SF schema | Direct field access | Add mapping layer |
| N+1 queries | Loop with individual queries | Use relationship SOQL or Collections |
| Stale cache | TTL too long | Use CDC events to invalidate |
| Event loss | No replay tracking | Persist last replayId |
Resources
Next Steps
For multi-environment setup, see salesforce-multi-env-setup.