Skip to main content

What are the effects?

Effects are the business logic written in TypeScript that is executed by Trace API after an action is submitted. The effects declared in the configuration project are stringified functions that are stored in the database, so they can be interpreted at runtime by Trace API.
No external constants or functions can be used in the effects.

Workflow definitions

The dsl.$definitions object is the read-only storage of the workflow. It can be used to store constants, environment variables, workflow ids and stringified functions that will be accessible in the effects. The definitions can be of any shape, but by convention, it’s shape is the following:
repo
object
The repository of the workflow where workflow constants are stored.
functions
object
An object where each key is the name of the function and the value is the stringified function.
wfIds
object
A map between the workflow label and its id.
env
object
A map between the environment variable name and its value.

Notifications

Notifications (usually emails) are sent to a user (could be a single user, or a group) when performing an action. They are sent when the state.notifications is updated. Thus, notifications are usually built and sent inside the effects of an action. There is 3 steps to send a notification through configuration :
  1. Create a function inside workflowDefinitions to build the template of the email, and manipulate data derived from the state (because no external constants or functions can be used in the effects.)
create a custom function in the workflow /definitions/functions
export const createNotification = (data, meta) => {
  return {
    title: '',
    channel: 'EMAIL',
    groupLabel: data.entityLabel,
    template: {
      // etc..
    }
  };
};
  1. Inside the effects, import this function.
Usage in effects
const { state, formData, meta } = dsl.$variables;
const { createNotification } = dsl.$functions;

const notificationPayload = createNotification(state.data, meta);
  1. Updating state.notifications by pushing the template object with the correct data.
Update state
state.notifications.push(notificationPayload);
To see more details about it, go to the notification page.

External functions

Some functions are declared directly in Trace API, and can be accessed direcly in the effects using dsl.$modules.
An asynchronous function that searches for traces, allowing optional filters to be applied based on the traces’ data.
workflowId
string
required
The id of the workflow to search traces in.
filters
JSONDeepFilterValue[]
The filters to apply to the search.
An asynchronous function used to create a new scheduler.
The scheduler can be for example used to create links at a specific interval.
name
string
required
The unique name of the scheduler.
data
object
The data that will be used by the scheduler.
cron_expression
string
required
The cron expression that defines the schedule.
created_by
string
required
Any string to identify the creator of the scheduler.
An asynchronous function that stops a scheduler using its id.
id
string
required
The id of the scheduler to stop.
Exposes the moment function from the moment library (v2.29.1).
See the moment documentation for more information.
Example
const { moment } = dsl.$modules;
const now = moment();
const tomorrow = moment().add(1, 'day');
const yesterday = moment().subtract(1, 'day');
Exposes z from the zod library (v3.24.0).
See the zod documentation for more information.
Example
const { z } = dsl.$modules;

const isAdultSchema = z.object({
name: z.string().min(2),
age: z.number().min(18),
}).strict();

const myData = mySchema.parse({
name: 'John',
age: 30,
});

Example - Order a meal

Let’s imagine a restaurant workflow where a client can order a meal. The workflow has two groups: cook and client. In the first action, the client will select a meal to order and submit the form. The goal of the effect is to:
  • store the selected meal in the trace’s data,
  • add the 'Order received' status to the trace with a progress of 20%,
  • and update the next available actions for each group:
  • the cook group should be able to do the prepareOrder action and comment,
  • the client group should only be able to do the comment action.
orderMealEffect
async function orderMealEffect(dsl: RestaurantWorkflowContext<FormData>) {
// We destructure the DSL variables for readability
const { state, formData } = dsl.$variables;
const { data, nextActions } = state;

// The chosen meal is retrieved from the form data and stored in the data
data.meal = formData.meal;

data.status = {
status: 'Order received',
progress: 0.2
};

// Now, we update the next actions
nextActions = {
cook: ['prepareOrder', 'comment'],
client: ['comment']
};
}

const effects: Statement[] = [execJs(orderMealEffect)];