{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Stresstest Workflow (easybits Extractor verified community node)",
  "tags": [],
  "nodes": [
    {
      "id": "0fcb599c-7cce-45a3-bbdb-179ae3078e79",
      "name": "Document Upload",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        16,
        96
      ],
      "parameters": {
        "options": {},
        "formTitle": "Document Upload Form",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "Upload"
            }
          ]
        },
        "responseMode": "lastNode"
      },
      "typeVersion": 2.5
    },
    {
      "id": "9b51006c-7343-412d-87b2-55005b5e1aa1",
      "name": "Validation",
      "type": "n8n-nodes-base.set",
      "position": [
        1232,
        96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a9749b03-86a3-42ab-9bea-2e37b3bc2f45",
              "name": "amount_due_status",
              "type": "string",
              "value": "={{ $json.data.amount_due === 0 ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "d155a6b5-108b-4634-9cf0-d857b582ecd0",
              "name": "amount_paid_status",
              "type": "string",
              "value": "={{ $json.data.amount_paid === 73.82 ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "a160371f-7ca0-4453-bd9e-b665839f1d18",
              "name": "billing_period_status",
              "type": "string",
              "value": "={{ $json.data.billing_period === \"Jan 15 to Feb 15, 2026\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "7ecd25a0-9ebb-4538-a754-3719cabfb3fe",
              "name": "currency_status",
              "type": "string",
              "value": "={{ $json.data.currency === \"EUR\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "ebf4410d-9528-4825-8522-9f4702ef2814",
              "name": "customer_name_status",
              "type": "string",
              "value": "={{ $json.data.customer_name === \"Max Mustermann\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "0b5f14ea-ab7c-4d9b-869a-a5dc293b799d",
              "name": "invoice_date_status",
              "type": "string",
              "value": "={{ $json.data.invoice_date === \"Jan 15, 2026\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "92da2d35-6694-4113-8572-2f58b1e5a235",
              "name": "invoice_number_status",
              "type": "string",
              "value": "={{ $json.data.invoice_number === \"IN-2026-0022514\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "f51863ca-174f-48cc-949d-af161fd3140e",
              "name": "payment_status_status",
              "type": "string",
              "value": "={{ $json.data.payment_status === \"PAID\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "678b30ca-69eb-424c-bd3a-c383b166b7d4",
              "name": "total_amount_status",
              "type": "string",
              "value": "={{ $json.data.total_amount === 73.82 ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "6b94284d-8ebb-4896-8dcf-203b2272b0ff",
              "name": "vendor_name_status",
              "type": "string",
              "value": "={{ $json.data.vendor_name === \"easybits GmbH\" ? \"correct \u2705\" : \"incorrect \u274c\" }}"
            },
            {
              "id": "51efc06b-0fc7-409c-b5a9-7b8a0947698c",
              "name": "accuracy_percent",
              "type": "number",
              "value": "={{ (\n  ($json.data.amount_due === 0 ? 1 : 0) +\n  ($json.data.amount_paid === 73.82 ? 1 : 0) +\n  ($json.data.billing_period === \"Jan 15 to Feb 15, 2026\" ? 1 : 0) +\n  ($json.data.currency === \"EUR\" ? 1 : 0) +\n  ($json.data.customer_name === \"Max Mustermann\" ? 1 : 0) +\n  ($json.data.invoice_date === \"Jan 15, 2026\" ? 1 : 0) +\n  ($json.data.invoice_number === \"IN-2026-0022514\" ? 1 : 0) +\n  ($json.data.payment_status === \"PAID\" ? 1 : 0) +\n  ($json.data.total_amount === 73.82 ? 1 : 0) +\n  ($json.data.vendor_name === \"easybits GmbH\" ? 1 : 0)\n) / 10 * 100 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f7f9ba54-b830-4f2b-abae-e31d3183923c",
      "name": "Merge Ground Truth",
      "type": "n8n-nodes-base.merge",
      "position": [
        928,
        384
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "3a2a3e96-586d-4f5c-997c-adad9e466725",
      "name": "Ground Truth",
      "type": "n8n-nodes-base.set",
      "position": [
        624,
        96
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f4ee8a43-3aea-431f-8d9b-4d856fb07190",
              "name": "gt_amount_due",
              "type": "number",
              "value": 0
            },
            {
              "id": "69e34d32-9262-411c-acb3-bac059b8095f",
              "name": "gt_amount_paid",
              "type": "number",
              "value": 73.82
            },
            {
              "id": "d8b4619b-aedf-4207-a142-1903c5417239",
              "name": "gt_billing_period",
              "type": "string",
              "value": "Jan 15 to Feb 15, 2026"
            },
            {
              "id": "1766bb6f-ab35-4032-b47a-fdb429521f04",
              "name": "gt_currency",
              "type": "string",
              "value": "EUR"
            },
            {
              "id": "bbaea181-5391-494b-80a3-58756692203c",
              "name": "gt_customer_name",
              "type": "string",
              "value": "Max Mustermann"
            },
            {
              "id": "efb28932-894d-4357-9e0a-2dd989fef99a",
              "name": "gt_invoice_date",
              "type": "string",
              "value": "Jan 15, 2026"
            },
            {
              "id": "3df929a7-ca9e-4a50-96cf-06e41856772b",
              "name": "gt_invoice_number",
              "type": "string",
              "value": "IN-2026-0022514"
            },
            {
              "id": "d281a5cb-07d0-481d-b71b-8844aaf975a9",
              "name": "gt_payment_status",
              "type": "string",
              "value": "PAID"
            },
            {
              "id": "2feba545-bd40-4c4e-9519-741c1aeca7d2",
              "name": "gt_total_amount",
              "type": "number",
              "value": 73.82
            },
            {
              "id": "29eff29d-9fe0-4a03-97d4-3ed0cc59dfb0",
              "name": "gt_vendor_name",
              "type": "string",
              "value": "easybits GmbH"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a8a48fb4-163a-4b3a-8ba9-887736b25b07",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -336
      ],
      "parameters": {
        "width": 752,
        "height": 1088,
        "content": "# \ud83e\uddea easybits Extractor \u2013 Stress Test Workflow\n\n## What This Workflow Does\nUpload the same invoice in different qualities (original PDF, scanned copy, phone photo, compressed JPEG, etc.) and instantly see how accurately each field was extracted. The workflow compares every extracted value against a fixed ground truth and returns a per-field pass/fail report with an overall accuracy percentage \u2013 directly in the browser.\n\n## How It Works\n1. **Upload** \u2013 A document is submitted through the n8n web form\n2. **Extract** \u2013 easybits Extractor processes the file and returns structured data\n3. **Compare** \u2013 Each extracted field is compared against the known correct values\n4. **Report** \u2013 A completion screen shows which fields matched and the overall accuracy\n\n## Setup Guide\n\n### 1. Create Your easybits Extractor Pipeline\n1. Go to [extractor.easybits.tech](https://extractor.easybits.tech/) and create a new pipeline\n2. Upload one of the example invoices as your reference document \u2013 you can find them here: https://github.com/felix-sattler-easybits/n8n-workflows/tree/88d7c9818b150e71dd749bf9f665359fa57efcb9/data-extraction-stresstest\n3. Click **Auto-Mapping** \u2013 the Extractor will automatically detect and set up all fields for you\n4. Save the pipeline and copy your **Pipeline ID** and **API Key**\n\n### 2. Connect Your easybits Credentials\nOpen the **easybits Extractor** node in the workflow and connect your credentials (Pipeline ID & API Key). The node will use the pipeline you just created \u2013 no further configuration needed.\n\n### 3. Adjust the Ground Truth (if needed)\nThe **Ground Truth** node contains the expected values for all 10 fields. If you're testing with a different document, update these values to match your reference invoice.\n\n### 4. Activate & Test the workflow by uploading your first test document\n\n---\n\n## \ud83d\udd04 Want to Test a Different Extraction Solution?\nYou can swap out the easybits Extractor node for an **HTTP Request node** pointing at any other extraction API. As long as your HTTP node returns the same field names under `json.data` (e.g. `data.invoice_number`, `data.amount_paid`, etc.), the rest of the workflow \u2013 ground truth comparison, validation, and results display \u2013 works identically. This makes it easy to benchmark multiple solutions side by side using the exact same test documents and accuracy criteria."
      },
      "typeVersion": 1
    },
    {
      "id": "b1edcf65-811a-43b3-ad64-2d283af43e68",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \ud83d\udce5 Document Upload\nHosts a simple web form with a single file upload field. Set to \"Workflow Finishes\" mode so the browser waits for the full pipeline to complete before showing results."
      },
      "typeVersion": 1
    },
    {
      "id": "d4082c17-e4fb-4b05-b4cc-aa3b0f3968fb",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        224,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \ud83e\udd16 easybits Data Extraction\nSends the uploaded file to the easybits Extractor API. Returns structured fields under `json.data` \u2013 including invoice number, amounts, dates, vendor, and payment status."
      },
      "typeVersion": 1
    },
    {
      "id": "54adb19b-1033-4358-a88e-7b0d608a6a09",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \ud83d\udccb Ground Truth\nHolds the known correct values for all 10 fields, prefixed with `gt_` to avoid name collisions after merging. Update these values if you switch to a different test document."
      },
      "typeVersion": 1
    },
    {
      "id": "a951b9cd-a29f-42db-904c-7a236b188f9d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        176
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \ud83d\udd00 Merge Ground Truth\nCombines the extracted data (Input 1) with the ground truth values (Input 2) into a single item using positional merge. This puts both datasets side by side for comparison."
      },
      "typeVersion": 1
    },
    {
      "id": "8f89e502-1420-43e8-8db6-4b1ee5224f51",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \u2705 Validation\nCompares each extracted field against its ground truth value. Outputs a status per field (correct \u2705 / incorrect \u274c) and calculates the overall accuracy as a percentage."
      },
      "typeVersion": 1
    },
    {
      "id": "7d2fa37b-5d86-4909-8a9e-e3095a1b73a8",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "## \ud83d\udcca Results\nDisplays the final report as a form completion page. Shows the accuracy percentage and a per-field breakdown so you can immediately see which fields were extracted correctly and which ones drifted."
      },
      "typeVersion": 1
    },
    {
      "id": "3fefe62e-e5eb-45c3-9585-d5296790e0f8",
      "name": "easybits: Data Extraction",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        320,
        96
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "55f36569-dd9b-4957-ba75-e6df41977ffc",
      "name": "Results in Form",
      "type": "n8n-nodes-base.form",
      "position": [
        1536,
        96
      ],
      "parameters": {
        "options": {},
        "operation": "completion",
        "completionTitle": "Stresstest Results",
        "completionMessage": "=Extraction Accuracy: {{ $json.accuracy_percent }}%<br><br>Vendor Name: {{ $json.vendor_name_status }}<br>Customer Name: {{ $json.customer_name_status }}<br>Invoice Number: {{ $json.invoice_number_status }}<br>Invoice Date: {{ $json.invoice_date_status }}<br>Billing Period: {{ $json.billing_period_status }}<br>Currency: {{ $json.currency_status }}<br>Total Amount: {{ $json.total_amount_status }}<br>Amount Paid: {{ $json.amount_paid_status }}<br>Amount Due: {{ $json.amount_due_status }}<br>Payment Status: {{ $json.payment_status_status }}"
      },
      "typeVersion": 2.5
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Validation": {
      "main": [
        [
          {
            "node": "Results in Form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ground Truth": {
      "main": [
        [
          {
            "node": "Merge Ground Truth",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Document Upload": {
      "main": [
        [
          {
            "node": "easybits: Data Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Ground Truth": {
      "main": [
        [
          {
            "node": "Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Data Extraction": {
      "main": [
        [
          {
            "node": "Merge Ground Truth",
            "type": "main",
            "index": 0
          },
          {
            "node": "Ground Truth",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}