Replies: 1 comment
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assumptions
No Custom Metadata by default
Developers shouldn’t be forced to create custom metadata records to make the framework work.
All handlers should be executed based on one of the following approaches:
A) Interface-based execution
The framework queries Apex classes that implement a handler interface and executes them automatically.
Pros
Cons
Mitigation
Trigger.Bypass(Open for discussion)
B) Orchestrator-based execution
Introduce an orchestrator that maintains a list of handlers to be executed.
Characteristics
Role of Custom Metadata
Custom metadata should be used only to override default handler behavior, not to define it.
Examples:
A metadata record can be created with a bypass flag enabled.
Handlers run for all users by default, but metadata can override this and restrict execution to specific profiles or permission sets.
Additional override options can be introduced as needed.
Populators
Over 90% of actions performed in
before insertorbefore updatecontexts are related to field population. We should introduce a sub-framework as part of the library called Populators. Populators should simplify development and reduce the need for complexif-elselogic.A populator should define two methods:
isQualifiedandpopulate.isQualifieddetermines whether the population logic should be executed.populateperforms the actual field population.This approach keeps the code minimal, readable, and easy to reason about.
The populator framework should be executed in a single-record context, without any explicit loops.
All DML and SOQL operations should be blocked when executed from the isQualified or populate methods.
If additional data is required—such as related or global data—it should be provided through a context object, which will be described in a separate section.
Handlers
Similarly to Populators, handlers should be executed in a single-record context to avoid repeating
forloops across multiple handlers.An interface should be introduced that enforces the implementation of two methods:
isQualifiedandexecute.isQualifieddetermines whether the execution logic should be applied to a given record.executeperforms the actual action — DML operations are allowed here.The
executemethod should be invoked only if at least one record qualifies.There should also be a way to enrich SObject records with related data.
A new method, enrichRelated, can be introduced to define the required relationships using a mapping structure:
Instead of a Map, a composite pattern (something similar to SOQL.FilterGroup
) could be used to support more deeply nested relationships, such as:Account.CreatedBy.Manager.Email`.All enrichRelated definitions from handlers should be aggregated, and the minimum number of SOQL queries should be executed without duplication.
SOQL Lib can be leveraged here to dynamically build optimized queries.
Records passed into the isQualified and execute methods should have related data accessible via dot notation, for example:
record.Account.CreatedBy.Manager.Email.Error handling
The framework should provide top-level error handling. It should be easy to override this behavior with custom logging.
Developers should not be required to add their own
try-catchblocks to every populator or handler.An interface such as
Trigger.Loggercan be introduced.Bypass
The
staticflag does not work correctly when there are more than 200 records (trigger chunks). A different approach should be defined to make bypassing work properly, for example using a hashCode-based mechanism (TBD).Finalizer
A finalizer should be defined. The finalizer can be implemented as a class with a dedicated interface, or the logic can be added to the orchestrator to specify a finalizer (similar to the Logger concept).
The finalizer can be used to commit all DML operations when a Unit of Work pattern is used.
All reactions