In this example, we manage a Ruleset with complex conditions that will be reused in different rules. Let's check the following use case: A world-wide event organizes conferences in Paris, London and New-York. To promote the event for young people, there is an extra discount for minors if they attend two days of the event.
While the pricing logic will be done on the API side, we will display a dedicated message for kids booking two days of the conference.
The French and American conferences also offer extra activities for the minors attending the event and will display a teaser of the activities.
In this scenario, we consider the following facts:
ageOfCustomer
at the time of the eventlocationOfConference
the customer wishes to attenddaysSpentAtEvent
The majority of the customer will depend on the place of the conference and the date of birth of the customer:
You could write this rule as follows:
In this Ruleset, there is some duplication of "the customer is a minor" logic. This makes it more difficult to read and maintain.
Let's see how the use of an intermediate, temporary fact (also known as runtime fact) helps to refactor this kind of ruleset.
For this rule, we will simply introduce the IS_MINOR
fact and share the logic between the different rules.
There will be three simpler rules and each will handle one condition with no duplicate logic:
{
"schema": "https://raw.githubusercontent.com/AmadeusITGroup/otter/main/packages/%40o3r/rules-engine/schemas/rulesets.schema.json",
"rulesets": [
{
"id": "6194b61a-1bf3-4c02-8b7c-20f782d68324",
"name": "Promotion for minors",
"disabled": false,
"rules": [
{
"id": "5467e501-b9ff-414f-8026-56885d0d7a4b",
"name": "Check if customer is a minor",
"disabled": false,
"outputRuntimeFacts": [
"IS_MINOR"
],
"inputRuntimeFacts": [],
"rootElement": {
"elementType": "RULE_BLOCK",
"blockType": "IF_ELSE",
"condition": {
"any": [
// The customer is a minor in France or London
{
"all": [
{
"lhs": {
"type": "FACT",
"value": "ageOfCustomer"
},
"operator": "lessThan",
"rhs": {
"type": "LITERAL",
"value": 18
}
},
{
"lhs": {
"type": "FACT",
"value": "locationOfConference"
},
"operator": "inArray",
"rhs": {
"type": "LITERAL",
"value": [
"Paris",
"London"
]
}
}
]
},
// The customer is a minor in New-York
{
"all": [
{
"lhs": {
"type": "FACT",
"value": "ageOfCustomer"
},
"operator": "lessThan",
"rhs": {
"type": "LITERAL",
"value": 21
}
},
{
"lhs": {
"type": "FACT",
"value": "locationOfConference"
},
"operator": "equals",
"rhs": {
"type": "LITERAL",
"value": "New-York"
}
}
]
}
]
},
"successElements": [
{
"actionType": "SET_FACT",
"key": "IS_MINOR",
"value": "TRUE"
}
],
"failureElements": [
{
"actionType": "SET_FACT",
"key": "IS_MINOR",
"value": "FALSE"
}
]
}
},
{
"id": "5467e501-b9ff-414f-8026-56885d0d7aas",
"name": "Teaser for minors in Paris and in New-York",
"disabled": false,
"outputRuntimeFacts": [],
"inputRuntimeFacts": [
"IS_MINOR"
],
"rootElement": {
"elementType": "RULE_BLOCK",
"blockType": "IF_ELSE",
"condition": {
"all": [
{
"lhs": {
"type": "RUNTIME_FACT",
"value": "IS_MINOR"
},
"operator": "equals",
"rhs": {
"type": "LITERAL",
"value": "TRUE"
}
},
{
"lhs": {
"type": "FACT",
"value": "locationOfConference"
},
"operator": "inArray",
"rhs": {
"type": "LITERAL",
"value": [
"Paris",
"New-York"
]
}
},
],
},
"successElements": [
{
"actionType": "UPDATE_PLACEHOLDER",
"key": "teaser-placeholder",
"value": "assets/placeholders/teaser-activities.json"
}
]
}
},
{
"id": "5467e501-b9ff-414f-8026-56885d0d7aas",
"name": "Discount message for minors spending 2 days at the event ",
"disabled": false,
"outputRuntimeFacts": [],
"inputRuntimeFacts": [
"IS_MINOR"
],
"rootElement": {
"elementType": "RULE_BLOCK",
"blockType": "IF_ELSE",
"condition": {
"all": [
{
"lhs": {
"type": "RUNTIME_FACT",
"value": "IS_MINOR"
},
"operator": "equals",
"rhs": {
"type": "LITERAL",
"value": "TRUE"
}
},
{
"lhs": {
"type": "FACT",
"value": "daysSpentAtEvent"
},
"operator": "equals",
"rhs": {
"type": "LITERAL",
"value": 2
}
}
]
},
"successElements": [
{
"actionType": "UPDATE_LOCALISATION",
"key": "welcome-text",
"value": "welcome-text-with-promotion"
}
]
}
}
]
}
]
}