{
  "name": "Invoice Processing - Local Ollama",
  "nodes": [
    {
      "parameters": {
        "formTitle": "Invoice Upload (Ollama)",
        "formDescription": "Upload an invoice (PDF or image) to extract data using local Ollama Qwen3-VL.",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Invoice File",
              "fieldType": "file",
              "requiredField": true,
              "acceptFileTypes": ".png,.jpg,.jpeg,.webp,.pdf"
            }
          ]
        },
        "options": {
          "respondWithOptions": {
            "values": {
              "formSubmittedText": "Processing your invoice... Check Executions tab for results."
            }
          }
        }
      },
      "id": "form-trigger",
      "name": "Upload Invoice Form",
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.2,
      "position": [250, 300],
      "webhookId": "invoice-form-ollama"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://host.docker.internal:11434/api/generate",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"model\": \"qwen3-vl\",\n  \"prompt\": \"Analyze this invoice and extract all data as JSON. Return ONLY valid JSON with this exact structure:\\n{\\n  \\\"vendor\\\": { \\\"name\\\": \\\"\\\", \\\"address\\\": \\\"\\\", \\\"tax_id\\\": \\\"\\\" },\\n  \\\"invoice\\\": { \\\"number\\\": \\\"\\\", \\\"date\\\": \\\"\\\", \\\"due_date\\\": \\\"\\\" },\\n  \\\"line_items\\\": [{ \\\"description\\\": \\\"\\\", \\\"quantity\\\": 0, \\\"unit_price\\\": 0, \\\"total\\\": 0 }],\\n  \\\"totals\\\": { \\\"net\\\": 0, \\\"tax_rate\\\": 0, \\\"tax_amount\\\": 0, \\\"gross\\\": 0 }\\n}\\nNo explanation, no markdown, just the JSON object.\",\n  \"images\": [\"{{ $binary['Invoice File'].data }}\"],\n  \"stream\": false\n}",
        "options": {
          "timeout": 180000
        }
      },
      "id": "ollama-vision",
      "name": "Ollama Qwen3-VL",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [470, 300]
    },
    {
      "parameters": {
        "jsCode": "const response = $input.first().json;\n\ntry {\n  let content = response.response || '';\n  content = content.replace(/```json\\n?/gi, '').replace(/```\\n?/g, '').trim();\n  \n  const jsonMatch = content.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    const parsed = JSON.parse(jsonMatch[0]);\n    return {\n      json: {\n        success: true,\n        invoice_data: parsed,\n        processed_at: new Date().toISOString(),\n        model: 'qwen3-vl (local)'\n      }\n    };\n  } else {\n    throw new Error('No JSON found in response');\n  }\n} catch (error) {\n  return {\n    json: {\n      success: false,\n      error: error.message,\n      raw_response: response.response?.substring(0, 500)\n    }\n  };\n}"
      },
      "id": "parse-response",
      "name": "Parse Result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [690, 300]
    }
  ],
  "connections": {
    "Upload Invoice Form": {
      "main": [
        [
          {
            "node": "Ollama Qwen3-VL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Qwen3-VL": {
      "main": [
        [
          {
            "node": "Parse Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "instanceId": "starter-workflow"
  }
}
