The Trigger Lib provides an orchestrator and small role-based handlers for Apex triggers, with record qualification, declared parent queries, a unit of work, bypasses and recursion control.
Trigger Lib is part of Apex Fluently, a suite of production-ready Salesforce libraries by Beyond the Cloud.
Trigger
trigger AccountTrigger on Account(before insert, after insert, before update, after update, before delete, after delete, after undelete) {
TriggerOrchestrator.run(new AccountTriggerOrchestrator());
}Orchestrator
public with sharing class AccountTriggerOrchestrator implements TriggerOrchestrator.BeforeInsert, TriggerOrchestrator.AfterInsert {
public List<BeforeInsert.Handler> beforeInsertHandlers() {
return new List<BeforeInsert.Handler>{ new AccountRatingPopulator(), new AccountCustomerDataValidator() };
}
public List<AfterInsert.Handler> afterInsertHandlers() {
return new List<AfterInsert.Handler>{ new AccountWelcomeTaskWriter() };
}
}public with sharing class AccountRatingPopulator implements BeforeInsert.Populator {
public Boolean populateOnBeforeInsertWhen(TriggerTypes.InsertRecord record) {
return record.isBlank(Account.Rating) && record.isNotNull(Account.AnnualRevenue);
}
public void populateOnBeforeInsert(TriggerTypes.InsertRecord record) {
record.put(Account.Rating, record.greaterThanOrEqualTo(Account.AnnualRevenue, 5000000) ? 'Hot' : 'Warm');
}
}public with sharing class AccountCustomerDataValidator implements BeforeInsert.Validator {
public Boolean addErrorOnBeforeInsertWhen(TriggerTypes.InsertRecord record) {
return record.startsWith(Account.Type, 'Customer') && record.isBlank(Account.Industry);
}
public void addErrorOnBeforeInsert(TriggerTypes.RejectableInsertRecord record) {
record.addError(Account.Industry, 'A customer account requires Industry.');
}
}public with sharing class AccountWelcomeTaskWriter implements AfterInsert.Writer, AfterInsert.ParentQuery, AfterInsert.ContinueOnError {
public Map<SObjectField, TriggerTypes.ParentFields> queryParentsOnAfterInsert() {
return new Map<SObjectField, TriggerTypes.ParentFields>{ Account.OwnerId => TriggerTypes.ParentFields.with(User.Name) };
}
public Boolean writeOnAfterInsertWhen(TriggerTypes.InsertRecord record) {
return record.startsWith(Account.Type, 'Customer');
}
public void writeOnAfterInsert(TriggerTypes.InsertRecord record, TriggerTypes.UnitOfWork unitOfWork) {
Account newAccount = (Account) record.getNewSObject();
User owner = (User) record.getNewParent(Account.OwnerId);
unitOfWork.toInsert(new Task(WhatId = record.getId(), OwnerId = newAccount.OwnerId, Subject = 'Onboarding call - ' + newAccount.Name, Description = 'Assigned to ' + owner?.Name));
}
}
Visit the documentation to view the full documentation.
Read about the features in the introduction.
- For proper license management each repository should contain LICENSE file similar to this one.
- Each original class should contain copyright mark: Copyright (c) 2026 Beyond The Cloud Sp. z o.o. (BeyondTheCloud.Dev)