Trigger Setup for Group Updates

FORMULASHARE ENTERPRISE / UNLIMITED ONLY
 

By default, FormulaShare keeps public groups up to date through a daily batch reassessment, which will be initiated by the first run of either the full recalculation batch or targeted calculation batch.

For more immediate updates, triggers can be set up to keep groups in sync in real time whenever team membership or User field values change.

This article covers the two types of triggers involved, what operations they handle, and the permissions required for them to work correctly.
 

Overview: Two Trigger Types

There are two separate mechanisms for real-time group updates, each enabled independently through FormulaShare Settings:

  • Team triggers – respond to changes to team member records, team records (including role field changes), and team affiliation records. Enabled via the Team Group Update Mode setting.
  • User trigger – responds to changes to User records where a field referenced by a "Users with Matching Field Value" rule is updated. Enabled via the User Group Update Mode setting.

Both types must be enabled in FormulaShare Settings and deployed as Apex triggers to work. See the sections below for details on each.
 

Team Triggers

Team triggers apply all additive changes (granting access) immediately. Most removal scenarios are deliberately deferred to the daily batch reassessment rather than handled in the trigger transaction.

This is a defensive design choice to ensure correct behaviour at large data volumes. Determining what to remove after a deletion or field change can require querying across many related records – team members, affiliated teams, parent/child hierarchies, and role assignments – all within a single transaction that is already consuming governor limits. Getting this wrong (removing too much, or triggering limit exceptions on large teams) would be worse than a short delay in access revocation. The batch job performs a complete, correct reassessment and will clean up any stale membership.

The one exception to this pattern is described under Team record changes below.

Supported Operations

Team Member changes (insert, update, delete)

When a team member record is created, the corresponding user is added to the team's public group immediately.

If a Team Member Role Field is configured on the mapping and a role value is set or changes on a team member record, the new role system group is added to the team's group immediately.

Removals – team member deleted, user/team lookup changed, or role value removed or changed – are deferred to batch reassessment.

Team record changes (insert, update)

If a team record's parent team field is assigned or changes, the child team's group is nested into the new parent team's group immediately. Removal from the old parent group is deferred to batch reassessment.

If a Team Role Field is configured on the mapping and the role field value changes, the new role system group is added to the team's public group immediately. The old role system group is also removed in real time, but only when both of the following apply:

  • No Team Affiliation Object is configured on the mapping (affiliated teams propagate role groups across groups, making real-time removal across all affected groups impractical)
  • No Team Member Role Field is configured on the mapping (otherwise multiple role sources may be present in the group and it is not safe to remove the old one unilaterally)

When either condition is not met, removal of the old role system group is deferred to batch reassessment.

This means the trigger on the team object handles both hierarchy changes and role field changes – no additional trigger is needed for role updates.

Team Affiliation changes (insert, update, delete)

When a new affiliation is created, the affiliated team's current direct members and role system groups are copied into the primary team's public group immediately (and vice versa for symmetrical mappings).

Removals – affiliation deleted or team pointers changed – are deferred to batch reassessment. Determining which members to remove after an affiliation change requires querying all remaining affiliations to avoid incorrectly revoking access that is still warranted via another path.

Enabling Team Group Update Mode

Real-time team group updates are enabled via the Team Group Update Mode setting in FormulaShare Settings custom metadata. Set this to Queueable to enable asynchronous processing (this is the only supported mode, as changes to public group membership in response to record changes must happen asynchronously to avoid Salesforce mixed DML errors).

If the setting is blank, team triggers will be bypassed even if the trigger code is deployed.

See App-Wide Settings for details on how to set this.

Deploying Team Triggers

For each object which is configured as a Team Object, Team Member Object, or Team Affiliation Object in any active Team Mapping, you should create an Apex trigger which calls FormulaShareTeamHelper. A single trigger per object is sufficient even if the object is used in multiple mappings.

The trigger should fire on after insert, after update, and after delete. Instantiate the helper and call process() – FormulaShare infers the trigger maps and object name from context automatically:

trigger TeamMemberTrigger on Team_Member__c(  after insert,  after update,  after delete ) {  new sdfs.FormulaShareTeamHelper().process(); }

This works for both standard and namespaced objects – no need to pass the object API name explicitly.

Triggers should also be created for the Team Object (to handle hierarchy changes and team-level role field changes) and the Team Affiliation Object (if affiliations are configured):

trigger TeamTrigger on Sales_Team__c (after insert, after update, after delete) {    new sdfs.FormulaShareTeamHelper().process(); } trigger TeamAffiliationTrigger on Team_Affiliation__c (after insert, after update, after delete) {    new sdfs.FormulaShareTeamHelper().process(); }

Role field changes on the team object: If your Team Mapping has a Team Role Field configured, changes to that field on team records are automatically handled by the existing team object trigger – the same trigger that handles hierarchy changes. No additional trigger is needed specifically for role updates. Just ensure the team object trigger is deployed and includes the role field in its coverage (no special configuration required beyond ensuring the trigger fires on after insert, after update, and after delete).

If you are using the standard FormulaShare Teams data model (sdfs__Team__c, sdfs__Team_Member__c and sdfs__Team_Affiliation__c), triggers on these objects are included in the FormulaShare package and do not need to be created separately.

A Note on Recursion Prevention

FormulaShareTeamHelper tracks which records have been processed within a transaction to prevent trigger recursion. If the same record is encountered a second time within the same transaction (which can happen if your automation updates team member records as a side effect), it will be skipped on the second pass.

Permission Requirements for Team Triggers

SOQL queries against team data run in user mode (the context of the user whose transaction enqueued the job), so the triggering user must have read access to the Team Object, Team Member Object (if configured), Team Affiliation Object (if applicable), and all mapped fields. DML to create or update public groups and group members runs in system mode, so no special group management permissions are required on the triggering user's profile.

See Team Sharing Permissions for the full list of required read access.

Bypassing Team Triggers

Assign the FormulaShare Groups Trigger Bypass custom permission to a user or profile to prevent the team trigger helper from processing their transactions. This is useful for data migration or batch processes which make large numbers of team membership changes that should be reconciled by the next batch reassessment instead.
 

User Triggers


Supported Operations

The User trigger handles User record updates. When a User record is updated and a field referenced by an active "Users with Matching Field Value" rule has changed, FormulaShare updates the user's membership in the relevant public groups. The user is removed from the group for the old field value and added to the group for the new field value.

If no field referenced by an active rule has changed, the trigger processing is skipped with no impact on performance.

Enabling User Group Update Mode

Real-time User group updates are enabled via the User Group Update Mode setting in FormulaShare Settings. This can be set to:

  • Queueable - Group membership is updated asynchronously via a queued job. This is recommended for most cases, as it avoids potential governor limit issues in transactions which update large numbers of users.
  • Synchronous - Group membership is updated immediately within the same transaction as the User update. This ensures groups are current before the transaction completes, but consumes governor limits from the triggering transaction. Use this if you need groups to reflect changes in real time within the same transaction.

If this setting is blank, the User trigger will be bypassed even if deployed.

Deploying the User Trigger

Create an Apex trigger on the User object which instantiates sdfs.FormulaShareUserTriggerHelper and calls process() – FormulaShare infers the trigger maps from context automatically:

trigger UserTrigger on User(after insert, after update) {    new sdfs.FormulaShareUserTriggerHelper().process(); }

A corresponding test class to provide code coverage:

@IsTest public class UserTriggerTest {  @IsTest  public static void testUpdate() {    User u = [      SELECT Id      FROM User      WHERE IsActive = TRUE AND UserType = 'Standard'      LIMIT 1    ];    update u;  } }

Permission Requirements for User Triggers

The queued job runs queries against User records in user mode, so the running user must have read access to the User fields referenced by active rules. No special access to public groups is required.

Bypassing the User Trigger

Assign the FormulaShare Groups Trigger Bypass custom permission to prevent the user trigger from processing a particular user's transactions. The same permission covers both team and user group trigger bypasses.
 

Working with Existing Trigger Frameworks

If your org uses a trigger framework or has existing triggers on the relevant objects, new sdfs.FormulaShareTeamHelper().process() or new sdfs.FormulaShareUserTriggerHelper().process() can be called from within the framework in the appropriate after-context handler rather than from a standalone trigger. Both classes also accept explicit map arguments via overloaded constructors or static methods which can be used if launching the functionality from outside a trigger context.

As with all FormulaShare trigger integrations, because FormulaShare is an approved managed package it has its own governor limit allocation and will not significantly impact your transaction's limits.
 

Related Articles: