Scheduled functions
Automate actions for existing policies triggered on a time-based schedule
Overview
Scheduled functions allow you to automate recurring actions to run against existing policies on a time-based schedule. You can configure how frequently the function will run, define custom function logic based on the existing policy data, and select from a predefined set of actions to be added to the platform's job queue.
Each scheduled function is defined as a standalone JavaScript function in the product module code. Each function can be defined to return a list of actions to update policy data, change policy status, and credit or debit the policy balance.
An example would be a monthly function that checks whether a policy is due for an annual premium increase, and returns an action to update the premium if the requirements are met.
You create a scheduled function by completing two steps:
- Setup - Choose a name for the scheduled function, define the schedule on which it will run, and filter for specific policy statuses.
- Configuration - Specify the function logic and the actions to be returned in the product module code.
Scheduled functions can also be triggered ad hoc using the trigger policy scheduled function endpoint.
Implementing scheduled functions safelyScheduled functions are a powerful tool that, by default, will
- run for all policies issued under your product module, and
- continue running indefinitely on your specified schedule (daily, monthly or yearly).
You may need to condition your scheduled function on the existing policy data to ensure that you execute actions for the right policies. For example, you can use a policy's start date to check that the anniversary has been reached before returning an action to update the premium.
We recommend testing scheduled functions in sandbox mode before implementing them for live policies.
Setup
Unlike lifecycle hooks, which are triggered by predefined policy events, scheduled functions are called on a schedule which you can determine.
When creating a scheduled function, you first need to specify the name of the code-function the platform will call in product module code, the time interval at which the function will be run, and for which policy statuses it will be applied.
You can set up a scheduled function for your product module using Workbench. Below is an example of a scheduled function in the root-config.json file.
{
"configVersion": "2021-05-09",
"productModuleName": "Shackleton Endurance",
"productModuleKey": "shackleton_endurance",
...
"scheduledFunctions": [
{
"functionName": "applyAnnualIncrease",
"policyStatuses": [
"not_taken_up",
"cancelled",
"active",
"lapsed",
"expired",
"pending_initial_payment"
],
"frequency": {
"type": "daily",
"timeOfDay": "02:00"
}
}
]
}Function name
The function name you specify (under the "functionName" parameter) must match the function name in the product module code. For example, if you create a new scheduled function with a name of applyAnnualIncrease, you need to include a corresponding function in your product module code with the same name:
/**
* Executed on the schedule defined in `.root-config.json`.
* @param {object} params
* @param {PlatformPolicy} params.policy The policy for which the scheduled function is running.
* @param {PlatformPolicyholder} params.policyholder The policyholder linked to the policy
* @return {ProductModuleAction[] | void} The actions to be queued by the platform.
*/
const applyAnnualIncrease = ({ policy, policyholder }) => {
// Function body
};Schedule
This scheduled function will recur indefinitely at the interval you specify. The frequency type can be set to any of the following:
- `daily` - to run the function at the same time every day
- `weekly` - to run the function on the same day every week
- `monthly` - to run the function on the same day every month
- `yearly` - to run the function on the same day every year
Depending on the frequency type selected, you will also need to specify the following:
dayOfWeek(for weekly functions)dayOfMonth(for monthly and yearly functions)monthOfYear(for yearly functions)
Irrespective of the selected frequency, you will also need to specify the time of day the function will run. This is the time at which any actions returned by the function will be added to the platform's job queue. The actual execution of those actions may be delayed by a few minutes.
This can be set at 30 minute intervals for any time during a 24-hour day.
Scheduled function execution timeThe time of day is specified as a Coordinated Universal Time time. The actual time of execution in your local timezone will depend on your timezone's offset from UTC.
This is the time at which any actions returned by the function will be added to the platform's job queue. The actual execution of those actions may be delayed by a few minutes.
Below is an example of the schedule frequency settings for a yearly scheduled function.
"frequency": {
"type": "yearly",
"monthOfYear": "january",
"dayOfMonth": 13,
"timeOfDay": "15:30"
}Scheduled functions can also be triggered ad hoc using the trigger policy scheduled function endpoint.
Policy statuses
The scheduled function will be applied only to the policy statuses you select. For example, you may want to exclude policies with an expired status from a scheduled function that implements an annual premium increase. Then you would select all policy statuses except expired.
You can select one or more of the policy statuses listed below. The active status is included by default, but can be removed. Note: At least one status must always be selected.
activepending_initial_paymentnot_taken_upcancelledlapsedexpired
Configuration
The configuration step involves defining the JavaScript function that will be called by the platform in the product module code. All scheduled functions accept the policy object and the policyholder object as arguments. Note: Both arguments are passed as properties of a single params object.
Function definition
You need to specify the following parts of the lifecycle hook function.
- Name - The name of the function in the product module code must match the name specified in the setup step exactly (case sensitive).
- Body - The body of the function can be used to define custom logic specifying the conditions under which certain actions are returned.
- Return statement - To queue an action or actions to be executed, the function must return an array of action objects. See the full list of actions.
Example
In this example, a scheduled function applyAnnualIncrease is defined to increase the policy's monthly premium by 10%.
/**
* Executed on the schedule defined in `.root-config.json`.
* @param {object} params
* @param {PlatformPolicy} params.policy The policy for which the scheduled function is running.
* @param {PlatformPolicyholder} params.policyholder The policyholder linked to the policy
* @return {ProductModuleAction[] | void} The actions to be queued by the platform.
*/
const applyAnnualIncrease = ({ policy, policyholder }) => {
const newPremium = policy.monthly_premium * 1.1;
return [
{
name: 'update_policy',
data: {
monthlyPremium: newPremium
}
}
];
}Optimising to reduce redundant executions
Executing a daily scheduled function across all policies in your book can lead to a significant amount of redundant product module code execution. To reduce this redundancy, you can make use of the processInstructions reserved scheduled function namespace. This ensures that only policies which include an instructions array with a length greater than 0 in their module data are processed.
- Contact the Root support team to request that they enable the process instructions feature flag for your organisation.
- Ensure that you name your scheduled function
processInstructions - Implement the
processInstructionsfunction in your product module code.- If you have more than one type of action, it is a good idea to implement this function as a wrapper that calls individual handlers.
- If the actions you are running are once off or need to be run again in the future you should manage date changes or removals of the current instruction in the handler. For example after executing policy anniversary logic you can update the instruction to run again in 1 years time.
- Add the
instructionsarray to the top level of the policy module data- This can be added at anytime during the policy lifecycle by using product module code in order to update module data.
- Each item in the array should include any data your handler might need in relation to the instruction. For example an execution date.
// Add your instructions to the policy
function getPolicy(application, policyholder) {
const instructions = [{ type: 'anniversary', date: moment().add(1, 'year').format('YYYY-MM-DD') }];
const module = {
...application.module,
instructions,
};
return new Policy({
...application,
module,
});
}
// The entry point to your custom instructions
function processInstructions({ policy }) {
const instructions = policy.module.instructions;
const updatedInstructions = instructions.map((instruction) => {
if (instruction.type === 'anniversary') {
return processAnniversary(instruction);
}
return instruction;
});
return [
{
name: 'update_policy_module_data',
data: {
...policy.module,
instructions: updatedInstructions,
},
},
];
}
// Handler for the anniversary instruction
function processAnniversary({ instruction }) {
return {
...instruction,
date: timeLib().add(1, 'year').format('YYYY-MM-DD'),
};
}Updated 2 days ago