{
  "id": "JWY2O76qzgXzPbXy",
  "name": "Multi-agent property CAPEX forecasting with ROI simulation",
  "tags": [],
  "nodes": [
    {
      "id": "e354d6b0-e30f-4355-8bd3-c374287052c8",
      "name": "Weekly Maintenance Analysis",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        256,
        496
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 6
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "234fab3b-6ca2-47a1-9e0e-08654a0359d6",
      "name": "Get Maintenance Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        480,
        304
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "range": "A:Z",
              "rangeDefinition": "specifyRangeA1"
            }
          }
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Maintenance History"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "9c1c7be0-29ea-41cb-ac23-8e8399164f2a",
      "name": "Get Property Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        480,
        496
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "range": "A:Z",
              "rangeDefinition": "specifyRangeA1"
            }
          }
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Property Details"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "037134fb-2c90-45c0-af40-baf23ba4df05",
      "name": "Get Tenant Feedback",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        480,
        688
      ],
      "parameters": {
        "options": {
          "dataLocationOnSheet": {
            "values": {
              "range": "A:Z",
              "rangeDefinition": "specifyRangeA1"
            }
          }
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Tenant Feedback"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "42fd32e9-c5fd-4e13-92ec-2da3356a8424",
      "name": "Combine All Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        704,
        480
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition",
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "2e83d42f-b1e3-4fa2-ad1a-8c8d3fbd225d",
      "name": "Main Prediction Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1352,
        496
      ],
      "parameters": {
        "text": "={{ $json }}",
        "options": {
          "systemMessage": "You are a predictive maintenance analyst for commercial real estate. Analyze historical maintenance data, property age, and tenant feedback to predict upcoming repair or upgrade needs. Identify patterns, recurring issues, and aging infrastructure that may require attention. Return structured predictions with property ID, predicted issue type, urgency level, estimated timeframe, and reasoning."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "f060400d-8990-4d3e-86fd-ae62446154fb",
      "name": "Main Agent Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        928,
        720
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-4o"
        },
        "options": {
          "temperature": 0.2
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c48eabc5-cb8a-448a-96b6-41a7794b8c53",
      "name": "Prediction Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1920,
        720
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"predictions\": {\n\t\t\t\"type\": \"array\",\n\t\t\t\"items\": {\n\t\t\t\t\"type\": \"object\",\n\t\t\t\t\"properties\": {\n\t\t\t\t\t\"propertyId\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"issueType\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"urgencyLevel\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"estimatedTimeframe\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t},\n\t\t\t\t\t\"estimatedCost\": {\n\t\t\t\t\t\t\"type\": \"number\"\n\t\t\t\t\t},\n\t\t\t\t\t\"reasoning\": {\n\t\t\t\t\t\t\"type\": \"string\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "380b6106-9dfc-4623-98b0-23b9e4f0c5cc",
      "name": "Split Predictions",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2128,
        496
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "predictions"
      },
      "typeVersion": 1
    },
    {
      "id": "027af18b-952d-4f7c-bcbc-0881ad473245",
      "name": "CAPEX Prioritizer Agent",
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "position": [
        1056,
        720
      ],
      "parameters": {
        "text": "={{ $fromAI('prediction', 'The maintenance prediction to prioritize') }}",
        "options": {
          "systemMessage": "You are a CAPEX prioritization specialist. Analyze predicted maintenance needs and assign priority scores based on: urgency (safety/compliance), cost-benefit ratio, property value impact, tenant satisfaction impact, and strategic alignment. Return prioritized recommendations with scoring breakdown."
        },
        "toolDescription": "Prioritizes capital expenditure projects based on urgency, cost, ROI potential, and strategic importance. Returns prioritized list with scores and justification."
      },
      "typeVersion": 3
    },
    {
      "id": "4ee61b90-3d44-4127-b6e1-2dd082850a73",
      "name": "CAPEX Agent Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1136,
        928
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-4o"
        },
        "options": {
          "temperature": 0.2
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "f73d99d0-db24-49f6-b750-c349af38c8b8",
      "name": "ROI Simulator Agent",
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "position": [
        1344,
        720
      ],
      "parameters": {
        "text": "={{ $fromAI('project', 'The capital project to analyze for ROI') }}",
        "options": {
          "systemMessage": "You are a financial analyst specializing in real estate ROI modeling. For each capital project, calculate: initial investment, annual operating cost changes, revenue impact, property value appreciation, NPV over 10 years, payback period, and IRR. Use the calculator and code tools for complex calculations."
        },
        "toolDescription": "Generates cost-benefit ROI simulations for capital projects. Calculates NPV, payback period, IRR, and long-term value impact."
      },
      "typeVersion": 3
    },
    {
      "id": "140c8784-1b0e-4d80-b913-07e963c5594d",
      "name": "ROI Agent Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1280,
        928
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-4o"
        },
        "options": {
          "temperature": 0.1
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "ce931892-b3f9-4be3-9fbe-57f31f9a14c6",
      "name": "Quote Requester Agent",
      "type": "@n8n/n8n-nodes-langchain.agentTool",
      "position": [
        1632,
        720
      ],
      "parameters": {
        "text": "={{ $fromAI('project_details', 'The project requiring contractor quotes') }}",
        "options": {
          "systemMessage": "You are a procurement specialist for commercial real estate. Generate detailed contractor quote requests including: project scope, technical specifications, timeline requirements, compliance standards, insurance requirements, and evaluation criteria. Format for professional contractor outreach."
        },
        "toolDescription": "Prepares and formats contractor quote requests with detailed specifications, scope of work, and requirements."
      },
      "typeVersion": 3
    },
    {
      "id": "03f89376-552c-4302-b11f-bcb86ffc3347",
      "name": "Quote Agent Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1712,
        928
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "gpt-4o"
        },
        "options": {
          "temperature": 0.3
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "2fa180b9-8bb4-45a8-b053-4c6957f610c7",
      "name": "Calculator Tool",
      "type": "@n8n/n8n-nodes-langchain.toolCalculator",
      "position": [
        1424,
        928
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "56dd52c0-06b2-4e46-bfcd-4cc4d61f7242",
      "name": "Financial Modeling Tool",
      "type": "@n8n/n8n-nodes-langchain.toolCode",
      "position": [
        1568,
        928
      ],
      "parameters": {
        "language": "python",
        "pythonCode": "# Financial calculator for NPV, IRR, and payback period\n# Input: _query should be a JSON string with parameters\nimport json\n\n# Parse the input query\ntry:\n    params = json.loads(_query)\nexcept:\n    return \"Error: Input must be valid JSON with cash_flows, discount_rate, and initial_investment\"\n\ncash_flows = params.get('cash_flows', [])\ndiscount_rate = params.get('discount_rate', 0.1)\ninitial_investment = params.get('initial_investment', 0)\n\n# Calculate NPV (Net Present Value)\ndef calculate_npv(cash_flows, discount_rate, initial_investment):\n    npv = -initial_investment\n    for i, cf in enumerate(cash_flows):\n        npv += cf / ((1 + discount_rate) ** (i + 1))\n    return npv\n\n# Calculate Payback Period\ndef calculate_payback_period(cash_flows, initial_investment):\n    cumulative = 0\n    for i, cf in enumerate(cash_flows):\n        cumulative += cf\n        if cumulative >= initial_investment:\n            return i + 1 - (cumulative - initial_investment) / cf\n    return None\n\n# Calculate IRR (simplified Newton-Raphson method)\ndef calculate_irr(cash_flows, initial_investment, iterations=100):\n    rate = 0.1\n    for _ in range(iterations):\n        npv = -initial_investment\n        npv_derivative = 0\n        for i, cf in enumerate(cash_flows):\n            period = i + 1\n            npv += cf / ((1 + rate) ** period)\n            npv_derivative -= period * cf / ((1 + rate) ** (period + 1))\n        if abs(npv) < 0.01:\n            return rate\n        if npv_derivative != 0:\n            rate = rate - npv / npv_derivative\n    return rate\n\nnpv = calculate_npv(cash_flows, discount_rate, initial_investment)\npayback = calculate_payback_period(cash_flows, initial_investment)\nirr = calculate_irr(cash_flows, initial_investment)\n\nresult = {\n    \"npv\": round(npv, 2),\n    \"irr\": round(irr * 100, 2) if irr else None,\n    \"payback_period_years\": round(payback, 2) if payback else \"Not achieved\",\n    \"discount_rate\": discount_rate * 100\n}\n\nreturn json.dumps(result)",
        "description": "Performs complex financial calculations including NPV, IRR, payback period, and cash flow projections"
      },
      "typeVersion": 1.3
    },
    {
      "id": "c4bf5227-2c7d-4c65-b09c-0aa6475a2277",
      "name": "Format Results",
      "type": "n8n-nodes-base.set",
      "position": [
        2352,
        496
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "propertyId",
              "type": "string",
              "value": "={{ $json.propertyId }}"
            },
            {
              "id": "id-2",
              "name": "issueType",
              "type": "string",
              "value": "={{ $json.issueType }}"
            },
            {
              "id": "id-3",
              "name": "urgencyLevel",
              "type": "string",
              "value": "={{ $json.urgencyLevel }}"
            },
            {
              "id": "id-4",
              "name": "estimatedTimeframe",
              "type": "string",
              "value": "={{ $json.estimatedTimeframe }}"
            },
            {
              "id": "id-5",
              "name": "estimatedCost",
              "type": "number",
              "value": "={{ $json.estimatedCost }}"
            },
            {
              "id": "id-6",
              "name": "priorityScore",
              "type": "string",
              "value": "={{ $json.priorityScore }}"
            },
            {
              "id": "id-7",
              "name": "roiAnalysis",
              "type": "string",
              "value": "={{ $json.roiAnalysis }}"
            },
            {
              "id": "id-8",
              "name": "quoteRequest",
              "type": "string",
              "value": "={{ $json.quoteRequest }}"
            },
            {
              "id": "id-9",
              "name": "analysisDate",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fc7f22f7-31b0-4d01-9f10-b26c530dc4d7",
      "name": "Save Predictions",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2576,
        400
      ],
      "parameters": {
        "columns": {
          "value": null,
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "Predictions & Analysis"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "da2635e0-b52d-4de4-9693-29524502a477",
      "name": "Update Budgeting System",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2576,
        592
      ],
      "parameters": {
        "url": "<__PLACEHOLDER_VALUE__budgeting_system_api_endpoint__>",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.4
    },
    {
      "id": "33fa73e0-ca00-4639-844a-d21092e4045a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1552,
        -272
      ],
      "parameters": {
        "color": 6,
        "width": 576,
        "height": 368,
        "content": "## Prerequisites\n- Google Sheets account with populated maintenance, property, and tenant data\n- Claude or OpenAI API credentials\n- External budgeting system with a POST-compatible API endpoint\n## Use Cases\n- Weekly CAPEX forecasting for multi-property real estate portfolios\n- Automated ROI modelling for planned renovations or equipment replacement\n## Customization\nAdd more data sources (e.g., IoT sensors, ERP exports). \n## Benefits\nEliminates manual CAPEX spreadsheet work with autonomous AI forecasting."
      },
      "typeVersion": 1
    },
    {
      "id": "237f07c0-7c81-42c1-b2a8-bce3173a28dc",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        928,
        -128
      ],
      "parameters": {
        "width": 528,
        "height": 224,
        "content": "## Setup Steps\n1. Connect Google Sheets credentials to all three read nodes and the Save Predictions node.\n2. Set correct Sheet IDs for maintenance, property, and tenant feedback tabs.\n3. Add Claude or OpenAI API credentials to all Chat Model nodes.\n4. Configure the Financial Modeling Tool with your cost rate assumptions.\n5. Replace the POST placeholder URL in Update Budgeting System with your actual endpoint."
      },
      "typeVersion": 1
    },
    {
      "id": "59891292-27bd-4419-9907-ca957c154b5f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        -160
      ],
      "parameters": {
        "width": 640,
        "height": 288,
        "content": "## How It Works\nThis workflow automates weekly capital expenditure (CAPEX) forecasting for property portfolios using a multi-agent AI architecture. It targets property managers, asset managers, and facilities finance teams who need data-driven maintenance budgeting without manual spreadsheet analysis. Three Google Sheets sources, namely: maintenance records, property data, and tenant feedback, are merged into a unified dataset. A Main Prediction Agent orchestrates three specialist sub-agents: a CAPEX Prioritizer that ranks spending needs, an ROI Simulator that models return scenarios, and a Quote Requester that fetches vendor estimates. Each agent is backed by dedicated AI models, memory, and tools including a Calculator and Financial Modeling Tool. Structured predictions are parsed, split by category, formatted, saved back to Google Sheets, and pushed to an external budgeting system via POST, delivering a fully automated, auditable CAPEX planning pipeline every week."
      },
      "typeVersion": 1
    },
    {
      "id": "b6f8be48-e5ba-4909-8261-3845c00c5a97",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 848,
        "content": "## Data Combination\n**What:** Merges three data streams into one unified payload.\n**Why:** Prevents fragmented analysis across disconnected sources."
      },
      "typeVersion": 1
    },
    {
      "id": "6cefbb46-f6df-4de6-9b07-3f42d9e23c44",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2080,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 736,
        "content": "## Output Parsing & Formatting\n**What:** Structured output is parsed, split, formatted, and saved to Sheets.\n**Why:** Ensures clean, categorised data ready for downstream consumption."
      },
      "typeVersion": 1
    },
    {
      "id": "c84b306d-bc31-477a-a3e0-bb0d3d9f7c30",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        336
      ],
      "parameters": {
        "color": 7,
        "width": 1184,
        "height": 736,
        "content": "## Main Prediction Agent\n**What:** Orchestrates CAPEX Prioritizer, ROI Simulator, and Quote Requester agents.\n**Why:** Coordinates specialised reasoning in parallel for faster, accurate forecasting."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "603991f8-27a4-458e-81aa-48bf011bf337",
  "connections": {
    "Format Results": {
      "main": [
        [
          {
            "node": "Save Predictions",
            "type": "main",
            "index": 0
          },
          {
            "node": "Update Budgeting System",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculator Tool": {
      "ai_tool": [
        [
          {
            "node": "ROI Simulator Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "ROI Agent Model": {
      "ai_languageModel": [
        [
          {
            "node": "ROI Simulator Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Combine All Data": {
      "main": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Main Agent Model": {
      "ai_languageModel": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "CAPEX Agent Model": {
      "ai_languageModel": [
        [
          {
            "node": "CAPEX Prioritizer Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get Property Data": {
      "main": [
        [
          {
            "node": "Combine All Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Quote Agent Model": {
      "ai_languageModel": [
        [
          {
            "node": "Quote Requester Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split Predictions": {
      "main": [
        [
          {
            "node": "Format Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Tenant Feedback": {
      "main": [
        [
          {
            "node": "Combine All Data",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "ROI Simulator Agent": {
      "ai_tool": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get Maintenance Data": {
      "main": [
        [
          {
            "node": "Combine All Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Main Prediction Agent": {
      "main": [
        [
          {
            "node": "Split Predictions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Quote Requester Agent": {
      "ai_tool": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "CAPEX Prioritizer Agent": {
      "ai_tool": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Financial Modeling Tool": {
      "ai_tool": [
        [
          {
            "node": "ROI Simulator Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Prediction Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Main Prediction Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Maintenance Analysis": {
      "main": [
        [
          {
            "node": "Get Maintenance Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Property Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Tenant Feedback",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}