Skip to main content

Regulatory Engine

The regulatory module implements a visual, graph-based rules engine for evaluating building regulations. Rules are created in the admin panel using a ReactFlow node graph editor and evaluated on the backend.

Concepts

Rules

A RegulatoryRule represents a single regulation or by-law. Each rule contains:

  • Parameters — Input variables required and output variables produced
  • Graph — A ReactFlow node/edge graph that defines the computation logic
  • Metadata — Authority, region, regulatory reference, tags

Variables

A RegulatoryVariable is a globally-registered input or output parameter:

site.area          → number (sqm)     [INPUT]
site.road_width → number (m) [INPUT]
result.max_far → number [OUTPUT]
result.max_height → number (m) [OUTPUT]
result.setback.front → number (m) [OUTPUT]

Graph Evaluation

The rule graph is a DAG (directed acyclic graph) of computation nodes:

┌───────────┐     ┌──────────────┐     ┌────────────┐
│ Input: │────▶│ Condition: │────▶│ Output: │
│ site.area │ │ area > 2000 │ │ max_far │
└───────────┘ │ ? 2.5 │ │ = result │
│ : 1.75 │ └────────────┘
└──────────────┘

Node types include:

  • Input — Reads a variable value
  • Constant — Fixed numeric/boolean/string value
  • Comparison>, <, >=, <=, ==, !=
  • Arithmetic+, -, *, /
  • Conditional — If/then/else branching
  • Output — Writes a result variable
  • Math Functionsmin, max, round, ceil, floor

Endpoints

MethodPathDescription
GET/regulatory/rulesList all rules
POST/regulatory/rulesCreate a new rule
GET/regulatory/rules/:idGet rule details (including graph)
PATCH/regulatory/rules/:idUpdate a rule
DELETE/regulatory/rules/:idDelete a rule
POST/regulatory/rules/:id/evaluateEvaluate a rule with given inputs
GET/regulatory/variablesList all registered variables
POST/regulatory/variablesRegister a new variable
DELETE/regulatory/variables/:keyDelete a variable

Evaluation

To evaluate a rule:

// POST /regulatory/rules/RUL-001/evaluate
{
"inputs": {
"site.area": 4000,
"site.road_width": 12,
"site.zone": "residential"
}
}

// Response
{
"outputs": {
"result.max_far": 2.5,
"result.max_height": 24,
"result.setback.front": 3,
"result.setback.rear": 2
}
}

The backend traverses the rule graph using math.js for expression evaluation, resolving node dependencies in topological order.