{
  "nodes": [
    {
      "id": "42217665-1184-40a8-bddf-b40f9e84fce1",
      "name": "Webhook - Receive Financial Data",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -768,
        288
      ],
      "parameters": {
        "path": "financial-data-reconciliation",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "de790021-1521-4926-bd1a-b40ae43e2794",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -592,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "confidenceThreshold",
              "type": "number",
              "value": 0.85
            },
            {
              "id": "id-2",
              "name": "matchingKeys",
              "type": "array",
              "value": "[\"transactionId\", \"invoiceNumber\", \"amount\", \"date\"]"
            },
            {
              "id": "id-3",
              "name": "fuzzyMatchThreshold",
              "type": "number",
              "value": 0.7
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "9f455d80-262a-4af3-85ed-143db95c4696",
      "name": "Check Data Source Type",
      "type": "n8n-nodes-base.if",
      "position": [
        -368,
        288
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.sourceType }}",
              "rightValue": "bank_statement"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3beba561-8803-4b92-b81e-d5aea0832d57",
      "name": "Extract CSV Data",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        16,
        48
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "5fd65063-4ddc-441b-97b3-9f75d88c32a2",
      "name": "Normalize Bank Statement Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        16,
        224
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "recordId",
              "type": "string",
              "value": "={{ $json.transaction_id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.transaction_amount }}"
            },
            {
              "id": "id-3",
              "name": "date",
              "type": "string",
              "value": "={{ $json.transaction_date }}"
            },
            {
              "id": "id-4",
              "name": "description",
              "type": "string",
              "value": "={{ $json.transaction_description }}"
            },
            {
              "id": "id-5",
              "name": "sourceType",
              "type": "string",
              "value": "bank_statement"
            },
            {
              "id": "id-6",
              "name": "normalizedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "cd62e763-8cd1-46bb-82b6-f18078412dfb",
      "name": "Normalize Invoice Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        16,
        400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "recordId",
              "type": "string",
              "value": "={{ $json.invoice_number }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.invoice_total }}"
            },
            {
              "id": "id-3",
              "name": "date",
              "type": "string",
              "value": "={{ $json.invoice_date }}"
            },
            {
              "id": "id-4",
              "name": "description",
              "type": "string",
              "value": "={{ $json.invoice_description }}"
            },
            {
              "id": "id-5",
              "name": "sourceType",
              "type": "string",
              "value": "invoice"
            },
            {
              "id": "id-6",
              "name": "normalizedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "0efc2451-3c62-4988-85d6-e06312afa34c",
      "name": "Normalize ERP Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        16,
        608
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "recordId",
              "type": "string",
              "value": "={{ $json.erp_transaction_id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.erp_amount }}"
            },
            {
              "id": "id-3",
              "name": "date",
              "type": "string",
              "value": "={{ $json.erp_date }}"
            },
            {
              "id": "id-4",
              "name": "description",
              "type": "string",
              "value": "={{ $json.erp_description }}"
            },
            {
              "id": "id-5",
              "name": "sourceType",
              "type": "string",
              "value": "erp"
            },
            {
              "id": "id-6",
              "name": "normalizedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "0c4e99b7-8eda-4216-aba0-c14e076285c5",
      "name": "Normalize CSV Schema",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        48
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "recordId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "id-2",
              "name": "amount",
              "type": "number",
              "value": "={{ $json.amount }}"
            },
            {
              "id": "id-3",
              "name": "date",
              "type": "string",
              "value": "={{ $json.date }}"
            },
            {
              "id": "id-4",
              "name": "description",
              "type": "string",
              "value": "={{ $json.description }}"
            },
            {
              "id": "id-5",
              "name": "sourceType",
              "type": "string",
              "value": "csv_upload"
            },
            {
              "id": "id-6",
              "name": "normalizedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "a8f3c054-a206-4a16-99d0-2957eb87caa6",
      "name": "Merge All Normalized Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        448,
        208
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "b54e7970-4c2b-478c-9568-57a10757895d",
      "name": "Deterministic Matching Logic",
      "type": "n8n-nodes-base.code",
      "position": [
        832,
        304
      ],
      "parameters": {
        "jsCode": "// Deterministic Matching Logic\n// Groups records by exact matches on recordId, amount, and date fields\n// Calculates match confidence based on number of matching fields\n\nconst items = $input.all();\nconst matchedGroups = {};\nconst results = [];\n\n// Helper function to normalize values for comparison\nfunction normalizeValue(value) {\n  if (value === null || value === undefined) return '';\n  return String(value).trim().toLowerCase();\n}\n\n// Helper function to normalize date for comparison\nfunction normalizeDate(date) {\n  if (!date) return '';\n  try {\n    const d = new Date(date);\n    return d.toISOString().split('T')[0]; // YYYY-MM-DD format\n  } catch (e) {\n    return String(date).trim();\n  }\n}\n\n// Helper function to normalize amount for comparison\nfunction normalizeAmount(amount) {\n  if (amount === null || amount === undefined) return '';\n  const num = parseFloat(String(amount).replace(/[^0-9.-]/g, ''));\n  return isNaN(num) ? '' : num.toFixed(2);\n}\n\n// Process each item and create matching keys\nfor (const item of items) {\n  const json = item.json;\n  \n  const recordId = normalizeValue(json.recordId || json.id || json.transactionId);\n  const amount = normalizeAmount(json.amount || json.total || json.value);\n  const date = normalizeDate(json.date || json.transactionDate || json.timestamp);\n  \n  // Create multiple matching keys with different combinations\n  const matchingKeys = [];\n  \n  // Exact match on all three fields (highest confidence)\n  if (recordId && amount && date) {\n    matchingKeys.push({ key: `${recordId}|${amount}|${date}`, matchedFields: ['recordId', 'amount', 'date'], confidence: 1.0 });\n  }\n  \n  // Match on recordId and amount (high confidence)\n  if (recordId && amount) {\n    matchingKeys.push({ key: `${recordId}|${amount}`, matchedFields: ['recordId', 'amount'], confidence: 0.85 });\n  }\n  \n  // Match on recordId and date (high confidence)\n  if (recordId && date) {\n    matchingKeys.push({ key: `${recordId}|${date}`, matchedFields: ['recordId', 'date'], confidence: 0.85 });\n  }\n  \n  // Match on amount and date (medium confidence)\n  if (amount && date) {\n    matchingKeys.push({ key: `${amount}|${date}`, matchedFields: ['amount', 'date'], confidence: 0.7 });\n  }\n  \n  // Match on recordId only (lower confidence)\n  if (recordId) {\n    matchingKeys.push({ key: `${recordId}`, matchedFields: ['recordId'], confidence: 0.6 });\n  }\n  \n  // Store item with its matching keys\n  for (const matchKey of matchingKeys) {\n    if (!matchedGroups[matchKey.key]) {\n      matchedGroups[matchKey.key] = {\n        items: [],\n        matchedFields: matchKey.matchedFields,\n        baseConfidence: matchKey.confidence\n      };\n    }\n    matchedGroups[matchKey.key].items.push(json);\n  }\n}\n\n// Process matched groups and create output\nfor (const [key, group] of Object.entries(matchedGroups)) {\n  if (group.items.length > 1) {\n    // Multiple items matched - potential reconciliation\n    const matchCount = group.items.length;\n    const confidence = group.baseConfidence * Math.min(1.0, matchCount / 2); // Adjust confidence based on match count\n    \n    results.push({\n      matchKey: key,\n      matchedFields: group.matchedFields,\n      matchCount: matchCount,\n      confidence: parseFloat(confidence.toFixed(2)),\n      matchType: 'deterministic',\n      records: group.items,\n      status: confidence >= 0.8 ? 'high_confidence' : 'medium_confidence'\n    });\n  } else if (group.items.length === 1) {\n    // Single item - no match found\n    results.push({\n      matchKey: key,\n      matchedFields: group.matchedFields,\n      matchCount: 1,\n      confidence: 0,\n      matchType: 'no_match',\n      records: group.items,\n      status: 'unmatched'\n    });\n  }\n}\n\n// Return results\nreturn results.map(result => ({ json: result }));"
      },
      "typeVersion": 2
    },
    {
      "id": "895fed31-1878-4834-bdff-834c29948de5",
      "name": "Check Match Quality",
      "type": "n8n-nodes-base.if",
      "position": [
        1008,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $('Deterministic Matching Logic').item.json.matchConfidence }}",
              "rightValue": "={{ $('Workflow Configuration').first().json.fuzzyMatchThreshold }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "73cfb80a-0342-4542-a099-9ca83d8b045e",
      "name": "AI Fuzzy Matching Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1248,
        528
      ],
      "parameters": {
        "text": "=Records to match: {{ $json.unmatchedRecords }}",
        "options": {
          "systemMessage": "You are a financial data reconciliation specialist. Your task is to analyze unmatched financial records and identify potential matches using fuzzy matching techniques.\n\nFor each unmatched record, you should:\n1. Compare transaction descriptions using semantic similarity\n2. Check for near-matches in amounts (within 1% tolerance)\n3. Look for date matches within a 3-day window\n4. Consider vendor name variations and abbreviations\n5. Return matched pairs with confidence scores\n\nReturn your analysis in the structured format defined by the output parser."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "7abbe9b8-2a0b-48d9-81c0-39b0a80df771",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1248,
        864
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "2a37407e-1fd9-46d5-a942-de40e246f47d",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1408,
        848
      ],
      "parameters": {
        "jsonSchemaExample": "{\n\t\"matchedPairs\": [\n\t\t{\n\t\t\t\"sourceRecord\": {},\n\t\t\t\"targetRecord\": {},\n\t\t\t\"confidenceScore\": 0.95,\n\t\t\t\"matchReason\": \"Exact match on transaction ID and amount\"\n\t\t}\n\t],\n\t\"unmatchedRecords\": []\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "295397ed-0102-4df9-a2cf-446a85439e49",
      "name": "Merge Matched Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        1680,
        304
      ],
      "parameters": {
        "mode": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "54f8e770-f6f8-4b49-bb2c-78962732ed6f",
      "name": "Calculate Confidence Scores",
      "type": "n8n-nodes-base.code",
      "position": [
        1872,
        304
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Calculate final confidence scores by combining deterministic and AI fuzzy match scores\n// Normalize to 0-1 range and add audit trail metadata\n\nconst item = $input.item.json;\n\n// Extract scores from different matching stages\nconst deterministicScore = item.deterministicMatchScore || 0;\nconst aiScore = item.aiMatchScore || 0;\nconst hasAiMatch = item.aiMatchScore !== undefined;\n\n// Weight configuration\nconst DETERMINISTIC_WEIGHT = 0.6;\nconst AI_WEIGHT = 0.4;\n\n// Calculate combined confidence score\nlet finalConfidence;\nif (hasAiMatch) {\n  // Combine both scores with weights\n  finalConfidence = (deterministicScore * DETERMINISTIC_WEIGHT) + (aiScore * AI_WEIGHT);\n} else {\n  // Only deterministic match available\n  finalConfidence = deterministicScore;\n}\n\n// Normalize to 0-1 range\nfinalConfidence = Math.max(0, Math.min(1, finalConfidence));\n\n// Determine confidence level\nlet confidenceLevel;\nif (finalConfidence >= 0.9) {\n  confidenceLevel = 'HIGH';\n} else if (finalConfidence >= 0.7) {\n  confidenceLevel = 'MEDIUM';\n} else if (finalConfidence >= 0.5) {\n  confidenceLevel = 'LOW';\n} else {\n  confidenceLevel = 'VERY_LOW';\n}\n\n// Build audit trail\nconst auditTrail = {\n  timestamp: new Date().toISOString(),\n  deterministicScore: deterministicScore,\n  aiScore: hasAiMatch ? aiScore : null,\n  finalConfidence: finalConfidence,\n  confidenceLevel: confidenceLevel,\n  matchingMethod: hasAiMatch ? 'HYBRID' : 'DETERMINISTIC',\n  weights: {\n    deterministic: DETERMINISTIC_WEIGHT,\n    ai: AI_WEIGHT\n  }\n};\n\n// Return enriched item with confidence scores and audit trail\nreturn {\n  json: {\n    ...item,\n    finalConfidence: finalConfidence,\n    confidenceLevel: confidenceLevel,\n    confidencePercentage: Math.round(finalConfidence * 100),\n    auditTrail: auditTrail\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e96842c2-5bc0-44e0-b3e9-bfcbb62a80e6",
      "name": "Route by Confidence Threshold",
      "type": "n8n-nodes-base.if",
      "position": [
        2080,
        320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.finalConfidence }}",
              "rightValue": "={{ $('Workflow Configuration').first().json.confidenceThreshold }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b10d37cf-b377-4397-8b67-f358bfc5da07",
      "name": "Flag for Human Review",
      "type": "n8n-nodes-base.set",
      "position": [
        2320,
        400
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "reviewStatus",
              "type": "string",
              "value": "pending_human_review"
            },
            {
              "id": "id-2",
              "name": "reviewReason",
              "type": "string",
              "value": "Low confidence match - requires manual verification"
            },
            {
              "id": "id-3",
              "name": "flaggedAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "52559270-484a-49d0-847e-f004518abb02",
      "name": "Mark as Auto-Reconciled",
      "type": "n8n-nodes-base.set",
      "position": [
        2320,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "reviewStatus",
              "type": "string",
              "value": "auto_reconciled"
            },
            {
              "id": "id-2",
              "name": "reconciledAt",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "fe27e284-4bc7-446b-85fc-1cd03f8b8f81",
      "name": "Merge All Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        2640,
        352
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "4cdd473a-2795-43ed-a464-a874d458e3ff",
      "name": "Log to Reconciliation Report",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2864,
        352
      ],
      "parameters": {
        "columns": {
          "value": null,
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Reconciliation Report"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Google Sheets Document ID__>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2682e628-ed05-4fd2-8feb-43d9caff7470",
      "name": "Notify Finance Team",
      "type": "n8n-nodes-base.slack",
      "position": [
        3120,
        352
      ],
      "parameters": {
        "text": "=Reconciliation Complete!\n\nTotal Records Processed: {{ $json.totalRecords }}\nAuto-Reconciled: {{ $json.autoReconciledCount }}\nPending Review: {{ $json.pendingReviewCount }}\n\nView full report: {{ $json.reportUrl }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<__PLACEHOLDER_VALUE__Slack Channel ID or Name__>"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "3d42b58b-ab5e-4969-bbd9-96444b55ee6c",
      "name": "Merge All Normalized Data1",
      "type": "n8n-nodes-base.merge",
      "position": [
        448,
        432
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "e879468a-0a17-4a40-ada7-79e8023272e2",
      "name": "Merge All Normalized Data2",
      "type": "n8n-nodes-base.merge",
      "position": [
        640,
        304
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c8f83a37-b017-4749-99da-e51966fabb13",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1664,
        64
      ],
      "parameters": {
        "width": 560,
        "height": 528,
        "content": "\n## How it works\nThis workflow automates reconciliation across bank statements, invoices, ERP systems, and CSV uploads. It standardizes all data into a unified format and performs deterministic matching using fields like ID, amount, and date.\n\nFor unmatched records, AI fuzzy matching identifies potential matches using descriptions, amount tolerance, and date proximity. A final confidence score is calculated, auto-reconciling high-confidence matches while flagging others for review.\n\n## Setup\n\n- Configure webhook to receive financial data  \n- Set matching keys and confidence thresholds  \n- Connect OpenAI for fuzzy matching  \n- Connect Google Sheets for reporting  \n- Connect Slack for notifications  \n- Ensure input data follows expected formats  \n- Test with sample data before activating  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "d97902db-baa8-41af-8e92-60ed7b090c42",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 352,
        "content": "## Data Input\nReceives financial data via webhook from multiple sources and Defines matching keys, thresholds, and reconciliation rules."
      },
      "typeVersion": 1
    },
    {
      "id": "1f5d7acb-20d4-4968-ae11-15a950fb1d82",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 352,
        "content": "## Source Routing\nDetects data type and routes to correct normalization flow.)"
      },
      "typeVersion": 1
    },
    {
      "id": "d5f1e7f2-2466-407a-bf7e-863fefa466f5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 848,
        "content": "## Data Normalization\nConverts bank, invoice, ERP, and CSV data into a unified schema."
      },
      "typeVersion": 1
    },
    {
      "id": "57d64771-fda3-4bd2-9b0a-d5e60537f5ae",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 528,
        "content": "## Data Merge\nCombines all normalized records for comparison."
      },
      "typeVersion": 1
    },
    {
      "id": "f93866d8-35f9-4065-8a18-d16ce408a60a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        128
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 384,
        "content": "## Deterministic Matching\nMatches records using exact fields like ID, amount, and date."
      },
      "typeVersion": 1
    },
    {
      "id": "1d8eb26d-23ee-4ca0-9620-3bd8775e7559",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        416
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 352,
        "content": "## AI Fuzzy Matching\nUses AI to find near matches based on text, amount, and date."
      },
      "typeVersion": 1
    },
    {
      "id": "10ca8421-c5f2-4033-a2e5-bf8f845322e1",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 272,
        "content": "## Confidence Scoring\nCombines matching results into final confidence score with audit trail."
      },
      "typeVersion": 1
    },
    {
      "id": "89ed1034-6845-4de2-8a5c-5a235c58bf7e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2048,
        176
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 416,
        "content": "## Decision Routing\nRoutes high-confidence matches or flags low-confidence for review."
      },
      "typeVersion": 1
    },
    {
      "id": "ef0d6bea-dbd9-42cb-b9e6-6fdac191bbd4",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2832,
        176
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 416,
        "content": "## Reporting\nLogs reconciliation results into Google Sheets and Sends summary of reconciliation results via Slack."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Extract CSV Data": {
      "main": [
        [
          {
            "node": "Normalize CSV Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Results": {
      "main": [
        [
          {
            "node": "Log to Reconciliation Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Fuzzy Matching Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check Match Quality": {
      "main": [
        [
          {
            "node": "Merge Matched Results",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "AI Fuzzy Matching Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize CSV Schema": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize ERP Schema": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Flag for Human Review": {
      "main": [
        [
          {
            "node": "Merge All Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Matched Results": {
      "main": [
        [
          {
            "node": "Calculate Confidence Scores",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Data Source Type": {
      "main": [
        [
          {
            "node": "Normalize Bank Statement Schema",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Normalize Invoice Schema",
            "type": "main",
            "index": 0
          },
          {
            "node": "Normalize ERP Schema",
            "type": "main",
            "index": 0
          },
          {
            "node": "Extract CSV Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Check Data Source Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Fuzzy Matching Agent": {
      "main": [
        [
          {
            "node": "Merge Matched Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Mark as Auto-Reconciled": {
      "main": [
        [
          {
            "node": "Merge All Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Invoice Schema": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Fuzzy Matching Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Normalized Data": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge All Normalized Data1": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data2",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge All Normalized Data2": {
      "main": [
        [
          {
            "node": "Deterministic Matching Logic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Confidence Scores": {
      "main": [
        [
          {
            "node": "Route by Confidence Threshold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Deterministic Matching Logic": {
      "main": [
        [
          {
            "node": "Check Match Quality",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Reconciliation Report": {
      "main": [
        [
          {
            "node": "Notify Finance Team",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Confidence Threshold": {
      "main": [
        [
          {
            "node": "Mark as Auto-Reconciled",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Flag for Human Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Bank Statement Schema": {
      "main": [
        [
          {
            "node": "Merge All Normalized Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Webhook - Receive Financial Data": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}