{
  "name": "ezGPT - Compare Snapshots",
  "active": false,
  "nodes": [
    {
      "id": "trigger",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        300
      ],
      "parameters": {}
    },
    {
      "id": "sample-snapshots",
      "name": "Sample Snapshots",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const before = [\n  {\"order_id\":\"001\",\"name\":\"Альфа\",\"amount_minor\":150000},\n  {\"order_id\":\"002\",\"name\":\"Бета\",\"amount_minor\":0},\n  {\"order_id\":\"003\",\"name\":\"Гамма\",\"amount_minor\":50000}\n];\nconst after = [\n  {\"order_id\":\"001\",\"name\":\"Альфа\",\"amount_minor\":150000},\n  {\"order_id\":\"002\",\"name\":\"Бета\",\"amount_minor\":20000},\n  {\"order_id\":\"004\",\"name\":\"Дельта\",\"amount_minor\":70000}\n];\nreturn [{ json: { before, after } }];"
      }
    },
    {
      "id": "check-snapshots",
      "name": "Check Snapshots",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const items = $input.all();\nif (items.length !== 1) throw new Error('one_snapshot_item_required');\nconst source = items[0].json;\nfor (const side of ['before', 'after']) {\n  const rows = source[side];\n  if (!Array.isArray(rows)) throw new Error(side + '_array_required');\n  if (rows.length > 20) throw new Error(side + '_too_many_rows');\n  const ids = new Set();\n  for (const row of rows) {\n    if (!row || typeof row !== 'object' || Array.isArray(row) || Object.keys(row).sort().join('|') !== 'amount_minor|name|order_id') {\n      throw new Error(side + '_row_fields_invalid');\n    }\n    if (typeof row.order_id !== 'string' || !/^\\d{3}$/.test(row.order_id) || ids.has(row.order_id)) {\n      throw new Error(side + '_id_invalid_or_duplicate');\n    }\n    if (typeof row.name !== 'string' || !row.name.trim()) throw new Error(side + '_name_required');\n    if (!Number.isSafeInteger(row.amount_minor) || row.amount_minor < 0) {\n      throw new Error(side + '_amount_invalid');\n    }\n    ids.add(row.order_id);\n  }\n}\nreturn [{ json: { before: source.before, after: source.after } }];"
      }
    },
    {
      "id": "before-rows",
      "name": "Before Rows",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        920,
        160
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const rows = $input.first().json.before;\nreturn rows.length ? rows.map(json => ({ json })) : [{ json: {} }];"
      }
    },
    {
      "id": "after-rows",
      "name": "After Rows",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        920,
        440
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const rows = $input.first().json.after;\nreturn rows.length ? rows.map(json => ({ json })) : [{ json: {} }];"
      }
    },
    {
      "id": "compare",
      "name": "Compare Snapshots",
      "type": "n8n-nodes-base.compareDatasets",
      "typeVersion": 2.3,
      "position": [
        1180,
        300
      ],
      "parameters": {
        "mergeByFields": {
          "values": [
            {
              "field1": "order_id",
              "field2": "order_id"
            }
          ]
        },
        "resolve": "includeBoth",
        "fuzzyCompare": false,
        "options": {
          "multipleMatches": "first",
          "skipFields": "",
          "disableDotNotation": false
        }
      }
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Sample Snapshots",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sample Snapshots": {
      "main": [
        [
          {
            "node": "Check Snapshots",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Snapshots": {
      "main": [
        [
          {
            "node": "Before Rows",
            "type": "main",
            "index": 0
          },
          {
            "node": "After Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Before Rows": {
      "main": [
        [
          {
            "node": "Compare Snapshots",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "After Rows": {
      "main": [
        [
          {
            "node": "Compare Snapshots",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveDataSuccessExecution": "all",
    "saveDataErrorExecution": "all"
  },
  "pinData": {}
}
