{
  "name": "ezGPT - File SHA256 Check",
  "active": false,
  "nodes": [
    {
      "id": "trigger",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        300
      ],
      "parameters": {}
    },
    {
      "id": "sample-file",
      "name": "Sample File",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const text = `Учебный отчёт ezGPT\nЗаказы: 2\nСумма: 150000 копеек\n`;\nconst expected_sha256 = 'bb17d9a5af47d968e26ffdab09cb3fb642f67ca0a76cee6d8cd99099731565ec';\nconst file = await this.helpers.prepareBinaryData(\n  Buffer.from(text, 'utf8'), 'n8n-sha256-demo.txt', 'text/plain',\n);\nreturn [{ json: { file_id: 'hash-demo-001', expected_sha256 }, binary: { document: file } }];"
      }
    },
    {
      "id": "check-file",
      "name": "Check File",
      "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_file_required');\nconst item = items[0];\nif (item.json.file_id !== 'hash-demo-001') throw new Error('file_id_invalid');\nif (typeof item.json.expected_sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(item.json.expected_sha256)) {\n  throw new Error('expected_sha256_invalid');\n}\nif (Object.keys(item.binary || {}).join('|') !== 'document') throw new Error('document_binary_required');\nconst file = item.binary.document;\nif (file.fileName !== 'n8n-sha256-demo.txt') throw new Error('file_name_invalid');\nconst buffer = await this.helpers.getBinaryDataBuffer(0, 'document');\nif (!buffer.length || buffer.length > 16384) throw new Error('file_size_invalid');\nreturn [{ json: {\n  file_id: item.json.file_id,\n  file_name: file.fileName,\n  bytes: buffer.length,\n  expected_sha256: item.json.expected_sha256,\n}, binary: item.binary }];"
      }
    },
    {
      "id": "hash",
      "name": "File SHA256",
      "type": "n8n-nodes-base.crypto",
      "typeVersion": 2,
      "position": [
        900,
        300
      ],
      "parameters": {
        "action": "hash",
        "type": "SHA256",
        "binaryData": true,
        "binaryPropertyName": "document",
        "dataPropertyName": "sha256",
        "encoding": "hex"
      }
    },
    {
      "id": "compare-sha256",
      "name": "Compare SHA256",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1120,
        300
      ],
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const items = $input.all();\nif (items.length !== 1) throw new Error('one_hash_result_required');\nconst row = items[0].json;\nif (Object.keys(row).sort().join('|') !== 'bytes|expected_sha256|file_id|file_name|sha256') {\n  throw new Error('hash_fields_mismatch');\n}\nconst original = $('Check File').first().json;\nfor (const key of ['file_id', 'file_name', 'bytes', 'expected_sha256']) {\n  if (row[key] !== original[key]) throw new Error('file_metadata_changed');\n}\nif (typeof row.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(row.sha256)) {\n  throw new Error('sha256_format_invalid');\n}\nif (row.sha256 !== row.expected_sha256) throw new Error('file_sha256_mismatch');\nreturn [{ json: {\n  file_id: row.file_id,\n  file_name: row.file_name,\n  bytes: row.bytes,\n  algorithm: 'SHA256',\n  sha256: row.sha256,\n  matches_expected: true,\n  status: 'verified',\n  action_performed: false,\n} }];"
      }
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Sample File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sample File": {
      "main": [
        [
          {
            "node": "Check File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check File": {
      "main": [
        [
          {
            "node": "File SHA256",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File SHA256": {
      "main": [
        [
          {
            "node": "Compare SHA256",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveDataSuccessExecution": "all",
    "saveDataErrorExecution": "all"
  },
  "pinData": {}
}
