
Send a message only when it fits
Use the request, the resulting record and the operation context to decide whether a message belongs. One action can notify in one situation and stay quiet in another.
Example — Invite only people who need to accept
Creating a pending membership sends an invitation. Creating an already active member through provisioning does not send an unnecessary acceptance email.
For engineers
Express the state that earns the notification
The organization-member configuration uses one predicate for the pending invitation state:
Selected from organization-members.shared.resources-config.schemas.ts; surrounding module configuration is omitted.
const isPendingOrganizationMemberInvitation = ({
currentObject,
}: {
currentObject: Record<string, unknown>;
}): boolean =>
currentObject.status === OrganizationMemberStatus.INVITED;
Its email declaration then uses that predicate:
Selected from organization-members.shared.resources-config.schemas.ts; surrounding module configuration is omitted.
userNotifications: [
{
target: CoreUserNotificationTarget.USER_SELF,
channel: CoreUserNotificationChannel.EMAIL,
recipientEmailField: 'userEmail',
condition: isPendingOrganizationMemberInvitation,
}
]
The dispatcher runs the condition against post-operation function parameters before channel routing. An absent condition means the declaration is eligible; a false condition skips that notification. The same gate applies before the direct email-address path.
Respect a deliberate quiet request
The existing organization suspension operation accepts suspensionReason and notifyMembers (default true). Its email declaration uses the request, not the resulting organization’s status. Selected from the registered suspension operation, with explanatory comments omitted:
userNotifications: [
{
target: CoreUserNotificationTarget.ORGANIZATION_USERS,
channel: CoreUserNotificationChannel.EMAIL,
condition: ({ inputDto }) => (inputDto as { notifyMembers?: boolean } | undefined)?.notifyMembers !== false,
}
]
Example request body for an authorized suspension:
{
"suspensionReason": "Temporary administrative review",
"notifyMembers": false
}
The operation still suspends the organization; this declaration sends no member email. Omitting the flag retains the default notification. The condition grants no suspension authority: the operation still requires its super-admin role and an eligible organization state.
| Predicate input | Useful question |
|---|---|
currentObject | Did the committed record enter the state this message describes? |
inputDto | Did this request ask to notify? |
objectContext | Which resolved parent or child context makes the message relevant? |
initiatorIds | Which user, organization or application initiated the action? |
These are the authored inputs. A previous version of the record is not supplied as previousObject by this contract.
Coordinate related side effects
Invitation token generation has its own condition on the operation variant. Apply the same state rule to both token generation and notification when neither should occur for an active member. Conditioning only the template would still mint an unused token; conditioning only token creation could leave an email with no meaningful acceptance link.
A predicate that throws is caught as that notification’s dispatch failure so later declarations can still be processed. Keep the condition deterministic and focused on eligibility; authorization and data mutation belong to the operation itself.