Skip to content

Latest commit

 

History

History
502 lines (396 loc) · 13.6 KB

File metadata and controls

502 lines (396 loc) · 13.6 KB

Architecture Overview

This document provides a comprehensive overview of the Rule Engine architecture, design decisions, and implementation details.

Table of Contents

System Architecture

High-Level Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        Application Layer                         │
│  ┌─────────────────┐  ┌──────────────────┐  ┌───────────────┐ │
│  │   React Apps    │  │   Node.js Apps   │  │  API Services │ │
│  └────────┬────────┘  └────────┬─────────┘  └───────┬───────┘ │
└───────────┼────────────────────┼─────────────────────┼─────────┘
            │                    │                     │
┌───────────┼────────────────────┼─────────────────────┼─────────┐
│           │         Rule Engine SDK Layer            │         │
│  ┌────────▼────────┐  ┌────────▼─────────┐  ┌──────▼───────┐ │
│  │   UI Builder    │  │   Rule Engine    │  │  Validators  │ │
│  │  (@usex/builder)│  │   (@usex/core)   │  │  & Utils     │ │
│  └─────────────────┘  └──────────────────┘  └──────────────┘ │
└────────────────────────────────────────────────────────────────┘

Component Architecture

Rule Engine Core
├── Services
│   ├── RuleEngine        # Main evaluation engine
│   ├── Evaluator         # Rule evaluation logic
│   ├── Validator         # Rule validation
│   ├── Introspector      # Rule analysis
│   ├── Builder           # Programmatic rule construction
│   └── ObjectDiscovery   # JSONPath utilities
│
├── Operators
│   ├── Comparison        # Basic comparisons
│   ├── String            # String operations
│   ├── Numeric           # Number operations
│   ├── Array             # Array/collection operations
│   ├── Date/Time         # Temporal operations
│   ├── Type              # Type validation
│   └── Custom            # User-defined operators
│
└── Types & Utils
    ├── Rule Types        # Core type definitions
    ├── JSONPath Utils    # Path resolution
    ├── Date Utils        # Date handling
    └── Error Utils       # Error management

Package Structure

Monorepo Organization

Directory Purpose Key Contents
/packages/core Core rule engine Engine, operators, types
/packages/builder React UI components Visual builder, inputs
/apps/web Documentation site Docs, examples, guides
/docs Project documentation Architecture, guides
/scripts Build scripts Automation, tooling

Package Dependencies

graph TD
    A[@usex/rule-engine-builder] --> B[@usex/rule-engine]
    C[React Apps] --> A
    D[Node.js Apps] --> B
    E[API Services] --> B
Loading

Module Structure

// Core Package Exports
export {
  // Main Classes
  RuleEngine,
  ObjectDiscovery,
  
  // Types
  RuleType,
  Condition,
  Constraint,
  EvaluationResult,
  
  // Enums
  OperatorsType,
  ConditionType,
  
  // Utilities
  validateRule,
  introspectRule,
  buildRule
} from '@usex/rule-engine';

// Builder Package Exports
export {
  // Components
  TreeRuleBuilder,
  ModernRuleBuilder,
  RuleEvaluator,
  HistoryViewer,
  
  // Hooks
  useEnhancedRuleStore,
  useFieldDiscovery,
  useKeyboardShortcuts,
  
  // Types
  FieldConfig,
  ThemeConfig
} from '@usex/rule-engine-builder';

Core Components

RuleEngine Service

The main service responsible for rule evaluation:

class RuleEngine {
  // Singleton instance
  private static instance: RuleEngine;
  
  // Mutation system for data preprocessing
  private mutations: Map<string, MutationFunction>;
  
  // Cache for performance
  private cache: Map<string, any>;
  
  // Core methods
  async evaluate<T>(rule: RuleType<T>, criteria: any): Promise<EvaluationResult<T>>;
  validate(rule: RuleType<any>): ValidationResult;
  introspect(rule: RuleType<any>): IntrospectionResult;
  
  // Static API
  static evaluate<T>(...args): Promise<EvaluationResult<T>>;
  static validate(...args): ValidationResult;
  static builder(): RuleBuilder;
}

Evaluator Pipeline

Input Data → Mutations → Validation → Evaluation → Result
     ↓            ↓           ↓            ↓          ↓
  Criteria   Transform   Type Check   Apply Rules  Output

Operator System

Layer Description Example
Registration Operator definition { name: 'equals', evaluate: (a, b) => a === b }
Categorization Logical grouping Comparison, String, Numeric, etc.
Type Safety Input/output types <T>(field: T, value: T) => boolean
Validation Pre-evaluation checks Value type, range, format
Evaluation Actual comparison Field value vs constraint value

Design Patterns

1. Strategy Pattern

Used for operator evaluation:

interface OperatorStrategy {
  evaluate(fieldValue: any, constraintValue: any): boolean;
}

class EqualsOperator implements OperatorStrategy {
  evaluate(fieldValue: any, constraintValue: any): boolean {
    return fieldValue === constraintValue;
  }
}

class OperatorFactory {
  private strategies: Map<string, OperatorStrategy>;
  
  getOperator(type: string): OperatorStrategy {
    return this.strategies.get(type);
  }
}

2. Builder Pattern

For programmatic rule construction:

const rule = RuleEngine.builder()
  .add({
    and: [
      { field: 'age', operator: 'greater-than', value: 18 },
      { field: 'country', operator: 'equals', value: 'US' }
    ],
    result: { allowed: true }
  })
  .default({ allowed: false })
  .build();

3. Observer Pattern

Used in the UI for state management:

class RuleStore {
  private listeners: Set<() => void> = new Set();
  private state: RuleState;
  
  subscribe(listener: () => void) {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }
  
  notify() {
    this.listeners.forEach(listener => listener());
  }
}

4. Command Pattern

For undo/redo functionality:

interface Command {
  execute(): void;
  undo(): void;
}

class UpdateRuleCommand implements Command {
  constructor(
    private store: RuleStore,
    private oldRule: Rule,
    private newRule: Rule
  ) {}
  
  execute() {
    this.store.setRule(this.newRule);
  }
  
  undo() {
    this.store.setRule(this.oldRule);
  }
}

Data Flow

Rule Evaluation Flow

1. Input Reception
   └── Receive rule and criteria
   
2. Mutation Phase
   ├── Apply registered mutations
   └── Transform criteria data
   
3. Validation Phase
   ├── Validate rule structure
   ├── Check operator validity
   └── Verify field paths
   
4. Resolution Phase
   ├── Resolve JSONPath expressions
   ├── Extract field values
   └── Handle nested objects
   
5. Evaluation Phase
   ├── Apply constraints
   ├── Evaluate conditions
   └── Aggregate results
   
6. Result Composition
   └── Return evaluation result

State Management Flow

User Action → Component → Hook → Store → State Update → UI Update
     ↓           ↓         ↓       ↓          ↓            ↓
  Change      Handler   Action  Reducer    New State   Re-render

Performance Architecture

Optimization Strategies

Strategy Implementation Impact
Caching Memoize evaluation results 40% faster for repeated rules
Lazy Evaluation Stop on first failure 60% faster for failing rules
Path Optimization Pre-compile JSONPath 30% faster path resolution
Batch Processing Evaluate multiple items 50% throughput increase
Trust Mode Skip validation 20% faster for trusted rules

Memory Management

class CacheManager {
  private cache: LRUCache<string, any>;
  private maxSize: number = 1000;
  
  set(key: string, value: any) {
    if (this.cache.size >= this.maxSize) {
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey);
    }
    this.cache.set(key, value);
  }
}

Concurrency Model

class BatchEvaluator {
  async evaluateBatch<T>(
    rule: RuleType<T>,
    items: any[],
    concurrency: number = 10
  ): Promise<EvaluationResult<T>[]> {
    const chunks = chunk(items, concurrency);
    const results = [];
    
    for (const chunk of chunks) {
      const chunkResults = await Promise.all(
        chunk.map(item => this.evaluate(rule, item))
      );
      results.push(...chunkResults);
    }
    
    return results;
  }
}

Security Architecture

Input Validation

Layer Protection Implementation
Schema Validation Rule structure JSON Schema validation
Type Checking Data types TypeScript + runtime checks
Path Validation JSONPath safety Whitelist allowed paths
Operator Validation Valid operators Operator registry check
Value Sanitization Input cleaning XSS prevention, type coercion

Security Patterns

class SecurityValidator {
  // Prevent prototype pollution
  validatePath(path: string): boolean {
    const dangerous = ['__proto__', 'constructor', 'prototype'];
    return !dangerous.some(d => path.includes(d));
  }
  
  // Limit complexity
  validateComplexity(rule: RuleType): boolean {
    const depth = this.calculateDepth(rule);
    const conditions = this.countConditions(rule);
    
    return depth <= MAX_DEPTH && conditions <= MAX_CONDITIONS;
  }
  
  // Sanitize regex patterns
  validateRegex(pattern: string): boolean {
    try {
      new RegExp(pattern);
      return !pattern.includes('(?<') && // No lookbehind
             !pattern.includes('{1000,}'); // No large repetitions
    } catch {
      return false;
    }
  }
}

Access Control Integration

interface RuleAccessControl {
  canCreate: (user: User) => boolean;
  canRead: (user: User, rule: Rule) => boolean;
  canUpdate: (user: User, rule: Rule) => boolean;
  canDelete: (user: User, rule: Rule) => boolean;
  canEvaluate: (user: User, rule: Rule) => boolean;
}

class RuleEngineWithACL extends RuleEngine {
  constructor(private acl: RuleAccessControl) {
    super();
  }
  
  async evaluate(rule: RuleType, criteria: any, user: User) {
    if (!this.acl.canEvaluate(user, rule)) {
      throw new Error('Access denied');
    }
    return super.evaluate(rule, criteria);
  }
}

Extension Architecture

Plugin System

interface RuleEnginePlugin {
  name: string;
  version: string;
  
  // Lifecycle hooks
  onInit?(engine: RuleEngine): void;
  beforeEvaluate?(rule: RuleType, criteria: any): void;
  afterEvaluate?(result: EvaluationResult): void;
  
  // Extension points
  operators?: Record<string, OperatorDefinition>;
  mutations?: Record<string, MutationFunction>;
  validators?: Record<string, ValidatorFunction>;
}

class PluginManager {
  private plugins: Map<string, RuleEnginePlugin> = new Map();
  
  register(plugin: RuleEnginePlugin) {
    this.plugins.set(plugin.name, plugin);
    plugin.onInit?.(this.engine);
  }
}

Custom Operator Architecture

interface CustomOperator {
  name: string;
  category: string;
  description: string;
  
  // Type constraints
  acceptedFieldTypes: FieldType[];
  acceptedValueTypes: ValueType[];
  
  // Validation
  validate(value: any): ValidationResult;
  
  // Evaluation
  evaluate(fieldValue: any, constraintValue: any): boolean;
  
  // UI hints
  ui?: {
    icon?: string;
    color?: string;
    inputComponent?: React.ComponentType;
  };
}

Future Architecture Considerations

Scalability

  • Distributed Evaluation: Rule evaluation across multiple workers
  • Rule Compilation: Compile rules to optimized JavaScript
  • Streaming Support: Process data streams with rules
  • Edge Computing: Run rules at the edge for low latency

Extensibility

  • Plugin Marketplace: Community-contributed operators and plugins
  • Rule Templates: Reusable rule patterns
  • AI Integration: ML-powered rule suggestions
  • Visual Debugging: Step-through rule evaluation

For more technical details, see the API Reference.