{
  "workflow": {
    "id": 6626,
    "name": "Analyze property maintenance costs with ScrapeGraphAI and budget planning",
    "views": 361,
    "recentViews": 0,
    "totalViews": 361,
    "createdAt": "2025-07-29T10:59:04.271Z",
    "description": "*This workflow contains community nodes that are only compatible with the self-hosted version of n8n.*\n\n# How it works\n\nThis workflow automatically analyzes property maintenance costs by scraping contractor websites and provides comprehensive budget planning and recommendations.\n\n## Key Steps\n\n1. **Scheduled Trigger** - Runs weekly to update maintenance cost data from multiple sources.\n2. **Multi-Source Scraping** - Uses ScrapeGraphAI to extract service data from plumbing, electrical, and HVAC contractor websites.\n3. **Cost Analysis** - JavaScript nodes process and categorize services by price level and urgency.\n4. **Service Comparison** - Compares providers within each category to find best-rated and most cost-effective options.\n5. **Budget Planning** - Creates annual budget with quarterly breakdown and service scheduling recommendations.\n6. **Property Manager Alerts** - Formats comprehensive reports with budget summaries and actionable recommendations.\n\n## Set up steps\n\n**Setup time: 10-15 minutes**\n\n1. **Configure ScrapeGraphAI credentials** - Add your ScrapeGraphAI API key for web scraping.\n2. **Customize contractor websites** - Update the URLs in the scraping nodes to target specific local contractor directories.\n3. **Adjust schedule frequency** - Modify the trigger timing based on how often you want cost updates.\n4. **Review budget parameters** - Customize the budget planning logic in the JavaScript nodes if needed.\n5. **Test the workflow** - Run manually first to ensure all scraping and analysis nodes work correctly.\n\n## Technologies Used\n\n- **ScrapeGraphAI** - For extracting structured data from contractor websites\n- **JavaScript Code Nodes** - For data processing, cost analysis, and budget planning\n- **Schedule Trigger** - For automated weekly execution\n- **JSON Data Processing** - For structured data handling and analysis\n",
    "workflow": {
      "id": "VhEwspDqzu7ssFVE",
      "meta": {
        "instanceId": "f4b0efaa33080e7774e0d9285c40c7abcd2c6f7cf1a8b901fa7106170dd4cda3",
        "templateCredsSetupCompleted": true
      },
      "name": "My workflow 2",
      "tags": [
        {
          "id": "DxXGubfBzRKh6L8T",
          "name": "Revenue Optimization",
          "createdAt": "2025-07-25T16:24:30.370Z",
          "updatedAt": "2025-07-25T16:24:30.370Z"
        },
        {
          "id": "IxkcJ2IpYIxivoHV",
          "name": "Content Strategy",
          "createdAt": "2025-07-25T12:57:37.677Z",
          "updatedAt": "2025-07-25T12:57:37.677Z"
        },
        {
          "id": "PAKIJ2Mm9EvRcR3u",
          "name": "Trend Monitoring",
          "createdAt": "2025-07-25T12:57:37.670Z",
          "updatedAt": "2025-07-25T12:57:37.670Z"
        },
        {
          "id": "YtfXmaZk44MYedPO",
          "name": "Dynamic Pricing",
          "createdAt": "2025-07-25T16:24:30.369Z",
          "updatedAt": "2025-07-25T16:24:30.369Z"
        },
        {
          "id": "wJ30mjhtrposO8Qt",
          "name": "Simple RAG",
          "createdAt": "2025-07-28T12:55:14.424Z",
          "updatedAt": "2025-07-28T12:55:14.424Z"
        }
      ],
      "nodes": [
        {
          "id": "d983af2a-51ee-49dd-ab37-3930ba3970f8",
          "name": "Schedule Trigger",
          "type": "n8n-nodes-base.scheduleTrigger",
          "position": [
            -1056,
            528
          ],
          "parameters": {
            "rule": {
              "interval": [
                {
                  "field": "weeks"
                }
              ]
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "01feb351-2bd6-4946-bf78-d1152ce14707",
          "name": "ScrapeGraphAI - Plumbing",
          "type": "n8n-nodes-scrapegraphai.scrapegraphAi",
          "position": [
            -656,
            384
          ],
          "parameters": {
            "userPrompt": "Extract plumbing services and costs. Use this schema: {\"service_name\": \"Drain Cleaning\", \"provider_name\": \"ABC Plumbing\", \"price_range\": \"$150-$300\", \"rating\": \"4.5\", \"location\": \"Local Area\", \"phone\": \"555-0123\", \"description\": \"Professional drain cleaning service\", \"provider_url\": \"https://example.com\"}",
            "websiteUrl": "https://www.angi.com/plumbers/"
          },
          "typeVersion": 1
        },
        {
          "id": "da7e50bc-2b5c-4418-a928-d14e95e03768",
          "name": "ScrapeGraphAI - Electrical",
          "type": "n8n-nodes-scrapegraphai.scrapegraphAi",
          "position": [
            -656,
            544
          ],
          "parameters": {
            "userPrompt": "Extract electrical services and costs. Use this schema: {\"service_name\": \"Outlet Installation\", \"provider_name\": \"Electric Pro\", \"price_range\": \"$200-$400\", \"rating\": \"4.8\", \"location\": \"Local Area\", \"phone\": \"555-0456\", \"description\": \"Professional electrical services\", \"provider_url\": \"https://example.com\"}",
            "websiteUrl": "https://www.angi.com/electrical-contractors/"
          },
          "typeVersion": 1
        },
        {
          "id": "ddad669a-9f0a-4dc8-8afb-242c5f55cb67",
          "name": "ScrapeGraphAI - HVAC",
          "type": "n8n-nodes-scrapegraphai.scrapegraphAi",
          "position": [
            -656,
            704
          ],
          "parameters": {
            "userPrompt": "Extract HVAC services and costs. Use this schema: {\"service_name\": \"AC Repair\", \"provider_name\": \"Cool Air HVAC\", \"price_range\": \"$300-$600\", \"rating\": \"4.7\", \"location\": \"Local Area\", \"phone\": \"555-0789\", \"description\": \"HVAC repair and maintenance\", \"provider_url\": \"https://example.com\"}",
            "websiteUrl": "https://www.angi.com/hvac-contractors/"
          },
          "typeVersion": 1
        },
        {
          "id": "52bd4121-25a5-46e5-978a-b31beef1f727",
          "name": "Cost Analyzer",
          "type": "n8n-nodes-base.code",
          "notes": "Analyzes costs and\ncategorizes services\nby price level",
          "position": [
            -256,
            304
          ],
          "parameters": {
            "jsCode": "// Cost Analyzer - Process and analyze maintenance costs\nconst allInputs = $input.all();\nconst currentDate = new Date().toISOString().split('T')[0];\nconst analysisResults = [];\n\n// Process each service category\nallInputs.forEach((input, index) => {\n  const serviceData = input.json;\n  let services = [];\n  \n  // Extract services from different possible structures\n  if (serviceData.result && serviceData.result.services) {\n    services = serviceData.result.services;\n  } else if (serviceData.result && Array.isArray(serviceData.result)) {\n    services = serviceData.result;\n  } else if (Array.isArray(serviceData)) {\n    services = serviceData;\n  }\n  \n  // Determine service category based on input index\n  const categories = ['Plumbing', 'Electrical', 'HVAC'];\n  const category = categories[index] || 'General';\n  \n  services.forEach(service => {\n    if (service && service.service_name) {\n      // Parse price range to get average cost\n      let averageCost = 0;\n      let minCost = 0;\n      let maxCost = 0;\n      \n      if (service.price_range) {\n        const priceMatch = service.price_range.match(/\\$(\\d+)[-–](\\d+)/);\n        if (priceMatch) {\n          minCost = parseInt(priceMatch[1]);\n          maxCost = parseInt(priceMatch[2]);\n          averageCost = (minCost + maxCost) / 2;\n        } else {\n          const singlePrice = service.price_range.match(/\\$(\\d+)/);\n          if (singlePrice) {\n            averageCost = parseInt(singlePrice[1]);\n            minCost = maxCost = averageCost;\n          }\n        }\n      }\n      \n      // Determine cost level\n      let costLevel = 'Medium';\n      if (averageCost < 200) costLevel = 'Low';\n      else if (averageCost > 500) costLevel = 'High';\n      \n      analysisResults.push({\n        date_analyzed: currentDate,\n        category: category,\n        service_name: service.service_name || 'Unknown Service',\n        provider_name: service.provider_name || 'Unknown Provider',\n        price_range: service.price_range || 'Price not available',\n        average_cost: averageCost,\n        min_cost: minCost,\n        max_cost: maxCost,\n        cost_level: costLevel,\n        rating: service.rating || 'No rating',\n        location: service.location || 'Location not specified',\n        phone: service.phone || 'No phone',\n        description: service.description || 'No description',\n        provider_url: service.provider_url || '#',\n        urgency_score: category === 'Plumbing' ? 8 : category === 'Electrical' ? 9 : 6\n      });\n    }\n  });\n});\n\nconsole.log(`Analyzed ${analysisResults.length} services across categories`);\n\nreturn analysisResults.map(result => ({ json: result }));"
          },
          "notesInFlow": true,
          "typeVersion": 2
        },
        {
          "id": "694967bc-86bc-40d8-b73e-8440b93c013a",
          "name": "Service Comparer",
          "type": "n8n-nodes-base.code",
          "notes": "Compares providers\nand finds best\noptions by rating\nand cost",
          "position": [
            48,
            304
          ],
          "parameters": {
            "jsCode": "// Service Comparer - Compare services and find best options\nconst services = $input.all().map(item => item.json);\nconst comparisonResults = [];\nconst serviceGroups = {};\n\n// Group services by category and service name\nservices.forEach(service => {\n  const key = `${service.category}_${service.service_name}`;\n  if (!serviceGroups[key]) {\n    serviceGroups[key] = [];\n  }\n  serviceGroups[key].push(service);\n});\n\n// Compare services within each group\nObject.keys(serviceGroups).forEach(groupKey => {\n  const group = serviceGroups[groupKey];\n  if (group.length > 1) {\n    // Sort by rating and cost\n    const sortedByRating = [...group].sort((a, b) => {\n      const ratingA = parseFloat(a.rating) || 0;\n      const ratingB = parseFloat(b.rating) || 0;\n      return ratingB - ratingA;\n    });\n    \n    const sortedByCost = [...group].sort((a, b) => a.average_cost - b.average_cost);\n    \n    const bestRated = sortedByRating[0];\n    const cheapest = sortedByCost[0];\n    const mostExpensive = sortedByCost[sortedByCost.length - 1];\n    \n    // Calculate price variance\n    const costs = group.map(s => s.average_cost).filter(c => c > 0);\n    const avgGroupCost = costs.length > 0 ? costs.reduce((a, b) => a + b, 0) / costs.length : 0;\n    const priceVariance = costs.length > 1 ? Math.max(...costs) - Math.min(...costs) : 0;\n    \n    comparisonResults.push({\n      service_category: group[0].category,\n      service_name: group[0].service_name,\n      provider_count: group.length,\n      average_market_price: Math.round(avgGroupCost),\n      price_variance: priceVariance,\n      best_rated_provider: {\n        name: bestRated.provider_name,\n        rating: bestRated.rating,\n        price: bestRated.price_range,\n        phone: bestRated.phone\n      },\n      cheapest_provider: {\n        name: cheapest.provider_name,\n        rating: cheapest.rating,\n        price: cheapest.price_range,\n        phone: cheapest.phone\n      },\n      most_expensive_provider: {\n        name: mostExpensive.provider_name,\n        rating: mostExpensive.rating,\n        price: mostExpensive.price_range,\n        phone: mostExpensive.phone\n      },\n      recommendation: bestRated.provider_name === cheapest.provider_name ? \n        'Best Value (High Rating + Low Cost)' : \n        parseFloat(bestRated.rating) > 4.5 ? 'Quality Focus' : 'Cost Focus',\n      all_providers: group\n    });\n  } else {\n    // Single provider for this service\n    const service = group[0];\n    comparisonResults.push({\n      service_category: service.category,\n      service_name: service.service_name,\n      provider_count: 1,\n      average_market_price: service.average_cost,\n      price_variance: 0,\n      single_provider: {\n        name: service.provider_name,\n        rating: service.rating,\n        price: service.price_range,\n        phone: service.phone\n      },\n      recommendation: 'Single Option Available',\n      all_providers: [service]\n    });\n  }\n});\n\nconsole.log(`Created comparisons for ${comparisonResults.length} service types`);\n\nreturn comparisonResults.map(result => ({ json: result }));"
          },
          "notesInFlow": true,
          "typeVersion": 2
        },
        {
          "id": "866b42f0-4b11-493c-bfd9-031dfb32d30a",
          "name": "Budget Planner",
          "type": "n8n-nodes-base.code",
          "notes": "Creates annual\nbudget plan with\nquarterly breakdown\nand recommendations",
          "position": [
            352,
            304
          ],
          "parameters": {
            "jsCode": "// Budget Planner - Create maintenance budget and scheduling recommendations\nconst comparisons = $input.all().map(item => item.json);\nconst currentDate = new Date();\nconst currentMonth = currentDate.getMonth() + 1;\nconst currentYear = currentDate.getFullYear();\n\n// Define maintenance categories and typical frequencies\nconst maintenanceSchedule = {\n  'HVAC': { frequency: 'biannual', urgency: 'high', typical_cost: 400 },\n  'Plumbing': { frequency: 'annual', urgency: 'medium', typical_cost: 300 },\n  'Electrical': { frequency: 'biannual', urgency: 'high', typical_cost: 350 }\n};\n\n// Create budget recommendations\nconst budgetPlan = {\n  planning_date: currentDate.toISOString().split('T')[0],\n  budget_year: currentYear,\n  quarterly_budgets: [],\n  annual_summary: {\n    total_estimated_cost: 0,\n    high_priority_services: [],\n    medium_priority_services: [],\n    low_priority_services: []\n  },\n  service_recommendations: [],\n  cost_optimization_tips: []\n};\n\n// Process each service comparison\ncomparisons.forEach(comparison => {\n  const category = comparison.service_category;\n  const schedule = maintenanceSchedule[category] || { frequency: 'annual', urgency: 'medium', typical_cost: 250 };\n  \n  // Determine priority based on service type and cost\n  let priority = 'Medium';\n  if (category === 'Electrical' || category === 'HVAC') priority = 'High';\n  if (comparison.average_market_price > 500) priority = 'High';\n  if (comparison.average_market_price < 200) priority = 'Low';\n  \n  const recommendation = {\n    service: comparison.service_name,\n    category: category,\n    priority: priority,\n    estimated_annual_cost: comparison.average_market_price,\n    recommended_frequency: schedule.frequency,\n    best_provider: comparison.best_rated_provider || comparison.single_provider,\n    budget_provider: comparison.cheapest_provider || comparison.single_provider,\n    next_service_month: schedule.frequency === 'biannual' ? \n      [3, 9] : schedule.frequency === 'quarterly' ? [3, 6, 9, 12] : [6],\n    cost_savings_potential: comparison.price_variance || 0\n  };\n  \n  budgetPlan.service_recommendations.push(recommendation);\n  budgetPlan.annual_summary.total_estimated_cost += comparison.average_market_price;\n  \n  // Categorize by priority\n  if (priority === 'High') {\n    budgetPlan.annual_summary.high_priority_services.push(recommendation);\n  } else if (priority === 'Medium') {\n    budgetPlan.annual_summary.medium_priority_services.push(recommendation);\n  } else {\n    budgetPlan.annual_summary.low_priority_services.push(recommendation);\n  }\n});\n\n// Create quarterly budget breakdown\nfor (let quarter = 1; quarter <= 4; quarter++) {\n  const quarterMonths = [(quarter - 1) * 3 + 1, (quarter - 1) * 3 + 2, (quarter - 1) * 3 + 3];\n  let quarterBudget = 0;\n  const quarterServices = [];\n  \n  budgetPlan.service_recommendations.forEach(rec => {\n    rec.next_service_month.forEach(month => {\n      if (quarterMonths.includes(month)) {\n        quarterBudget += rec.estimated_annual_cost;\n        quarterServices.push({\n          service: rec.service,\n          month: month,\n          cost: rec.estimated_annual_cost,\n          provider: rec.best_provider.name\n        });\n      }\n    });\n  });\n  \n  budgetPlan.quarterly_budgets.push({\n    quarter: quarter,\n    months: quarterMonths,\n    total_budget: quarterBudget,\n    services: quarterServices\n  });\n}\n\n// Add cost optimization tips\nbudgetPlan.cost_optimization_tips = [\n  'Bundle multiple services with the same provider for discounts',\n  'Schedule preventive maintenance to avoid emergency repairs',\n  'Get multiple quotes for expensive services (>$500)',\n  'Consider seasonal pricing - HVAC services may be cheaper in off-season',\n  'Join service contracts for regular maintenance at reduced rates'\n];\n\n// Calculate budget metrics\nbudgetPlan.annual_summary.monthly_average = Math.round(budgetPlan.annual_summary.total_estimated_cost / 12);\nbudgetPlan.annual_summary.high_priority_cost = budgetPlan.annual_summary.high_priority_services\n  .reduce((sum, service) => sum + service.estimated_annual_cost, 0);\nbudgetPlan.annual_summary.potential_savings = budgetPlan.service_recommendations\n  .reduce((sum, rec) => sum + rec.cost_savings_potential, 0);\n\nconsole.log(`Created budget plan with total estimated cost: $${budgetPlan.annual_summary.total_estimated_cost}`);\n\nreturn [{ json: budgetPlan }];"
          },
          "notesInFlow": true,
          "typeVersion": 2
        },
        {
          "id": "027966fe-cee6-445e-a839-61333bb31e98",
          "name": "Property Manager Alert",
          "type": "n8n-nodes-base.code",
          "notes": "Formats comprehensive\nalert for property\nmanager with budget\nanalysis and recommendations",
          "position": [
            640,
            304
          ],
          "parameters": {
            "jsCode": "// Property Manager Alert - Format comprehensive maintenance report\nconst budgetData = $input.all()[0].json;\nconst currentDate = new Date().toLocaleDateString();\nconst currentTime = new Date().toLocaleTimeString();\n\n// Create formatted alert message\nfunction formatCurrency(amount) {\n  return new Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n    minimumFractionDigits: 0\n  }).format(amount);\n}\n\nfunction createMaintenanceAlert() {\n  const { annual_summary, quarterly_budgets, service_recommendations } = budgetData;\n  \n  let alertMessage = `🏠 **PROPERTY MAINTENANCE COST ANALYSIS**\\n`;\n  alertMessage += `📅 Generated: ${currentDate} at ${currentTime}\\n\\n`;\n  \n  // Annual Summary\n  alertMessage += `💰 **ANNUAL BUDGET SUMMARY**\\n`;\n  alertMessage += `• Total Estimated Cost: ${formatCurrency(annual_summary.total_estimated_cost)}\\n`;\n  alertMessage += `• Monthly Average: ${formatCurrency(annual_summary.monthly_average)}\\n`;\n  alertMessage += `• Potential Savings: ${formatCurrency(annual_summary.potential_savings)}\\n\\n`;\n  \n  // Priority Breakdown\n  alertMessage += `🚨 **SERVICE PRIORITIES**\\n`;\n  alertMessage += `• High Priority: ${annual_summary.high_priority_services.length} services (${formatCurrency(annual_summary.high_priority_cost)})\\n`;\n  alertMessage += `• Medium Priority: ${annual_summary.medium_priority_services.length} services\\n`;\n  alertMessage += `• Low Priority: ${annual_summary.low_priority_services.length} services\\n\\n`;\n  \n  // Quarterly Breakdown\n  alertMessage += `📊 **QUARTERLY BUDGET BREAKDOWN**\\n`;\n  quarterly_budgets.forEach(quarter => {\n    if (quarter.total_budget > 0) {\n      alertMessage += `Q${quarter.quarter}: ${formatCurrency(quarter.total_budget)} (${quarter.services.length} services)\\n`;\n    }\n  });\n  alertMessage += `\\n`;\n  \n  // Top Service Recommendations\n  alertMessage += `🔧 **TOP SERVICE RECOMMENDATIONS**\\n`;\n  const topServices = service_recommendations\n    .filter(rec => rec.priority === 'High')\n    .slice(0, 5);\n    \n  topServices.forEach((service, index) => {\n    alertMessage += `${index + 1}. **${service.service}** (${service.category})\\n`;\n    alertMessage += `   • Cost: ${formatCurrency(service.estimated_annual_cost)}\\n`;\n    alertMessage += `   • Provider: ${service.best_provider.name}\\n`;\n    alertMessage += `   • Rating: ${service.best_provider.rating}\\n`;\n    alertMessage += `   • Phone: ${service.best_provider.phone}\\n\\n`;\n  });\n  \n  // Cost Optimization Tips\n  alertMessage += `💡 **COST OPTIMIZATION TIPS**\\n`;\n  budgetData.cost_optimization_tips.slice(0, 3).forEach((tip, index) => {\n    alertMessage += `${index + 1}. ${tip}\\n`;\n  });\n  \n  alertMessage += `\\n━━━━━━━━━━━━━━━━━━━━━━\\n`;\n  alertMessage += `📈 **Next Update**: Next week\\n`;\n  alertMessage += `🔄 **Data Source**: Multiple contractor websites\\n`;\n  \n  return alertMessage;\n}\n\n// Create summary for property management system\nfunction createSystemSummary() {\n  return {\n    alert_type: 'maintenance_cost_analysis',\n    severity: 'info',\n    property_count: 1, // Adjust based on actual properties\n    total_annual_budget: budgetData.annual_summary.total_estimated_cost,\n    high_priority_count: budgetData.annual_summary.high_priority_services.length,\n    next_quarter_budget: budgetData.quarterly_budgets[0]?.total_budget || 0,\n    top_expense_category: budgetData.service_recommendations\n      .reduce((max, current) => \n        current.estimated_annual_cost > max.estimated_annual_cost ? current : max\n      ).category,\n    generated_at: new Date().toISOString(),\n    recommendations_count: budgetData.service_recommendations.length\n  };\n}\n\nconst alertMessage = createMaintenanceAlert();\nconst systemSummary = createSystemSummary();\n\nconsole.log(`Generated property manager alert with ${budgetData.service_recommendations.length} service recommendations`);\n\nreturn [\n  {\n    json: {\n      message_text: alertMessage,\n      system_summary: systemSummary,\n      full_budget_data: budgetData,\n      alert_timestamp: new Date().toISOString(),\n      requires_action: budgetData.annual_summary.high_priority_services.length > 0\n    }\n  }\n];"
          },
          "notesInFlow": true,
          "typeVersion": 2
        },
        {
          "id": "ad11589e-d46d-4bcb-8a12-cdde5d10ceb2",
          "name": "Sticky Note - Trigger",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            -1200,
            -160
          ],
          "parameters": {
            "color": 5,
            "width": 400,
            "height": 1036,
            "content": "# Step 1: Weekly Schedule Trigger ⏰\n\nTriggers the workflow every week to update maintenance cost data.\n\n## Configuration\n- Set to run weekly (every 7 days)\n- Customize time of day as needed\n- Can change to different intervals"
          },
          "typeVersion": 1
        },
        {
          "id": "5ab406ac-6e07-4bd2-b393-745f23a14372",
          "name": "Sticky Note - Scraping",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            -800,
            -160
          ],
          "parameters": {
            "color": 5,
            "width": 400,
            "height": 1040,
            "content": "# Step 2: Multi-Source Scraping 🤖\n\nThree ScrapeGraphAI nodes scrape different contractor categories:\n\n- **Plumbing Services**: Drain cleaning, pipe repair, etc.\n- **Electrical Services**: Outlet installation, wiring, etc.\n- **HVAC Services**: AC repair, heating maintenance, etc.\n\n## What it extracts\n- Service names and descriptions\n- Provider details and ratings\n- Price ranges and contact info"
          },
          "typeVersion": 1
        },
        {
          "id": "4c5d33d2-3c00-4bcb-a4c4-023bfdd51f9b",
          "name": "Sticky Note - Analysis",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            -400,
            -160
          ],
          "parameters": {
            "color": 5,
            "width": 400,
            "height": 1040,
            "content": "# Step 3: Cost Analysis & Comparison 📊\n\n**Cost Analyzer**: Processes scraped data and calculates average costs, cost levels, and urgency scores.\n\n**Service Comparer**: Compares providers within each service category to find:\n- Best rated providers\n- Most cost-effective options\n- Price variance analysis\n\n## Output\n- Categorized cost analysis\n- Provider comparisons\n- Recommendation logic"
          },
          "typeVersion": 1
        },
        {
          "id": "9f34b893-579d-4ccd-85ac-9113905e4db9",
          "name": "Sticky Note - Planning",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            0,
            -160
          ],
          "parameters": {
            "color": 5,
            "width": 832,
            "height": 1040,
            "content": "# Step 4: Budget Planning & Alerts 💰\n\n**Budget Planner**: Creates comprehensive annual budget with:\n- Quarterly budget breakdown\n- Service scheduling recommendations\n- Cost optimization strategies\n- Priority-based planning\n\n**Property Manager Alert**: Formats results into actionable alerts with:\n- Budget summaries\n- High-priority services\n- Provider recommendations\n- Cost-saving tips"
          },
          "typeVersion": 1
        }
      ],
      "active": false,
      "pinData": {},
      "settings": {
        "executionOrder": "v1"
      },
      "versionId": "f6d045df-1c7e-4a0d-a03a-89745d18f990",
      "connections": {
        "Cost Analyzer": {
          "main": [
            [
              {
                "node": "Service Comparer",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Budget Planner": {
          "main": [
            [
              {
                "node": "Property Manager Alert",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Schedule Trigger": {
          "main": [
            [
              {
                "node": "ScrapeGraphAI - Plumbing",
                "type": "main",
                "index": 0
              },
              {
                "node": "ScrapeGraphAI - Electrical",
                "type": "main",
                "index": 0
              },
              {
                "node": "ScrapeGraphAI - HVAC",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Service Comparer": {
          "main": [
            [
              {
                "node": "Budget Planner",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "ScrapeGraphAI - HVAC": {
          "main": [
            [
              {
                "node": "Cost Analyzer",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "ScrapeGraphAI - Plumbing": {
          "main": [
            [
              {
                "node": "Cost Analyzer",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "ScrapeGraphAI - Electrical": {
          "main": [
            [
              {
                "node": "Cost Analyzer",
                "type": "main",
                "index": 0
              }
            ]
          ]
        }
      }
    },
    "lastUpdatedBy": 62,
    "workflowInfo": {
      "nodeCount": 12,
      "nodeTypes": {
        "n8n-nodes-base.code": {
          "count": 4
        },
        "n8n-nodes-base.stickyNote": {
          "count": 4
        },
        "n8n-nodes-base.scheduleTrigger": {
          "count": 1
        },
        "n8n-nodes-scrapegraphai.scrapegraphAi": {
          "count": 3
        }
      }
    },
    "status": "published",
    "user": {
      "name": "vinci-king-01",
      "username": "vinci-king-01",
      "bio": "",
      "verified": true,
      "links": [
        "https://www.linkedin.com/in/marco-vinciguerra-7ba365242/"
      ],
      "avatar": "https://gravatar.com/avatar/d939eeef03a5fcb5df08bee8196f12ccb248c38209487414e419032004f0c014?r=pg&d=retro&size=200"
    },
    "nodes": [
      {
        "id": 565,
        "icon": "fa:sticky-note",
        "name": "n8n-nodes-base.stickyNote",
        "codex": {
          "data": {
            "alias": [
              "Comments",
              "Notes",
              "Sticky"
            ],
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers"
              ]
            }
          }
        },
        "group": "[\"input\"]",
        "defaults": {
          "name": "Sticky Note",
          "color": "#FFD233"
        },
        "iconData": {
          "icon": "sticky-note",
          "type": "icon"
        },
        "displayName": "Sticky Note",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 834,
        "icon": "file:code.svg",
        "name": "n8n-nodes-base.code",
        "codex": {
          "data": {
            "alias": [
              "cpde",
              "Javascript",
              "JS",
              "Python",
              "Script",
              "Custom Code",
              "Function"
            ],
            "details": "The Code node allows you to execute JavaScript in your workflow.",
            "resources": {
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"
                }
              ]
            },
            "categories": [
              "Development",
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0",
            "subcategories": {
              "Core Nodes": [
                "Helpers",
                "Data Transformation"
              ]
            }
          }
        },
        "group": "[\"transform\"]",
        "defaults": {
          "name": "Code"
        },
        "iconData": {
          "type": "file",
          "fileBuffer": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="
        },
        "displayName": "Code",
        "typeVersion": 2,
        "nodeCategories": [
          {
            "id": 5,
            "name": "Development"
          },
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      },
      {
        "id": 839,
        "icon": "fa:clock",
        "name": "n8n-nodes-base.scheduleTrigger",
        "codex": {
          "data": {
            "alias": [
              "Time",
              "Scheduler",
              "Polling",
              "Cron",
              "Interval"
            ],
            "resources": {
              "generic": [],
              "primaryDocumentation": [
                {
                  "url": "https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"
                }
              ]
            },
            "categories": [
              "Core Nodes"
            ],
            "nodeVersion": "1.0",
            "codexVersion": "1.0"
          }
        },
        "group": "[\"trigger\",\"schedule\"]",
        "defaults": {
          "name": "Schedule Trigger",
          "color": "#31C49F"
        },
        "iconData": {
          "icon": "clock",
          "type": "icon"
        },
        "displayName": "Schedule Trigger",
        "typeVersion": 1,
        "nodeCategories": [
          {
            "id": 9,
            "name": "Core Nodes"
          }
        ]
      }
    ],
    "categories": [
      {
        "id": 32,
        "name": "Market Research"
      },
      {
        "id": 49,
        "name": "AI Summarization"
      }
    ],
    "image": []
  }
}