Code Contribution Guidelines

Firstly, thank you for your support in contributing to DLRS!

Here are some simple guidelines we ask you to follow

  • Be familiar with the Git and submit all changes via PR’s, after submitting your PR check its status as we run some automation against all changes.
  • Be familiar with the general layout and style of code and separation of concerns
  • Ensure all modified or new Apex code you contribute has associated Apex tests
  • Ensure all code passes X style guide rules
  • Visualforce pages are lowercase in filename with no underscores

Code Overview

Q: Is there a class diagram for the code base?

This diagram shows the core service class described below being reused from various controllers, scheduled jobs and even a flow action! More detailed descriptions of these classes and others are included below.

[TODO - Need to install ApexUML package into a scratchorg]

Feature Related Objects, Classes, LWC’s etc
Core Engine - the core logic of the tool - its beating heart! Objects
LookupRollupSummary__c
Original store for rollup definitions
LookupRollupSummary2__c
New store for rollup definitions
LookupRollupCalculateJob__c
Used to avoid overlapping scheduled job execution
LookupRollupSummaryLog__c
Used to record failed rollups stemming from scheduled updates, records get automatically cleared on successful reruns
LookupRollupSummaryScheduleItems__c
When a rollup definition is defined as scheduled, this object records a list of parent records that need to be recalculated next time the RollupJob class is executed by a schedule
LookupChild__c and LookupParent__c
Only used by Apex test classes

Classes
LREngine.cls
See below
RollupService.cls
See below
RollupSummary.cls
See below
RollupSummariesSelector.cls
See below
RollupJob.cls
The incremental schedule recalc job, typically scheduled manually under Setup Apex Classes and reads instructions from LookupRollupScheduleItems__c.
RollupCalculateJob.cls
Specific to one rollup, uses criteria based on SOQL where clause to update parent records based on selected child records.
RollupCalculateScheduableJob.cls
Specific to one rollup, is an Apex scheduler for the above job, so it can be run on a recurring basis not just once.
Core UI - from the welcome page, to the main editing UI to managing rollup schedules and view schedules. Visualforce Pages
welcome.page and welcometab.page
The main welcome tab page!
managerollupsummaries.page
The main page for editing rollup definitions
managerollupsummaries_New.page
A brand new pilot UI for the tool with more advanced UI features
managetrigger.page
Used by RollupController.cls to deploy Apex Triggers dynamically, uses a JavaScript library via static resources to zip stuff up.
managetriggermdt.page
Same as above, but tweaked to work with Custom Metadata stored rollup definitions vs Custom Object.
rollupcalculate.page
See RollupCalculateJob.cls above
rollupcalculatemdt.page
See RollupCalculateJob.cls above
rollupschedulecalculate.page
See RollupCalculateScheduableJob.cls above
rollupsummaryenhanced.page
An older pilot UI based on the Custom Objects rollups (do not edit)
rolluplogdelete.page
See RollupSummaryLogDeleteController.cls below
rollupsummaryview.page
See RollupSummaryLogDeleteController.cls below

Apex Controllers
WelcomeController.cls
The main welcome page (default tab for DLRS app)
ManageLookupRollupSummariesController.cls
The main controller for editing rollup definitions
RollupController.cls
The main controller for deploying Apex Triggers dynamically!
ManageLookupRollupSummariesNewController
New pilot UI for the tool with more advanced UI features
RollupCalculateController.cls
See RollupCalculateJob.cls above
RollupScheduledCalculateController.cls
See RollupCalculateScheduableJob.cls above
RollupSummaryViewController.cls
The main controller to view full recalc scheduled rollups in one place
RollupSummaryLogDeleteController.cls
Simple controller to make deleting LookupRollupSummaryLog__c records easier for the user (so long as they know its safe to do so)
RollupSummaryEnhancedController.cls
An older pilot UI based on the Custom Objects rollups (do not edit)
Optimizer UI - relatively new UI for the tool - to help keep implementations healthy and running smoothly! Designed to be extensible easily. Flexipage
LookupRollupSummariesGome.flexipage
This is actually the Lookup Rollup Summaries Tools page and includes one component, the optimizer.cmp below.

Aura Components
optimizer.cmp
Linked with the Flexipage above, dynamically renders itself based on registered optimization components and their output.
optimizerNotification.cmp
Generic component used by the optimization components (see below) to communicate to the user.

Classes
OptimizerComponentController.cls
Calls methods on the OptimizerService to render recommended optimizations to the user for the tool
OptimizerService.cls
Internally extensible class that allows developers to write inner classes that perform various health checks by updating the NotificationReference enum and adding a corresponding inner class. See inner classes LookupRollupSummaryLogsExist and LookupRollupSummaryScheduleItemsFieldDeletion for examples. Also see further information in this blog.
Others - Flow integration and other misc files. RollupActionCalculate.cls
Implement invocable Action to allow the rollup engine to be invoked from Flow and other declarative builders.

Q: Where do I put SOQL logic?

If it relates to rollup definition information you want to query, please refer to the information above on the RollupSelector class. If it is more general, other system objects for example, please use the Selector pattern for this, see below.

Q: I see the tool uses fflib, what parts of it does it use?

It is used only to provide support for the Enterprise Architecture Patterns Selector concept, more about this can be found on the internet and in Trailhead itself.

Q: Where do I put new classes?

If its a new library class (from another open source library) please try to put thus under the /lib folder. Otherwise you can put new classes, including test classes directly in the /src folder.

Q: What other files do I need to consider when making changes?

The tool has its own permission sets that get upgraded when user install the latest package version. Thus if you add new tabs, objects, fields etc you will want to consider if they need exposing via one or both of the two packaged permission sets.

Q: Where are rollup definitions stored?

Historically the tool only used Custom Objects and went through many public releases with this approach. Custom Metadata arrived on the platform and provided a better way to store and access rollup definitions - which are essentially metadata. In order to maintain backwards compatibility - with those who installed the package prior - an abstraction layer was implemented within the code - to check both locations when looking for rollups. Users installing the tool for the first time are directed to the Manage Rollup Summaries tab which only reads and writes rollup configurations to Custom Metadata objects. The old Declarative Rollup Summaries tab for the Custom Object is still available but not added to the app by default.

Q: Tell me more about this abstraction layer for access rollup definitions?

The RollupSummariesSelector class is the single place in which the DLRS code base reads rollup definitions. It uses another class RollupSummary to represent a rollup definition instead of the usual __c or __mdt types.

This is because the selector class encapsulates both reading from the custom object and custom metadata locations where rollup definitions can exist in both places for some older customers. This encapsulation also makes it the perfect place to implement changes in the data model (new fields, defaults etc) without incurring widespread changes to the rest of the code.

Additionally the selector class uses two inner selector classes to separate the concerns of reading from two different locations, these inner classes are CustomMetadataSelector and CustomObjectSelector. The RollupSummariesSelector class exposes several public methods that represent requests the rest of the code makes for rollup information. These methods delegate to methods in the inner classes mentioned above. One to query for custom object based rollups and one for custom metadata based rollups. The results from both of these delegations are aggregated together before returning to the caller - so it appears as one result set and thus the storage and access patterns complexity is invisible to the caller.

Q: Why does the tool mostly use Visualforce page?

The main UI of the tool is the Manage Rollup Summaries tab although it uses the Lightning styles, it is a Visualforce page. As mentioned above the tool primarily uses Custom Metadata objects to store configuration - these objects are not supported by traditional Apex DML. Although Apex now supports Custom Metadata Operations natively, it does not support delete operations. For this reason Apex HTTP callouts to the Salesforce SOAP Metadata API are used to implement the read, update and delete actions when managing rollup definitions. This API requires a Session ID from the users current session with the correct privileges, at present this is only obtained from a Visualforce Apex Controller execution context. Other parts of the tools UI, such as the Tools tab use Lightning Web Components and no Visualforce.

Q: Where is the main entry point for the tools engine?

The methods marked as global on the RollupService class are used to perform the core operations of the tool, including scheduling of work and responding to scheduled invocations. Of course its primary entry point is RollupService.triggerHandler, which is a generic entry point capable of determining the context (which objects) the trigger is being fired from and scanning for one or more rollup definitions to execute. This class has gotten quite large over the years and is also supported by many test classes RollupServiceTestX.

Additionally, the LREngine class was the historic origin of the tools birth and performs much of the actual rollup work and results in set of parent records to update. This class is only ever used by the RollupService class and can be considered an implementation detail of it. Given that the LREEngine class is no longer it seems maintained by its original author, and given the overhead in maintaining it as such within DLRS, it is worth considering merging it as part of a future refactor of RollupService class should that happen.


Back to top

Declarative Lookup Roll-Up Summaries is a tool built and maintained by a community of volunteers through the Open Source Commons program. This is not a Salesforce-owned product. If you need support, go to the Trailblazer Community Group.