Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dynamic Math Workflow Engine

A powerful and flexible workflow engine built with Node.js, Express, and LangGraph that dynamically executes arithmetic operations based on JSON configuration.

🚀 Features

  • Dynamic Workflow Creation: Define workflows using simple JSON configuration
  • Multiple Operations: Support for Add, Subtract, Multiply, and Divide
  • Node Referencing: Reference previous node results using $nodeId syntax
  • Multiple Operands: Each operation can handle 2 or more values
  • Flexible Variable Names: Use any property names in your data objects
  • RESTful API: Easy-to-use HTTP endpoints
  • Error Handling: Comprehensive error handling and validation
  • Execution Logging: Track each step of the workflow execution

📋 Prerequisites

  • Node.js (v16 or higher)
  • npm or yarn

🛠️ Installation

  1. Clone or create the project directory:
mkdir dynamic-math-workflow
cd dynamic-math-workflow
  1. Initialize the project and install dependencies:
npm init -y
npm install express @langchain/langgraph dotenv cors helmet morgan
npm install -D nodemon
  1. Create the project structure:
mkdir -p src/workflow src/routes src/middleware
  1. Create the following files with the provided code:

Project Structure

dynamic-math-workflow/
├── src/
│   ├── server.js                 # Main Express server
│   ├── workflow/
│   │   ├── workflowEngine.js     # LangGraph workflow logic
│   │   └── operations.js         # Math operations
│   ├── routes/
│   │   └── workflowRoutes.js     # API routes
│   └── middleware/
│       └── errorHandler.js       # Error handling
├── package.json
├── .env
└── README.md
  1. Create .env file:
PORT=3000
NODE_ENV=development
  1. Update package.json scripts:
{
  "type": "module",
  "scripts": {
    "dev": "nodemon src/server.js",
    "start": "node src/server.js"
  }
}

🎮 Usage

Start the Server

Development mode (with auto-reload):

npm run dev

Production mode:

npm start

The server will start on http://localhost:3000

📡 API Endpoints

1. Health Check

GET /api/workflow/health

Check if the server is running.

curl http://localhost:3000/api/workflow/health

Response:

{
  "success": true,
  "message": "Workflow engine is running",
  "timestamp": "2024-01-15T10:30:00.000Z"
}

2. Get Example Workflows

GET /api/workflow/examples

Get pre-defined example workflows.

curl http://localhost:3000/api/workflow/examples

3. Execute Workflow

POST /api/workflow/execute

Execute a custom workflow.

Request Body:

{
  "name": "Workflow Name",
  "description": "Optional description",
  "nodes": [
    {
      "id": "unique_node_id",
      "type": "add|subtract|multiply|divide",
      "data": {
        "variableName1": value,
        "variableName2": "$referenceNodeId"
      }
    }
  ],
  "edges": [
    {
      "source": "START",
      "target": "node_id"
    }
  ]
}

Response:

{
  "success": true,
  "finalResult": 27,
  "results": {
    "node1": 15,
    "node2": 30,
    "node3": 27
  },
  "executionLog": [
    "node1: 10 + 5 = 15",
    "node2: 15 × 2 = 30",
    "node3: 30 - 3 = 27",
    "Final Result: 27"
  ]
}

📚 Examples

Example 1: Simple Addition

curl -X POST http://localhost:3000/api/workflow/execute \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Simple Addition",
    "description": "10 + 5 = 15",
    "nodes": [
      {
        "id": "add_node",
        "type": "add",
        "data": { "a": 10, "b": 5 }
      }
    ],
    "edges": [
      { "source": "START", "target": "add_node" },
      { "source": "add_node", "target": "END" }
    ]
  }'

Example 2: Chained Operations (10 + 5) * 2 - 3 = 27

curl -X POST http://localhost:3000/api/workflow/execute \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Chained Operations",
    "description": "(10 + 5) * 2 - 3 = 27",
    "nodes": [
      {
        "id": "add_node",
        "type": "add",
        "data": { "a": 10, "b": 5 }
      },
      {
        "id": "multiply_node",
        "type": "multiply",
        "data": { "value": "$add_node", "multiplier": 2 }
      },
      {
        "id": "subtract_node",
        "type": "subtract",
        "data": { "minuend": "$multiply_node", "subtrahend": 3 }
      }
    ],
    "edges": [
      { "source": "START", "target": "add_node" },
      { "source": "add_node", "target": "multiply_node" },
      { "source": "multiply_node", "target": "subtract_node" },
      { "source": "subtract_node", "target": "END" }
    ]
  }'

Example 3: Multiple Operands 2 _ 3 _ 4 * 5 = 120

curl -X POST http://localhost:3000/api/workflow/execute \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Multiple Multiplication",
    "description": "2 * 3 * 4 * 5 = 120",
    "nodes": [
      {
        "id": "multiply_all",
        "type": "multiply",
        "data": { "val1": 2, "val2": 3, "val3": 4, "val4": 5 }
      }
    ],
    "edges": [
      { "source": "START", "target": "multiply_all" },
      { "source": "multiply_all", "target": "END" }
    ]
  }'

Example 4: Complex Workflow ((100 - 20) / 4) + 10 = 30

curl -X POST http://localhost:3000/api/workflow/execute \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Complex Calculation",
    "description": "((100 - 20) / 4) + 10 = 30",
    "nodes": [
      {
        "id": "sub_node",
        "type": "subtract",
        "data": { "x": 100, "y": 20 }
      },
      {
        "id": "div_node",
        "type": "divide",
        "data": { "numerator": "$sub_node", "denominator": 4 }
      },
      {
        "id": "add_node",
        "type": "add",
        "data": { "a": "$div_node", "b": 10 }
      }
    ],
    "edges": [
      { "source": "START", "target": "sub_node" },
      { "source": "sub_node", "target": "div_node" },
      { "source": "div_node", "target": "add_node" },
      { "source": "add_node", "target": "END" }
    ]
  }'

🔧 Workflow Configuration

Node Structure

{
  "id": "unique_identifier",        // Unique node ID
  "type": "add|subtract|multiply|divide",  // Operation type
  "data": {
    "param1": 10,                   // Direct value
    "param2": "$previous_node"      // Reference to another node
  }
}

Edge Structure

{
  "source": "START|node_id",        // Source node
  "target": "node_id|END"           // Target node
}

Supported Operations

Operation Type Example Result
Addition add 10 + 5 + 3 18
Subtraction subtract 20 - 5 - 2 13
Multiplication multiply 2 * 3 * 4 24
Division divide 100 / 5 / 2 10

Referencing Previous Nodes

Use the $ prefix to reference results from previous nodes:

{
  "data": {
    "value": "$add_node", // Gets result from add_node
    "multiplier": 2
  }
}

🎯 Key Features Explained

1. Flexible Variable Names

You can use any property names in your data objects:

{
  "data": {
    "firstNumber": 10,
    "secondNumber": 5
  }
}

or

{
  "data": {
    "x": 10,
    "y": 5
  }
}

2. Multiple Operands

Operations support 2 or more values:

{
  "data": {
    "val1": 2,
    "val2": 3,
    "val3": 4,
    "val4": 5
  }
}

3. Node Chaining

Reference previous node results to create complex workflows:

{
  "nodes": [
    { "id": "step1", "type": "add", "data": { "a": 10, "b": 5 } },
    {
      "id": "step2",
      "type": "multiply",
      "data": { "value": "$step1", "by": 2 }
    }
  ]
}

🛡️ Error Handling

The API provides comprehensive error handling:

Validation Errors

{
  "success": false,
  "error": "Invalid workflow configuration: nodes array is required"
}

Execution Errors

{
  "success": false,
  "error": "Division by zero"
}

Reference Errors

{
  "success": false,
  "error": "Referenced node \"unknown_node\" not found or not executed yet"
}

🧪 Testing

Using curl

# Test health endpoint
curl http://localhost:3000/api/workflow/health

# Execute a workflow
curl -X POST http://localhost:3000/api/workflow/execute \
  -H "Content-Type: application/json" \
  -d @workflow.json

Using Postman

  1. Import the collection
  2. Set the base URL to http://localhost:3000
  3. Use the POST /api/workflow/execute endpoint
  4. Add your JSON workflow in the body

Using JavaScript/Fetch

fetch("http://localhost:3000/api/workflow/execute", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Test Workflow",
    nodes: [{ id: "add", type: "add", data: { a: 10, b: 5 } }],
    edges: [
      { source: "START", target: "add" },
      { source: "add", target: "END" },
    ],
  }),
})
  .then((res) => res.json())
  .then((data) => console.log(data));

📊 Response Format

All successful workflow executions return:

{
  "success": true,
  "finalResult": 27,
  "results": {
    "node1": 15,
    "node2": 30,
    "node3": 27
  },
  "executionLog": [
    "node1: 10 + 5 = 15",
    "node2: 15 × 2 = 30",
    "node3: 30 - 3 = 27",
    "Final Result: 27"
  ]
}

🔐 Security

The application includes:

  • Helmet.js for security headers
  • CORS enabled
  • Input validation
  • Error message sanitization

🚀 Deployment

Deploy to Heroku

# Install Heroku CLI
# Login to Heroku
heroku login

# Create app
heroku create your-app-name

# Push code
git push heroku main

# Open app
heroku open

Deploy to Railway

  1. Push code to GitHub
  2. Connect Railway to your repository
  3. Deploy automatically

Deploy to Render

  1. Connect your GitHub repository
  2. Set build command: npm install
  3. Set start command: npm start

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📝 License

This project is licensed under the MIT License.

👨‍💻 Author

Created with ❤️ using Node.js, Express, and LangGraph

🆘 Support

For issues, questions, or suggestions, please open an issue on GitHub.

🔗 Links


Happy Computing! 🎉

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages