Skip to content

RuleCraft is a flexible rule engine that utilizes Abstract Syntax Trees (AST) to evaluate user eligibility based on attributes like age, department, and income. Its 3-tier architecture supports easy creation and modification of rules through a simple UI, API, and backend for efficient decision-making.

License

Notifications You must be signed in to change notification settings

Satyamkumarnavneet/RuleCraft

Repository files navigation

RuleCraft: Advanced Rule Engine with AST

RuleCraft is a flexible rule engine designed to evaluate user eligibility based on various attributes such as age, department, and income. Utilizing Abstract Syntax Trees (AST), this application supports a modern 3-tier architecture that enables efficient creation, combination, and evaluation of complex business rules.

Table of Contents

🌟 Key Features

  • Dynamic Rule Creation: Build complex rules using an intuitive UI
  • AST-Based Evaluation: Efficient rule processing using Abstract Syntax Trees
  • Rule Combination: Merge multiple rules with smart optimization
  • Real-time Validation: Instant feedback on rule syntax and structure
  • Attribute Catalog: Pre-defined set of valid attributes for rule creation
  • User-Friendly Interface: Modern, responsive design for easy rule management

πŸš€ Technologies Used

  • Frontend: React, TypeScript, Tailwind CSS
  • Backend: Node.js, Express.js
  • Database: MongoDB
  • Testing: Postman

πŸ— Architecture

RuleCraft follows a robust 3-tier architecture:

β”œβ”€β”€ Frontend (React + TypeScript)
β”‚   β”œβ”€β”€ Rule Builder UI
β”‚   β”œβ”€β”€ Rule Visualization
β”‚   └── Results Dashboard
β”‚
β”œβ”€β”€ API Layer (Express.js)
β”‚   β”œβ”€β”€ Rule Management
β”‚   β”œβ”€β”€ Evaluation Engine
β”‚   └── Combination Logic
β”‚
└── Data Layer (MongoDB)
    β”œβ”€β”€ Rule Storage
    β”œβ”€β”€ User Data
    └── Evaluation History

Repository Structure

RuleCraft/
β”œβ”€β”€ server/                  # Backend code
β”‚   β”œβ”€β”€ models/             # Database models
β”‚   β”‚   └── Rule.js
β”‚   β”œβ”€β”€ routes/             # API routes
β”‚   β”‚   └── rules.js
β”‚   β”œβ”€β”€ controllers/        # Request handling logic
β”‚   β”œβ”€β”€ utils/             # Utility functions
β”‚   β”‚   └── ruleEngine.js
β”‚   β”œβ”€β”€ config/            # Configuration files
β”‚   └── index.js           # Entry point
β”‚
β”œβ”€β”€ src/                    # Frontend code
β”‚   β”œβ”€β”€ components/        # React components
β”‚   β”‚   β”œβ”€β”€ Dashboard.tsx
β”‚   β”‚   β”œβ”€β”€ Navbar.tsx
β”‚   β”‚   β”œβ”€β”€ RuleList.tsx
β”‚   β”‚   β”œβ”€β”€ RuleCreator.tsx
β”‚   β”‚   β”œβ”€β”€ RuleEvaluator.tsx
β”‚   β”‚   └── RuleCombiner.tsx
β”‚   β”œβ”€β”€ pages/            # Page components
β”‚   β”œβ”€β”€ utils/            # Frontend utilities
β”‚   β”œβ”€β”€ App.tsx           # Main application
β”‚   └── index.tsx         # Entry point
β”‚
β”œβ”€β”€ .gitignore            # Git ignore rules
β”œβ”€β”€ package.json          # Dependencies
β”œβ”€β”€ tsconfig.json         # TypeScript config
β”œβ”€β”€ vite.config.ts        # Vite configuration
└── README.md             # Documentation

πŸ’» Implementation Details

Backend Implementation

Rule Model (models/Rule.js)

const RuleSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    unique: true,
  },
  expression: {
    type: String,
    required: true,
  },
  ast: {
    type: Object,
    required: true,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
  updatedAt: {
    type: Date,
    default: Date.now,
  }
});

Rule Engine (utils/ruleEngine.js)

// Create a new rule
export function createRule(ruleString) {
  const cleanedString = ruleString.replace(/\s+/g, ' ').trim();
  const jsExpression = cleanedString
    .replace(/AND/g, '&&')
    .replace(/OR/g, '||')
    .replace(/(\w+)\s*=\s*'(\w+)'/g, "$1 === '$2'");
  
  const ast = parse(jsExpression);
  return ast.body[0].expression;
}

// Combine multiple rules
export function combineRules(rules) {
  return rules.reduce((combined, rule) => ({
    type: 'LogicalExpression',
    operator: '&&',
    left: combined,
    right: rule
  }));
}

// Evaluate a rule
export function evaluateRule(ast, data) {
  function evaluate(node) {
    switch (node.type) {
      case 'BinaryExpression':
        const left = evaluate(node.left);
        const right = evaluate(node.right);
        return performOperation(node.operator, left, right);
      case 'LogicalExpression':
        return evaluateLogical(node);
      case 'Identifier':
        return getData(node.name);
      case 'Literal':
        return node.value;
    }
  }
  return evaluate(ast);
}

Frontend Implementation

App Component (App.tsx)

function App() {
  return (
    <Router>
      <div className="min-h-screen bg-gray-100">
        <Navbar />
        <div className="container mx-auto px-4 py-8">
          <Routes>
            <Route path="/" element={<Dashboard />} />
            <Route path="/rules" element={<RuleList />} />
            <Route path="/create" element={<RuleCreator />} />
            <Route path="/evaluate" element={<RuleEvaluator />} />
            <Route path="/combine" element={<RuleCombiner />} />
          </Routes>
        </div>
      </div>
    </Router>
  );
}

πŸš€ Getting Started

Prerequisites

  • Node.js (v18 or higher)
  • MongoDB (v6.0 or higher)
  • npm or yarn

Installation

  1. Clone the repository:

    git clone https://github.com/Satyamkumarnavneet/rulecraft.git
    cd rulecraft
  2. Install dependencies:

    npm install
  3. Start the Backend Server:

    node server/index.js
  4. Start the Frontend Development Server:

    npm run dev
  5. Open or click on the link: http://127.0.0.1:5173/

    Screenshot of the application

πŸ”Œ API Endpoints

Rule Management

// Get all rules
GET /api/rules

// Create a new rule
POST /api/rules
Body: {
  "name": "SalesRule",
  "expression": "(age > 30 AND department = 'Sales') OR salary > 50000"
}

// Delete a rule
DELETE /api/rules/:id

// Evaluate a rule
POST /api/evaluate
Body: {
  "ruleId": "rule123",
  "userData": {
    "age": 35,
    "department": "Sales",
    "salary": 60000
  }
}

// Combine rules
POST /api/combine-rules
Body: {
  "ruleIds": ["rule1ID", "rule2ID"],
  "name": "CombinedRule"
}

πŸ“Š Data Structures

Rule Node

interface RuleNode {
  type: "operator" | "condition";
  operator?: "AND" | "OR" | ">" | "<" | "=" | ">=";
  field?: string;
  value?: any;
  left?: RuleNode;
  right?: RuleNode;
}

Sample Rules

// Rule 1: Sales and Marketing Rule
const rule1 = "((age > 30 AND department = 'Sales') OR (age < 25 AND department = 'Marketing')) AND (salary > 50000 OR experience > 5)";

// Rule 2: Marketing Experience Rule
const rule2 = "((age > 30 AND department = 'Marketing')) AND (salary > 20000 OR experience > 5)";

πŸ›  Advanced Features

  • Rule Templates: Pre-defined rule patterns for common use cases
  • Version Control: Track changes in rules over time
  • Batch Evaluation: Process multiple records efficiently
  • Custom Functions: Support for user-defined evaluation functions
  • Rule Export/Import: Share rules across systems

πŸ§ͺ Testing with Postman

You can find the Postman documentation for the RuleCraft API https://documenter.getpostman.com/view/16476251/2sAY4rDPzX.

Screenshots

1. Home

Combine Rules

2. Get All Rules

Evaluate Rule

3. Create a New Rule

Create New Rule

4. Evaluate a Rule

Get All Rules

5. Combine Rules

Home

πŸ“ˆ Performance

  • Optimized AST traversal
  • Caching for frequently used rules
  • Batch processing capabilities
  • Response time < 100ms for standard rules

🀝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“ License

This project is licensed under the Apache License - see the LICENSE file for details.

πŸ“ž Support

For support, email navneetsatyamkumar@gmail.com.


About

RuleCraft is a flexible rule engine that utilizes Abstract Syntax Trees (AST) to evaluate user eligibility based on attributes like age, department, and income. Its 3-tier architecture supports easy creation and modification of rules through a simple UI, API, and backend for efficient decision-making.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published