Docs‎ > ‎CA Live API Creator‎ > ‎Rules‎ > ‎

Business Rule - Reactive Design

Reactive Design

The key to understanding business rules is knowing that each rule is defined on a business entity (Table) and perhaps an attribute (Column) and the rule is'triggered' when state change occurs (e.g. PUT/POST/DELETE) on the entity and/or attribute. The other key to Reactive Design is that it may be necessary to introduce new tables and columns as part of the design to enact specific design results.

Derivations

These rule types are used to alter or 'derive' the value of a specific attribute.  Much like a spreadsheet cell, these derivations will be part of a chain of events that are called during the processing of a data transaction.   These derivations are applied to a specific attributes on a table.  For a more details see the Live Logic page.  In this exercise we are going to use the classic Customer/Order/Invoice to describe each of the derivation rules and how they are applied to an invoice.


The typical invoice contains company information, customer billing and shipping information, order header (invoice specific) and line item details.  Using this template as our guide - the invoice line item has an item#, quantity, details, unit price ($) and Total price ($).



The TotalPrice is derived using a formula (row.unitprice * row.quantity).  But we do not want to enter the unit price by hand, so where does this value live?  It is assigned to the Parts Inventory system.  The next rule we add is called a parent copy of unitprice from the Parts table when we enter the part item#.  The parent copy makes a replication of the value at the time of entry (non-maintained) so future price changes do not impact existing orders.  Not shown is the lineitem Discount calculations for this customer using a formula which applies quantity discounts based on customer loyalty.  We can also use the Parent Copy from Part to populate the Details on the line item.



The Invoice SubTotal uses a sum on the Invoice (order header) itself and we  will use a derivation called 
sum(lineitem.TotalPrice).  The invoice discount is the sum(lineitem.discount).  The Tax/VAT is another formula (row.subtotal * row.taxrate).  Finally - we calculate the grand total using a formula ((row.subtotal -row.discount) - (row.tax + row.shipping)). 

Notice that the building of rules we did not specify the order of operation or what events were needed.  In other words, state change means inserting a new line item, deleting a line item, changing a quantity or even an item# will trigger every one of these rules to recalculate. 

Validation

Behind the actual data entry of an order or shopping cart is some sort of validation logic.  The business requirements determine the level of open and unpaid orders a customer may have at any moment in time.  For example, we may create a validation that will REJECT an order when the balance of unpaid orders exceed the maximum credit limit.  This sounds like we need some additional derivation rules before we can determine the state of the unpaid balance.   If we create a validation reject if (row.totalUnpaidOrders > row.creditLimit) on the Customer entity we see that we need to derive totalUnpaidOrders as the sum(OrderTotal where paid= false).  We have added a qualification paid=false.  This paid flag is on our invoice (order) and when the state change occurs - this will increase or decrease or totalUnpaidOrders on the Customer entity. 

Events

Events are written in pure JavaScript and can be used to perform additional processes; for example, an event can be used to insert (Audit) changes for the current Entity, call an external Resource, send Email,  update a calendar system,  post a message on a queue, call a push notification engine, or process additional custom logic.  Events can begin with the incoming Request, the final Response, and early and post-commit processing on a transaction.  Events can be combined with Resources (user defined endpoints to external systems) to perform additional logic.  For example, this customers address can be passed to a Resource which in turn calls Google Geocode to return the lat/long coordinates to be used in a Google map for product delivery.

State Change Triggers

One of the often overlooked rules is Count.  The count is used like a sum to calculate the number of child objects.  And like the sum - it can have a filter (where) clause.  So you can use the state change (increase or decrease) in a child row to 'trigger' an event action.  For example, if the count of the child transactions is greater than 100, you could archive to MongoDB the older rows.  

Foreign Key Propagation

When using a Resource with nested children (Customer contains Orders, contains Items) - the ability to POST (insert) a new Customer, Order, and Items in one transaction can only be done when the primary key of the parent (Customer or Orders) can be propagated down to the child (e.g. Orders or Items).