archetypes-rules v1.2.2
archetypes-rules

Move conditional logic out of source code and database triggers and into a reusable package, where explicit rules can be independently defined and managed.
archetypes-rules models Boolean logic. Instead of writing conditionals like
if / else if / else, you can instead create Rules that describe and
evaluate Facts (aka, RuleContexts).
Table of Contents
1. Overview
Figure 1: Class diagram for the archetypes.rules namespace.

1.1. Rules
Rules are explicit constraints that govern actions. Rules evaluate Facts, or RuleContexts.
Rules are defined with⏤and stored as⏤JSON.
1.2. RuleElements
Rules contain one or more RuleElements. There are three types of RuleElements:
Propositions, Operators, and Variables.
1.2.1. Propositions
Propositions are statements that are either, true, false, or null
(unknown).
Learn more...
1.2.2. Variables
Variables are symbols that represent the value of something. Learn more...
1.2.3. Operators
Operators: Boolean and quantifier operators.
1.3. RuleContexts (aka "facts")
RuleContexts are facts, stored as JSON in files, databases, etc.
1.4. Rules evaluate RuleContexts/Facts
Rules evaluate RuleContexts. During evaluation, we determine whether a
RuleContext/Fact complies with a Rule.
returning a Proposition that tells us whether a given set of facts conform to
the defined Rule.
RuleElements are evaluated using
Reverse Polish Notation (RPN).
See the examples below for details.
2. Installation
npm install archetypes-rules3. Usage
3.1. Example 1: Is this customer eligible for a discount
Suppose we have a very simple rule that checks whether a customer is eligible for a discount. In order to be eligible, the customer simply needs to be a Gold Card holder.
const { Rule, RuleContext } = require('archetypes-rules')
// Create the rule
const rule = new Rule('eligibleForDiscount')
// Add a Proposition, i.e., a statement that has a value of true or false
rule.addProposition('customerIsGoldCardHolder', true)
// Create a RuleContext, i.e., a "Fact"
const ruleContext = RuleContext('eligibleForDiscountContext')
// Provide the truth statement as to whether the actual customer
// has a Gold Card
ruleContext.addProposition('customerIsGoldCardHolder', true)
// Evaluate
const result = rule.evaluate(ruleContext)
// Log the resulting Proposition
// Outputs
// Proposition statement = customerIsGoldCardHolder, value = true3.2. Example 2: Group discount for six or more people
Say you provide a discount to a group of six or more people:
// Create the rule
const rule = Rule('eligible-for-group-discount')
// Declare a "placeholder" variable for the actual number of people
// (This value will be retrieved from the RuleContext)
rule.addVariable('actual-num-people', null)
// Declare the minimum number of people required for discount
rule.addVariable('min-num-people', 6)
// Compare the two, i.e.,
// actual-num-people >= min-num-people
rule.addOperator(Operator.GREATER_THAN_OR_EQUAL_TO)
// Create a RuleContext, i.e., a "Fact"
const ruleContext = RuleContext('eligible-for-group-discount-fact')
// How many people are there?
ruleContext.addVariable('actual-num-people', 5)
// Declare the "placeholder" minimun number of people required for discount
// (This value will be retrieved from the Rule)
ruleContext.addVariable('min-num-people', 'NULL_NUMBER_VARIABLE')
// Evaluate
const result = rule.evaluate(ruleContext)
// Log the resulting Proposition
// OUTPUT:
// Proposition statement =
// (actualNumPeople >= minNumPeople), value = false3.3. Example 3: Is an airline passenger eligible for an upgrade?
In this example, we’re determining whether a given airline passenger is eligible to have their coach seat upgraded to a first-class seat. In order to be eligible, a passenger must:
- Be in economy class now and either
- Hold a Gold member card or
 - Hold a Silver member card and
 
 - Their carry-on luggage must be less than or equal to 15.0 pounds.
 
In order to determine this, we must compare a passenger’s facts with our rule.
const { Rule, RuleContext, RuleElement } = require('archetypes-rules')
// Create the rule
const rule = Rule('eligible-for-upgrade')
// Populate the rule using method chaining
rule
  .addProposition('passenger-is-economy', true)
  .addProposition('passenger-is-gold-card-holder', true)
  .addProposition('passenger-is-silver-card-holder', true)
  .addOperator('OR')
  .addOperator('AND')
  .addVariable('passenger-carry-on-baggage-weight', 'NULL_NUMBER_VARIABLE')
  .addVariable('passenger-carry-on-baggage-allowance', 15.0)
  .addOperator('LESS_THAN_OR_EQUAL_TO')
  .addOperator('AND')
// Create the RuleContext
const fact = RuleContext('eligibleForUpgradeFact')
// Load it with the facts about the passenger
fact
  .addProposition('passengerIsEconomy', true)
  .addProposition('passengerIsGoldCardHolder', true)
  .addProposition('passengerIsSilverCardHolder', false)
  .addVariable('passenger-carry-on-baggage-weight', 10.0)
  .addVariable('passenger-carry-on-baggage-allowance', 'NULL_NUMBER_VARIABLE')
// Log the resulting Proposition
// =>
// Proposition statement = (
//  (passengerIsEconomy AND
//    (passengerIsGoldCardHolder OR passengerIsSilverCardHolder)
//  ) AND (
//    passenger-carry-on-baggage-weight <= passenger-carry-on-baggage-allowance
//  )
// ), value = true4. Maintainers
The Maintainer Guide describes how we develop and release archetype-rules (and has useful information for Maintainers and Trusted Committers).
5. Contributions
 We gratefully accept Pull Requests. Here's what you
need to know to get started.
Before submitting a Pull Request, please read our:
- Code of Conduct
 - Contributing Aggreement
 - Developer Guide
 - Maintainer/Trusted Committer Guide
 - Architecture Decision Records
 
6. License
MIT © 2019 Greg Swindle
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago