{
  "id": "iseNsMusqpCWXzue",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automate Inventory Reordering from Airtable using GPT-4o, Slack & Email",
  "tags": [],
  "nodes": [
    {
      "id": "037cd3b0-2a18-4c98-8e92-e75d8f3d0a4e",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -2144,
        688
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "7121f040-e567-4d0b-9dba-f8dcaa520b5d",
      "name": "Configure GPT-4o Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        64,
        1712
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cd5f5266-7db1-428c-9710-9dce2b429e3a",
      "name": "Configure GPT-4o Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        0,
        944
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "00f12801-52b7-42f7-97f1-c98c5c250dfc",
      "name": "Fetch Inventory Records from Airtable",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -1888,
        688
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appxjEpOgye5YQG1J",
          "cachedResultUrl": "https://airtable.com/appxjEpOgye5YQG1J",
          "cachedResultName": "Lead Manager"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tbl4TiSSi2uUJaUOO",
          "cachedResultUrl": "https://airtable.com/appxjEpOgye5YQG1J/tbl4TiSSi2uUJaUOO",
          "cachedResultName": "Leads"
        },
        "options": {},
        "operation": "search"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0566f579-12d6-4481-8f1d-91b4e7830410",
      "name": "Validate Inventory Record Structure",
      "type": "n8n-nodes-base.if",
      "position": [
        -1648,
        688
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "e2adb005-2b3c-4d1e-8445-442df1fe925a",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "33ca7f8d-04ad-4a26-92ee-8e1b4aab8505",
      "name": "Log Invalid Inventory Rows to Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1520,
        960
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "output",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "output",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "output"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1318002027,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit#gid=1318002027",
          "cachedResultName": "hacker news"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17rcNd_ZpUQLm0uWEVbD-NY6GyFUkrD4BglvawlyBygM/edit?usp=drivesdk",
          "cachedResultName": "sample_leads_50"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "58ec936e-5e82-46dc-8c1f-9f05c18d5064",
      "name": "Configure GPT-4o \u2014 Inventory Optimization Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAzureOpenAi",
      "position": [
        -1184,
        1040
      ],
      "parameters": {
        "model": "gpt-4o",
        "options": {}
      },
      "credentials": {
        "azureOpenAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "83728f9e-386c-42db-9dcf-4fb6a95363a9",
      "name": "Generate Inventory Optimization Output (AI)",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1184,
        672
      ],
      "parameters": {
        "text": "=Analyze the following Airtable inventory records and return the optimized stock details.\n\nInput Data:\n{{ JSON.stringify($json, null, 2) }}\n\nReturn ONLY this JSON structure:\n\n{\n  \"results\": [\n    {\n      \"id\": \"...\",\n      \"ItemName\": \"...\",\n      \"SKU\": \"...\",\n      \"QuantityInStock\": number,\n      \"ReorderLevel\": number,\n      \"SuggestedReorderPoint\": number,\n      \"SuggestedSafetyStock\": number,\n      \"StockStatus\": \"OK | Needs Reorder | Critical\"\n    }\n  ]\n}\n",
        "options": {
          "systemMessage": "=Analyze the following Airtable inventory records and return the optimized stock details.\n\nInput Data:\n{{ JSON.stringify($json, null, 2) }}\n\nReturn ONLY this JSON structure:\n\n{\n  \"results\": [\n    {\n      \"id\": \"...\",\n      \"ItemName\": \"...\",\n      \"SKU\": \"...\",\n      \"QuantityInStock\": number,\n      \"ReorderLevel\": number,\n      \"SuggestedReorderPoint\": number,\n      \"SuggestedSafetyStock\": number,\n      \"StockStatus\": \"OK | Needs Reorder | Critical\"\n    }\n  ]\n}\n\n\nImportant:\n- NEVER wrap the output in backticks.\n- NEVER include markdown.\n- Return ONLY raw JSON.\n- The final output MUST be a valid JSON object. \nYou are an Inventory Optimization Engine.\nFollow formulas strictly and NEVER improvise:\n\nFormula 1:\nSuggestedReorderPoint = ReorderLevel * 1.2\n\nFormula 2:\nSuggestedSafetyStock = ReorderLevel * 0.5\n\nRules:\n- DO NOT round values unless needed.\n- DO NOT swap the formulas.\n- DO NOT invent new logic.\n- Only use the formulas exactly as written.\n\nStockStatus:\n- \"Critical\" if QuantityInStock <= SuggestedSafetyStock\n- \"Needs Reorder\" if QuantityInStock <= SuggestedReorderPoint\n- \"OK\" otherwise\n\nReturn ONLY raw JSON.\n\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "6fee56e2-5f56-4eb0-8aeb-ea5eec3b9966",
      "name": "Merge AI Optimization Results ",
      "type": "n8n-nodes-base.code",
      "position": [
        -768,
        672
      ],
      "parameters": {
        "jsCode": "let items = $input.all();\n\n// AI may return multiple partial outputs \u2192 merge them\nlet mergedResults = [];\n\nfor (const item of items) {\n  let out = item.json.output || item.json;\n  \n  // Remove backticks or markdown\n  out = String(out).replace(/```json|```/g, '').trim();\n  \n  try {\n    const parsed = JSON.parse(out);\n    if (parsed?.results) {\n      mergedResults.push(...parsed.results);\n    }\n  } catch (err) {\n    // Skip invalid JSON\n  }\n}\n\nreturn [\n  {\n    json: {\n      results: mergedResults\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e135ec50-ebdd-46b1-8ce6-3f7efd5aa96b",
      "name": "Generate Inventory Email Summary ",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        64,
        1408
      ],
      "parameters": {
        "text": "=Generate an operations-team\u2013ready email summary based on the following inventory optimization results:\n\n{{ JSON.stringify($json, null, 2) }}\n\nThe email must include:\n- A clear subject line\n- A short overview of today\u2019s inventory health\n- A bullet list highlighting:\n    - Item name\n    - SKU\n    - Quantity in stock\n    - Reorder level\n    - Suggested reorder point\n    - Suggested safety stock\n    - Stock status\n- Specific alerts for items:\n    - Below reorder level\n    - Below safety stock\n    - Low stock or critical stock\n- A closing section with recommended actions\n\nKeep the tone professional but simple.\n",
        "options": {
          "systemMessage": "=You are an expert Operations Assistant responsible for generating clear, concise, and actionable email summaries based on inventory optimization data. \n\nYour job:\n- Read the inventory items and their updated stock calculations.\n- Identify any SKUs that need attention.\n- Highlight items that are nearing reorder point, below safety stock, or have critical status.\n- Summarize important updates for the operations team in a professional business email format.\n- Keep tone: concise, objective, and action-oriented.\n- DO NOT rewrite or change inventory numbers; use exactly what is provided.\n- DO NOT add fictional items or assumptions.\n- If all items are healthy, still provide an email confirming \"No issues detected\".\n\nFormat the email as:\n1. Subject line\n2. Greeting\n3. Summary paragraph\n4. Bullet list of key items with issues\n5. Recommended next steps\n6. Closing\n"
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "dc2b5093-f528-484f-938d-a1edec8b6683",
      "name": "Generate Inventory Slack Summary",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        0,
        608
      ],
      "parameters": {
        "text": "=Generate a Slack-friendly inventory summary using the following data:\n\n{{ JSON.stringify($json, null, 2) }}\n\nInclude:\n- One-line overall inventory health message\n- A compact bullet list of items (name, SKU, stock, reorder level, suggestions, status)\n- Highlight items that are:\n   - Below reorder level\n   - Below safety stock\n   - Low or critical stock\n- Use emojis for quick visibility (\u26a0\ufe0f \ud83d\udd34 \ud83d\udfe2)\n- End with a single recommended Ops action line\n\nKeep it short and actionable.\n",
        "options": {
          "systemMessage": "=Generate a Slack-friendly inventory summary using the following data:\n\n{{ JSON.stringify($json, null, 2) }}\n\nInclude:\n- One-line overall inventory health message\n- A compact bullet list of items (name, SKU, stock, reorder level, suggestions, status)\n- Highlight items that are:\n   - Below reorder level\n   - Below safety stock\n   - Low or critical stock\n- Use emojis for quick visibility (\u26a0\ufe0f \ud83d\udd34 \ud83d\udfe2)\n- End with a single recommended Ops action line\n\nKeep it short and actionable.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 2.1
    },
    {
      "id": "ad89daec-5eb0-440c-a920-f38c71118521",
      "name": "Notify Operations Team on Slack",
      "type": "n8n-nodes-base.slack",
      "notes": "Sends formatted notification to #product-faqs channel with FAQ summary, category, and links",
      "position": [
        432,
        608
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "user": {
          "__rl": true,
          "mode": "list",
          "value": "U09HMPVD466",
          "cachedResultName": "newscctv22"
        },
        "select": "user",
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "71fd0164-d326-495e-9142-3ff2108e6c50",
      "name": "Email Inventory Summary to Manager",
      "type": "n8n-nodes-base.gmail",
      "position": [
        448,
        1408
      ],
      "parameters": {
        "sendTo": "=",
        "message": "={{ $json.output }}",
        "options": {},
        "subject": "=Consent Manager Governance"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "6a917416-e1cd-482d-b553-039bd9184f76",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2720,
        -368
      ],
      "parameters": {
        "width": 816,
        "height": 576,
        "content": "## \ud83d\udce6 Automate Inventory Reordering from Airtable using GPT-4o, Slack & Email\nThis workflow automates inventory intelligence using Airtable + AI models to generate \noptimized stock metrics, and delivers actionable summaries through Email and Slack.\n\nThe workflow starts with a manual trigger \u2192 fetches Inventory from Airtable \u2192 validates \neach row \u2192 uses GPT-4o to calculate reorder points, safety stock, and stock health using \nstrict formulas. Multiple AI outputs are merged into one consolidated dataset. Using the \noptimized results, the system generates two types of summaries: a professional email for \noperations managers and a compact Slack message for quick team visibility.\n\nInvalid rows are logged into Google Sheets to maintain audit-readiness. The workflow ensures \nzero hallucinations, strict JSON formatting, accurate stock-health status, and consistent \nmulti-channel communication. This enables the operations team to instantly identify low, \ncritical, or reorder-level items and take action on time.\n\nTools used:\n\u2022 Airtable \u2192 Inventory source  \n\u2022 GPT-4o (Azure) \u2192 Optimization + Email summary  \n\u2022 GPT-4o (Azure) \u2192 Slack summary  \n\u2022 Google Sheets \u2192 Invalid record logging  \n\u2022 Slack \u2192 Ops team alert  \n\u2022 Gmail \u2192 Email to Manager  \n\nOverall, this workflow ensures clean intake, strict validation, accurate AI-based \noptimization, and multi-channel actionable reporting.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "497c6ee4-b792-49b4-a140-879d68ca54c5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1952,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 688,
        "content": "## Intake & Validation Block\n\nThis section handles data import and quality checks:\n\u2022 Pulls inventory from Airtable  \n\u2022 Validates required fields (id)  \n\u2022 Routes invalid rows to Google Sheets for auditing  \n\u2022 Only clean data enters the AI computation phase  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "c5c932d7-205e-4551-b3ee-ea1ff00930de",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1232,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 688,
        "height": 800,
        "content": "## AI Optimization Engine\n\nThis block processes inventory rows using GPT-4o:\n\u2022 Applies fixed formulas for reorder point & safety stock  \n\u2022 Computes stock health status  \n\u2022 Ensures strict JSON output (no markdown, no hallucinations)  \n\u2022 Merges multiple model outputs into one consolidated dataset  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "a360b40d-47a6-4531-8482-b3dacbd6654b",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        1216
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 672,
        "content": "## Email Summary Generation\n\nCreates a professional, actionable inventory report:\n\u2022 Overall stock health  \n\u2022 Low/critical SKU alerts  \n\u2022 Recommended next steps  \n\u2022 Delivered via Gmail to the manager  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "9148fded-83db-4b92-824f-926f518ff4de",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        400
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 688,
        "content": "## Slack Summary Generation\n\nProduces a compact, emoji-friendly inventory status message:\n\u2022 One-line health indicator  \n\u2022 Item-wise stock highlights  \n\u2022 Critical/reorder alerts (\ud83d\udfe2 \u26a0\ufe0f \ud83d\udd34)  \n\u2022 Auto-sent to the Ops Slack user/channel  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "292c5f1c-9082-438e-9d15-3f6c39e12a5a",
      "name": "Workflow Error Handler",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -1888,
        1552
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "41c63b59-052a-4014-803a-9a5b6d0eb043",
      "name": "Send a message1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -1536,
        1552
      ],
      "parameters": {
        "message": "=\ud83d\udea8 *Workflow Error Alert*  *Error Node:* {{ $json.node.name }} *Error Message:* {{ $json.error.message }} *Timestamp:* {{ $now.toISO() }}  Please investigate immediately.",
        "options": {},
        "subject": "Workflow Error Alert",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4f3d6a6f-a41d-49ed-b253-782ae348d8ef",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1968,
        1392
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 336,
        "content": "## Error Handling\nSends alerts when the workflow fails\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3db10acf-1c31-43d5-8dbf-5d5f63a1dea9",
      "name": "Log Trade Decision to Notion (inventory db)",
      "type": "n8n-nodes-base.notion",
      "position": [
        -64,
        -176
      ],
      "parameters": {
        "title": "=data",
        "simple": false,
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "2e2802b9-1fa0-8035-a725-c04fde5c7b00",
          "cachedResultUrl": "https://www.notion.so/2e2802b91fa08035a725c04fde5c7b00",
          "cachedResultName": "inventory reorder "
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Name|title",
              "title": "={{ $json.results }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1efc26f4-8b24-4d10-a68e-278211042301",
      "name": "Create Asana Task for Inventory Db",
      "type": "n8n-nodes-base.asana",
      "position": [
        208,
        -80
      ],
      "parameters": {
        "name": "={{\n  ($json.results[0].ItemName || 'Unnamed Item')\n  + ' | Stock: ' + $json.results[0].StockStatus\n  + ' | SKU: ' + ($json.results[0].SKU || 'N/A')\n}}\n",
        "workspace": "1212551193156936",
        "authentication": "oAuth2",
        "otherProperties": {
          "notes": "={{\n`\ud83d\udce6 Inventory Alert\n\nItem Name: ${$json.results[0].ItemName || 'N/A'}\nSKU: ${$json.results[0].SKU || 'N/A'}\n\n\ud83d\udcca Stock Details\n\u2022 Quantity In Stock: ${$json.results[0].QuantityInStock}\n\u2022 Reorder Level: ${$json.results[0].ReorderLevel}\n\u2022 Suggested Reorder Point: ${$json.results[0].SuggestedReorderPoint}\n\u2022 Suggested Safety Stock: ${$json.results[0].SuggestedSafetyStock}\n\n\ud83d\udea6 Status: ${$json.results[0].StockStatus}\n\n\ud83c\udd94 Record ID: ${$json.results[0].id}\n`\n}}\n",
          "due_on": "={{ $now.plus({ days: 1 }).toISODate() }}\n",
          "projects": [
            "1212565062132347"
          ]
        }
      },
      "credentials": {
        "asanaOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "231ddfbe-f4a2-4c28-8ef4-16753de41def",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        704
      ],
      "parameters": {
        "color": 3,
        "width": 336,
        "height": 272,
        "content": "## \ud83d\udd10 Required Credentials\n- Airtable (Inventory source)\n- Azure OpenAI (GPT-4o)\n- Google Sheets (audit logging)\n- Slack API (Ops alerts)\n- Gmail OAuth2 (email summaries)\n- Notion API (inventory records)\n- Asana OAuth2 (task creation)\n\nUse n8n credentials. Never hard-code API keys.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f471c407-abc4-4048-b482-c994baa3d4df",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        -432
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 576,
        "content": "## \ud83d\uddc2\ufe0f Task & Record Logging\nLogs inventory decisions for traceability and action.\nCreates tasks in Asana and stores optimized records\ninside a Notion inventory database.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "670ae766-9341-46e3-98f7-34467b462e7b",
  "connections": {
    "Configure GPT-4o Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Inventory Email Summary ",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Error Handler": {
      "main": [
        [
          {
            "node": "Send a message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure GPT-4o Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Inventory Slack Summary",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Merge AI Optimization Results ": {
      "main": [
        [
          {
            "node": "Generate Inventory Email Summary ",
            "type": "main",
            "index": 0
          },
          {
            "node": "Generate Inventory Slack Summary",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create Asana Task for Inventory Db",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Trade Decision to Notion (inventory db)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Inventory Slack Summary": {
      "main": [
        [
          {
            "node": "Notify Operations Team on Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Inventory Email Summary ": {
      "main": [
        [
          {
            "node": "Email Inventory Summary to Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Inventory Record Structure": {
      "main": [
        [
          {
            "node": "Generate Inventory Optimization Output (AI)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Invalid Inventory Rows to Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Fetch Inventory Records from Airtable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Inventory Records from Airtable": {
      "main": [
        [
          {
            "node": "Validate Inventory Record Structure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Inventory Optimization Output (AI)": {
      "main": [
        [
          {
            "node": "Merge AI Optimization Results ",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure GPT-4o \u2014 Inventory Optimization Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Inventory Optimization Output (AI)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}