Business rules,
without the business logic mess!
RuleBox turns tangled if/else blocks into named rules you can read,
test and audit. Given some facts, when a condition holds, then act. Write them in BoxLang, YAML, JSON or even the database and
your business rules can change without a deploy.
class extends="rulebox.models.RuleBook" { function defineRules(){ addRule( newRule( "declineLowScores" ) .withPriority( 20 ) .when( ( facts ) => facts.creditScore < 580 ) .then( ( facts, result ) => result.setValue( "DECLINED" ) ) .stop() ) addRule( newRule( "autoApprove" ) .when( ( facts ) => facts.creditScore >= 680 ) .except( ( facts ) => facts.requestedAmount > 500000 ) .then( ( facts, result ) => result.setValue( "APPROVED" ) ) ) } }
// in any handler ruleBook( "loan" ) .run( { creditScore: 720, requestedAmount: 250000 } ) .getResult().getValue() // "APPROVED"
See the Rule Visualizer in action
Dashboard, chain view, dry runs, rule health, errors with stack traces and the live tracker, recorded against the RuleBox test app.
Facts in. A decision out. Every step recorded.
Rules run in priority order. Each one checks its condition, acts or skips, and can stop the chain. The audit trail shows exactly what happened.
Facts
run( facts )
A struct of name and value pairs: the data you decide on, declared and checked if you want.
When
.when( ... )
Each rule tests its condition, in priority order.
Except
.except( ... )
An exception skips the rule even when the condition holds.
Then
.then( ... )
Actions run, set the result, and can stop the chain.
Result
.getResult()
One answer, plus an audit trail of every rule.
Small API. Serious engine.
Natural-language DSL
Rules read like sentences. No nested conditionals, no scattered business logic.
given / when / except / then
Rules as data
Load rules from JSON, YAML or a database table, with named actions and predicates.
loadRules( source )
Declared rulebooks
Declare rulebooks in config or a folder, then get one anywhere by name.
ruleBook( "loan" )
Declared facts
Say which facts a rulebook takes, with types, defaults, examples and descriptions.
fact( "creditScore" ).required()
Enforced facts
Reject a missing or invalid fact before any rule runs, with every problem listed.
enforceFacts() / strictFacts()
Self-describing
Describe rulebooks and rules, or let a class's docblock do it. The Visualizer shows them.
withDescription( "..." )
Full audit trail
Know which rules executed, skipped or failed on every run.
getRuleStatusMap()
Dry runs
Ask what would happen for a set of facts, without running a single action.
dryRun( facts )
Priorities and stops
Order rules explicitly and let one rule end the chain.
withPriority( 20 ).stop()
Time windows
Turn a rule on for a season or a campaign, then let it expire.
active( from, until )
Rule Visualizer
Dashboard, chain view, dry run, rule health, errors with stack traces and a live tracker.
visualizer.enabled = true
WireBox native
Inject rulebooks and the Builder. A fresh RuleBook per decision keeps it thread safe.
inject="rulebook:loan"
The same rule, two ways.
Keep logic that rarely changes in BoxLang. Move thresholds that change often into JSON, YAML or a database table, and load them at runtime.
newRule( "declineLowScores" ) .withDescription( "Declines a score under 580" ) .withPriority( 20 ) .when( ( facts ) => facts.creditScore < 580 ) .then( ( facts, result ) => result.setValue( "DECLINED" ) ) .stop()
- name: declineLowScores description: Declines a score under 580 priority: 20 when: lt: [ creditScore, 580 ] then: - action: decide params: { decision: DECLINED } stop: true
{
"name": "declineLowScores",
"description": "Declines a score under 580",
"priority": 20,
"when": { "lt": [ "creditScore", 580 ] },
"then": [ { "action": "decide",
"params": { "decision": "DECLINED" } } ],
"stop": true
}
See your rules. Watch them fire.
A built-in admin UI: browse every rulebook, view its chain in run order, dry-run any facts, find the rules that fail or run slow, read each error with its stack trace, and stream evaluations live.
Learn RuleBox in ten short lessons.
Build a loan decision from a single if statement to rules in a file, running inside ColdBox and showing up in the Visualizer.
Get started
Install the module and run your first rule in five minutes.
Getting StartedProfessional support
Get expert help designing, implementing, or supporting your RuleBox integration from the Ortus Solutions team.
Email consulting@ortussolutions.comOpen source
Apache 2.0 licensed. Issues, ideas and pull requests welcome on GitHub.
coldbox-modules/rulebox