Empowering Customer Engagement: Inside Capillary Loyalty+’s Advanced Rule Engine Architecture

Sourabh Tiwari
Capillary Technologies
6 min readMar 28, 2024

Capillary Loyalty+ stands out as an innovative customer loyalty platform that offers extensive configurability. This advanced product empowers brands to tailor rules and actions across various customer touch points. Brands can use a lot of predefined events such as customer registration, transaction additions, points redemption etc. to write rules and ensure precise execution of configured actions. These actions span a diverse range, including point awards, communication across channels, and coupon issuance, among others.

At the core of processing all these events, lies the in-house rule engine which is used to define and execute the rules. Every rule is defined by an expression, which determines the conditions under which the rule applies. This rule expression utilizes a specialized DSL integrated with a custom data library for supported types which defines which rule expressions are supported for which event. It allows us to write rules on events and their attributes.

Challenges of Scaling with New Business Requirements

The platform’s initial design adeptly handled a predetermined set of events. However, as Capillary Loyalty+ expanded to accommodate new business verticals as well as newer channels like online and social channels capturing behavioral events, each introducing unique event types and attributes, the limitations became evident. Incorporating these new events traditionally required manual interventions by the development team, a process that was both time-consuming and prone to redundancy. This scalability bottleneck necessitated a more agile and automated solution.

Deep Dive into the Rule Engine Architecture

Rule engines, often referred to as inference engines, are dynamic software components engineered to execute business rules that have been abstracted or detached from application code. This abstraction enables business users to alter rules independently, without the involvement of the IT team.

Rule engine Overview

A rule engine can be understood through the following components:

  1. Rules Processor: This encompasses the essential logic required to interpret and evaluate rule expressions with the help of rule grammar. This rule grammar is also known as the data library. This data library not only facilitates the rule evaluation process but also enhances the user experience for business users by offering autocomplete suggestions and highlighting errors in real-time as rules are being written.
  2. Rules: This consists of the specific rules that are provided as input to the rule engine for processing.
  3. Event Payload: The event payload comprises event data, including information from API requests and user details stored in the database. It triggers the rule engine to evaluate the applicable rules.
Figure 1: Rule Engine overview

How rule expressions are stored and evaluated?

An Abstract Syntax Tree (AST) is a data structure used to represent and parse rules defined in a programming language or a domain-specific language. Rule expressions specify conditions or patterns that must be met for certain actions to be taken. The AST breaks down these expressions into a tree-like structure of nodes, where each node represents a part of the expression, such as an operator, operand, or function. This structure makes it easier to analyze, interpret, or transform the expressions.

Constructing an AST for rule expressions is essential for rule engines, compilers, and interpreters, as it enables complex logic to be represented in a structured and hierarchical manner, facilitating easier manipulation and evaluation of the rules.

In a rule engine, data is often encapsulated in objects with various attributes. For instance:

  • A User object might have attributes like name and age.
  • A Transaction object might have attributes like amount and date.

Rule expressions like user.age<25 && transaction.amount>1000 are divided into nodes which form an AST. The tree structure allows for efficient evaluation of expressions, following a bottom-up approach where sub-expressions are evaluated first, and their results are used to determine the overall outcome.

Figure 2: rule expression evaluation

Expression Evaluation

When the rule engine processes a rule expression, it begins by loading necessary objects and their associated attributes into memory. These attribute values are then inputted into an expression evaluator, which determines the outcome as either true or false.

The source of these attribute values varies, ranging from the request payload to database entries, external services, or the outcome of complex methods. Attributes which depend upon request payload, are loaded quickly whereas those from other sources usually take more time.
To enhance efficiency in rule evaluation, the rule engine often incorporates attribute caching techniques. This is achieved through the use of either in-memory caching systems or external caches, such as Redis, which serve to expedite the evaluation process. Additionally, the rule engines are designed with mechanisms for cache eviction, facilitated through user-friendly interfaces that allow for the modification of attribute values when necessary. This becomes particularly useful during the processing of an event that is evaluated across several rule expressions. One of cleaner ways of implementing caching and cache eviction is by using Proxy design pattern.

Figure 3: Rule expression evaluation flow

When rules expressions are evaluated, they result in true/false output. Based on rule expression output, whether it is true or false (fig. 4), configured actions are executed. Actions perform some of the validations and generate instructions. The instructions contain information about the actual tasks to be done.

Figure 4: Rule expression and corresponding actions for true/false condition

Adding Support for custom events and attributes in rule engine

Adding support for custom events in a rule engine involves several key steps to ensure that the events are structured in a way that can be easily parsed and loaded into the data library. Here’s a structured approach to accomplish this:

Defining Event Schema

In our scenario, the objects and properties within a rule expression are analogous to events and their respective attributes. For example, a custom event like GameCompletedEvent, which might include attributes such as playerName, score, rank, timeToFinish, and so forth. To incorporate this event into the rule engine, the user initially defines the event schema detailing all the attributes along with their data types.

{
"eventName" : "GameCompletedEvent",
"attributes" : [
{
"name": "playerName",
"dataType": "string"
},
{
"name": "score",
"dataType": "double"
},
{
"name": "rank",
"dataType": "integer"
},
{
"name": "timeToFinish",
"dataType": "long"
}
]
}

Defining event schema parser

The event schema parser is a crucial component. It reads the JSON event data and extracts necessary information. It also validates the event data against the defined event schema template. This ensures that the events have the correct structure and data types.

Integrating custom event data to data library

After the event schema is defined by brand user, the event can then be integrated into the data library. In the data library, all the event attributes are added with their data types which are available for rule writing. It is done by parsing the event schema, type casting to resolve attribute value and interpreting event data against the event schema at runtime using runtime interpretation methods.

Once these custom events and attributes are added to the data library as objects and attributes, they automatically become available in autocomplete suggestions on frontend and for evaluation on backend. Therefore, it allows brand users to add new custom events at runtime without the intervention of the dev team.

Conclusion

Capillary Loyalty+ offers a state-of-the-art customer loyalty platform with unmatched configurability. The core of Capillary’s platform is its dynamic rule engine, enabling independent rule modifications by business users. Brand users can configure rules without IT intervention.

With a comprehensive Data Library, packed with an extensive array of data objects and attributes, and support to add new event data objects and their attributes, Capillary Loyalty+ ensures efficient rule evaluation, enhancing performance.

In summary, Capillary Loyalty+ sets the standard for customer loyalty platforms, providing unmatched flexibility and performance to drive customer engagement and retention in today’s competitive market.

--

--