This article outlines the technical requirements, syntax rules, and limitations that apply when creating scenarios. Please review these before building or editing scenarios to ensure they run efficiently and reliably.
Scenario limitations
When creating scenarios, please be aware of the following limitations. Staying within these boundaries will ensure that your scenarios run efficiently and reliably.
Execution time limit: Scenarios must complete within 30 seconds. Queries that take longer will be automatically stopped.
Historical data in real-time scenarios: Real-time scenarios are designed to access up to 1 month of historical data. In special cases, longer ranges may be possible, but these are exceptions and require careful handling.
Historical data in post-event scenarios: Post-event scenarios can typically access up to 1 year of past transactions. This helps keep scenarios efficient and prevents very large scans.
JMESPath scenarios: JMESPath filters can only evaluate the current alerting transaction. They cannot look up or compare against past transactions.
Cross-checking large datasets: Scenarios that attempt to compare very large amounts of historical data across entities are not supported by default. If you need to design such a scenario, please discuss it with our Data Science team to evaluate feasibility and performance.
Real-time and post-event scenario syntax requirements
For SQL queries for real-time and post-event, pay attention to the following:
SQL query example for real-time or post-event:
select sum(past.amount) >= 10000 and count(distinct past.receiver_account) >= 20
, sum(past.amount)
, count(distinct past.receiver_account)
from transaction new
join transaction past on past.person_id = $personId and past.customer_id = $organisationId
join person p on p.id = $personId and p.customer_id = $organisationId
where new.id = $transactionId
and past.timestamp <= $transactionTimestamp
and past.timestamp >= $transactionTimestamp - '30 days'::interval
and past.direction = 'OUTGOING'
and p.type = 'INDIVIDUAL'
The first field in the SELECT clause needs to return TRUE or FALSE for the conditions relevant to the scenario. In the above example, the total amount in the past 30 days is at least 10000 and the number of distinct receiver accounts is 20.
Other fields in the SELECT clause are needed if they are used as dynamic parameters in the details field. This information will appear along with the alert.
In order to use parameters, add them to the SELECT clause and use the “$param” placeholder on the details field.
See the SQL scenario example above.
When joining tables on person ID: Ensure you add “person.id = $personId” and person.customer_id = $organisationId. When person data gets added, “$personId” will be replaced by the relevant person_id, and "$organisationID" will be replaced by your organisation ID.
Ensure you add “transaction.id = $transactionId” to the WHERE clause. When a transaction comes in, “$transactionId” will be replaced by the relevant transaction_id.
When using the timestamp of the current transaction, please use $transactionTimestamp. "$transactionTimestamp" will be replaced by the current transaction timestamp.
For JMESPATH queries, keep the following in mind:
JMESPATH query example for real-time or post-event:
currentTransaction[?direction == 'O'].amount.to_number(@)>`10000`
For JMESpath you can use variable currentTransaction to monitor one transaction, you can specify the needed parameters and query must return True-False.
For more on writing JMESpath, you can check out public documentation here.
Periodic scenario syntax requirements
For SQL queries for periodic scenarios, pay attention to the following:
SQL query example for a periodic scenario:
select person_id
, last_month_sum >= 1.5 * prev_month_sum and last_month_sum >= 10000
, last_month_sum
, prev_month_sum
from
(
select past.person_id as person_id
, sum(case when past.timestamp >= date_trunc('month', current_date-'1 month'::interval) then past.amount else 0 end) as last_month_sum
, sum(case when past.timestamp < date_trunc('month', current_date-'1 month'::interval) then past.amount else 0 end) as prev_month_sum
from transaction past
where past.customer_id = $organisationId
and past.timestamp < date_trunc('month', current_date)
and past.timestamp >= date_trunc('month', current_date-'2 months'::interval)
group by 1
) sub
Periodic scenarios do not use $transactionId, $personId, or $transactionTimestamp placeholders.
Instead, put person.id (or transaction.person_id) as the first field in the SELECT clause and group by that field.
The second field in the SELECT clause should still return TRUE or FALSE.
No other fields are mandatory, but you can still use dynamic query parameters.
Available computed parameters
The following computed parameters are available when writing scenarios:
$organisation.id— number$person.id— number (Salv's internal numeric ID for persons, separate from the IDs you send)$transaction.id— number (Salv's internal numeric ID for transactions, separate from the IDs you send)$transaction.timestamp— timestamp$person.risk— person final risk as string. Possible values:LOW, LOW_TO_MEDIUM, MEDIUM, MEDIUM_TO_HIGH, HIGH, UNACCEPTABLE$person.tags— array of person screening tags. Possible values:PEP, SANCTION, ADVERSE_MEDIA, CUSTOM_SCREENING_LIST, ADVERSE_MEDIA_ENTITY$scenario.handle— string$person.attributes.*— person attributes as strings, cast into other types explicitly if necessary.$transaction.attributes.*— transaction attributes as strings, cast into other types explicitly if necessary.$transaction.type$person.type- string, possible values:INDIVIDUAL,LEGALorUNDEFINED(legacyPRIVATEorBUSINESS)$transaction.external_id,$person.external_id- your internal IDs for transaction/person

