Anatomy of a Risk Action¶
Risk actions are the central building block of the Send Workbench workflow. Almost everything else in the platform — submission forms, pipelines, document generation, rules, display expressions — exists in service of risk actions. Understanding their structure thoroughly is the single most useful thing a configurator can do before touching any other part of the platform.
What a risk action is¶
From a user's perspective, a risk action is one of the steps listed on the left-hand side of a risk record — "Appetite Check", "Sanctions Check", "Structured Quote", "Bind". Each has a status (pending, in progress, complete, failed) and a button that opens a pop-up form.
From a configurator's perspective, a risk action is a JSON object that defines:
- which business class and placing type it belongs to
- where it appears in the list (sort order, group)
- what must be completed before it becomes available (prerequisites)
- what pipeline fires automatically when it becomes available (initial pipeline)
- what pipeline fires when the user submits it (completion pipeline)
- which operations (buttons) appear inside the pop-up, and when
- how sub-statuses set by pipelines map to the action's displayed status
- whether it is visible at all, based on the current state of the risk
Where the file lives¶
Actions for a business class are defined in a single JSON array file:
For example, all Open Market actions for the Aviation class live in:
The file contains an ordered array of action objects — one object per action. The sortOrder field controls the order they appear in the UI.
Never change an action name once it is in use
The name field is the action's permanent identifier. Workbench stores action instance records keyed on this value. Changing it breaks the action history for all existing risks and corrupts dashboards and reporting. Treat it as immutable once deployed.
The anatomy of one action object¶
Here is a fully annotated example based on the base repository's appetite_check action from av-open-market-actions.json:
{
"businessClassTypeCode": "AV",
"placingType": "OPEN_MARKET",
"actionGroupCode": "risk_setup",
"name": "appetite_check",
"defaultOwningRole": "UA",
"sortOrder": 25,
"actionPrerequisites": [
"dnb_lookup"
],
"initialPipeline": "appetite_check_initial",
"displayCriteriaExpression": {
"jsonPathExpression": "$.mtaReasonCode",
"operatorType": "NOT_EQUAL_OR_NULL",
"testValue": "MTAR16"
},
"operations": [
{
"name": "appetite_check",
"defaultOwningRole": "UA",
"displayIfStatePresent": [
"APPETITE_CHECK_FAILED"
]
}
],
"statusMappings": {
"APPETITE_CHECK_COMPLETE": "COMPLETE"
}
}
Every field is explained below.
Field reference¶
Identity fields¶
| Field | Required | Description |
|---|---|---|
name |
Yes | Unique identifier for this action within this business class and placing type. Used in actionPrerequisites, pipeline references, screen meta data, and reporting. Never change once deployed. |
businessClassTypeCode |
Yes | The business class this action belongs to (e.g. AV, ME, PB). Must match the business class file. |
placingType |
Yes | The placing type this action applies to. Must match the business class's enabledPlacingTypes. |
Display and grouping¶
| Field | Required | Description |
|---|---|---|
actionGroupCode |
Recommended | The action group this action belongs to. Controls the section heading it appears under on the risk record. If omitted, the action appears in a default ungrouped section. |
sortOrder |
Recommended | Numeric position of this action within its group. Lower numbers appear first. Actions with the same sort order appear in file order. |
defaultOwningRole |
Yes | The role code (e.g. UA, UW) of the user who owns this action by default. Determines who sees the action as assigned to them. |
Prerequisites¶
An array of name values of actions that must be in COMPLETE status before this action becomes available. The action will not appear as actionable until all prerequisites are satisfied.
Tip
Design prerequisites to reflect real underwriting governance — not just technical sequencing. The prerequisite chain is visible to auditors and is the platform's primary evidence of workflow compliance.
Pipelines¶
| Field | When it fires |
|---|---|
initialPipeline |
Fires once, automatically, when the action first becomes available (i.e. when all prerequisites are met). Use this to pre-populate data, auto-run checks, or set the initial action state. |
completionPipeline |
Fires when the user submits the action (clicks Save or an operation button that completes the action). Use this to trigger downstream workflow steps. |
Both values are pipeline file names (without .json) that must exist in config/{client}/pipelines/.
Display criteria¶
Display criteria control whether an action is visible on the risk record. An action that fails its display criteria is hidden entirely — not greyed out, not locked, just absent.
Single expression¶
"displayCriteriaExpression": {
"jsonPathExpression": "$.mtaReasonCode",
"operatorType": "NOT_EQUAL_OR_NULL",
"testValue": "MTAR16"
}
Multiple expressions (AND / OR)¶
When you need more than one condition, use the plural form with an operand type:
"displayCriteriaExpressionsOperandType": "AND",
"displayCriteriaExpressions": [
{
"jsonPathExpression": "$.displayAllActions",
"operatorType": "EQUAL",
"testValue": "true"
},
{
"jsonPathExpression": "$.mtaReasonCode",
"operatorType": "NOT_EQUAL_OR_NULL",
"testValue": "MTAR16"
}
]
| Field | Options | Description |
|---|---|---|
displayCriteriaExpressionsOperandType |
AND / OR |
Whether all expressions must be true (AND) or any one must be true (OR). |
jsonPathExpression |
JSONPath string | Evaluated against the risk context object. |
operatorType |
See below | How to compare the expression result to testValue. |
testValue |
String | The value to compare against. |
Available operator types for display criteria:
| Operator | Description |
|---|---|
EQUAL |
Result equals testValue |
NOT_EQUAL |
Result does not equal testValue |
IS_NULL |
Result is null or absent |
NOT_NULL |
Result is not null |
EQUAL_OR_NULL |
Result equals testValue or is null |
NOT_EQUAL_OR_NULL |
Result does not equal testValue, or is null |
Note
GREATER_THAN, LESS_THAN, and STARTSWITH exist in the operator enum but are only honoured in pipeline configuration — not in risk action display criteria.
Status mappings¶
Pipeline steps can set a sub-status on the action (a string key that represents what the pipeline found). The statusMappings field translates those sub-status keys into the three displayed action statuses the UI understands.
"statusMappings": {
"SANCTIONS_CHECK_PASSED": "COMPLETE",
"SANCTIONS_CHECK_FAILED": "FAILED",
"sanctions_check_referral_outcome_first_line.TRUE_MATCH_ACCEPTED": "COMPLETE",
"sanctions_check_referral_outcome_first_line.TRUE_MATCH_DECLINE": "FAILED"
}
| Displayed status | Meaning |
|---|---|
COMPLETE |
The action is done — prerequisites on downstream actions are considered satisfied. |
FAILED |
The action has failed — downstream prerequisites that depend on this action cannot be met. |
IN_PROGRESS |
The action is open and actively being worked. |
Any sub-status key not listed in statusMappings leaves the action in its current state (it does not automatically fail or complete).
Operations¶
An operation is a button inside the action pop-up. Most core actions have a default set of operations (Save, Submit, Not Required, Restart) provided by the platform. You can extend, restrict, or override these.
"operations": [
{
"name": "review_sanctions_warning",
"defaultOwningRole": "SC_FC_OPS",
"displayIfStatePresent": ["SANCTIONS_CHECK_WARNINGS"],
"displayIfStateNotPresent": ["sanctions_check_referral_outcome_first_line.TRUE_MATCH_REFERRED"]
},
{
"name": "review_sanctions_warning_second_line",
"defaultOwningRole": "SC_FC",
"displayIfStatePresent": ["sanctions_check_referral_outcome_first_line.TRUE_MATCH_REFERRED"]
}
]
| Field | Description |
|---|---|
name |
Operation identifier — must match a key in business-constants/operation.json for its label to display correctly. |
defaultOwningRole |
Role that owns this operation. |
displayIfStatePresent |
Array of sub-status keys — this operation only appears if at least one of these sub-statuses is currently set on the action. |
displayIfStateNotPresent |
Array of sub-status keys — this operation is hidden if any of these sub-statuses is set. |
icon |
Optional icon key (e.g. "eye") to display on the operation button. |
Completed operations (completedOperations) define operations that appear once the action is in COMPLETE status — typically a read-only view operation:
Removing platform defaults:
Overriding platform default operation labels:
How everything connects¶
A risk action is the centre of a web of related config. Here is how each piece connects:
Risk action (actions/{bc}/{bc}-{pt}-actions.json)
│
├─ actionGroupCode ──────────► Action group label (business-constants/action_group.json)
│
├─ name ─────────────────────► Action label (business-constants/action.json)
│
├─ initialPipeline ──────────► Pipeline file (pipelines/{name}.json)
│
├─ completionPipeline ───────► Pipeline file (pipelines/{name}.json)
│
├─ operations[].name ────────► Operation label (business-constants/operation.json)
│ Screen meta data config (screen-meta-data/config/{bc}/{name}.json)
│ Screen meta data layout (screen-meta-data/files/{bc}/{name}.json)
│
└─ displayCriteriaExpressions ► Risk context (evaluated at page load)
The operationName linkage is the most commonly broken connection. The name in an operations entry must match the operationName in the screen meta data config file exactly. If it does not, the action pop-up opens with an empty or broken form, and no error appears in the UI — only in the service logs.
A minimal working example¶
The smallest possible custom action — a manual sign-off step with no pipeline:
{
"businessClassTypeCode": "ME",
"placingType": "OPEN_MARKET",
"actionGroupCode": "compliance",
"name": "compliance_sign_off",
"defaultOwningRole": "UW",
"sortOrder": 50,
"actionPrerequisites": ["sanctions_check"],
"statusMappings": {
"COMPLIANCE_APPROVED": "COMPLETE",
"COMPLIANCE_REJECTED": "FAILED"
}
}
To make it functional end to end you would additionally need:
compliance_sign_offadded tobusiness-constants/action.json(for its label)- A screen meta data config file at
screen-meta-data/config/me/compliance_sign_off.json - A screen meta data layout file at
screen-meta-data/files/me/compliance_sign_off.json - The
compliancegroup defined inbusiness-constants/action_group.json
Common mistakes¶
| Mistake | Symptom | Fix |
|---|---|---|
name changed after deployment |
Existing risk histories broken; dashboards show blank action names | Never change name. Create a new action instead. |
operationName in screen meta data does not match operations[].name |
Pop-up opens empty or throws error | Ensure exact string match (case-sensitive) |
statusMappings key does not match sub-status set by pipeline |
Action stays IN_PROGRESS indefinitely |
Log the pipeline execution and verify the exact sub-status string it sets |
actionPrerequisites lists a name that does not exist |
Prerequisite can never be satisfied; action never becomes available | Verify the spelling matches the name field of the prerequisite action exactly |
displayCriteriaExpressions used without displayCriteriaExpressionsOperandType |
Platform behaviour is undefined | Always specify AND or OR when using the plural form |
See also¶
- Actions — full field reference and applying configuration changes
- Action Groups — configuring the section groupings
- Pipelines — writing the pipelines that actions trigger
- Element Types — writing the screen meta data for action pop-ups
- Display Expressions — the full display criteria operator reference