The Hidden Power of Permission Set Groups

The Hidden Power of Permission Set Groups

Permission Set Groups are one of the cleanest admin upgrades Salesforce has introduced—and I now use them to enforce structure and clarity across our org.

Instead of assigning a dozen permission sets individually, I:

  • Create logical groups like “Core Consultant Access” or “Service Manager Tools”

  • Add or remove permission sets centrally

  • Apply muting permissions when necessary (yes, you can subtract access too)

When to Use Platform Events vs Change Data Capture

When to Use Platform Events vs Change Data Capture

Both Platform Events and Change Data Capture (CDC) are great tools for loosely coupled integrations—but they serve different use cases.

How I decide:

  • Platform Events are best for intentional actions (e.g. “ReservationConfirmed”)

  • CDC is best for passive data sync (e.g. whenever a Contact is updated)

Loose Coupling in Flow and Apex: Why I Never Hardcode Anything Anymore

Loose Coupling in Flow and Apex: Why I Never Hardcode Anything Anymore

If there’s one rule I apply religiously in my org: hardcoding is technical debt.

Whether it’s Flow logic, Apex classes, or email templates, I aim for loose coupling:

  • Use Custom Metadata Types or Custom Settings for key values

  • Reference Labels, not static strings

  • Pull IDs dynamically using Custom Labels or SOQL selectors, not copy/paste

CI/CD in Salesforce: How I Use Source Control and Automated Testing

CI/CD in Salesforce: How I Use Source Control and Automated Testing

The best Salesforce orgs are built like modern software projects. That means embracing CI/CD, even if you’re a solo admin.

My current setup:

  • All declarative and code changes tracked in GitHub

  • Pull requests trigger validation deployments to a sandbox

  • Static code analysis runs using PMD and Prettier

  • Deployments happen via SFDX CLI scripts or GitHub Actions

Apex Design Patterns That Have Earned Their Place in My Org

Apex Design Patterns That Have Earned Their Place in My Org

Not all Apex needs to be abstract and layered—but when complexity grows, design patterns are how I keep things clean.

The patterns I reach for again and again:

  • Trigger Handler Pattern: One trigger per object, always. Handled via a framework class.

  • Service Layer Pattern: Keeps logic centralized and testable

  • Strategy Pattern (with interfaces): For dynamically applying rules based on context (e.g. by Record Type or membership category)

Governance, Not Gatekeeping: Enforcing Standards with Custom Metadata

Governance, Not Gatekeeping: Enforcing Standards with Custom Metadata

Great systems enforce standards without punishing innovation. I use Custom Metadata to define and enforce those standards across the org.

Examples from real projects:

  • Controlling which Record Types can trigger which Flows

  • Defining available options for dynamic automation menus

  • Centralizing logic that multiple Apex classes reference

Integration Patterns: Choosing the Right Tool for the Job

Integration Patterns: Choosing the Right Tool for the Job

Salesforce gives you a lot of ways to integrate—REST API, Apex callouts, Named Credentials, External Services, and more. The trick isn’t knowing what’s possible. It’s knowing what’s appropriate.

My go-to rules:

  • For real-time sync, I use REST callouts with Named Credentials

  • For asynchronous or high-volume data, I lean on Platform Events or Change Data Capture

  • For user-initiated actions, I’ll consider Screen Flows or LWC buttons with Apex

Event-Driven Architecture in Salesforce: Getting Started with Platform Events

Event-Driven Architecture in Salesforce: Getting Started with Platform Events

When systems need to talk to each other asynchronously, I reach for Platform Events. They’ve become a core part of how I design integrations and decoupled automation.

Why they matter:

  • They allow publish/subscribe communication between systems

  • They’re built for scale and resilience, not just speed

  • You can trigger flows or Apex in response to events—with zero user action