{
  "nodes": [
    {
      "parameters": {
        "formTitle": "file upload",
        "formFields": {
          "values": [
            {
              "fieldLabel": "files",
              "fieldType": "file",
              "acceptFileTypes": ".pdf",
              "requiredField": true
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.3,
      "position": [
        -2128,
        16
      ],
      "id": "66526d50-ed9e-49ae-b6a5-52878b666c99",
      "name": "On form submission",
      "webhookId": "993ca39c-2d05-4bd9-a9cb-553519ba8bbd"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://172.16.2.210:5001/v1/convert/file",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "files",
              "inputDataFieldName": "files"
            },
            {
              "name": "to_formats",
              "value": "md"
            },
            {
              "name": "do_ocr",
              "value": "true"
            },
            {
              "name": "pdf_backend",
              "value": "dlparse_v2"
            },
            {
              "name": "include_images",
              "value": "false"
            },
            {
              "name": "ocr_engine",
              "value": "rapidocr"
            },
            {
              "name": "image_export_mode",
              "value": "placeholder"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        -1904,
        16
      ],
      "id": "d69077d1-f63f-4d6c-8e50-9f85345926d2",
      "name": "Docling PDF File to Markdown"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Resume text:\n\n```\n{{ $json.document.md_content }}\n```",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "You are a deterministic resume parser.\n\nTASK\nExtract personal contact information from the resume text.\n\nIMPORTANT RULES\n\n1. Output ONLY valid JSON.\n2. Do NOT explain anything.\n3. Do NOT rewrite or modify the resume text.\n4. The field \"text_content\" MUST contain the ORIGINAL input text unchanged.\n5. Do NOT remove headers, sections, or formatting.\n6. If a field does not exist return \"\".\n7. Phone numbers must contain only digits.\n8. Convert +84XXXXXXXXX → 0XXXXXXXXX.\n\nFIELDS\n\nfull_name\nphone\nemail\ngithub\nlinkedin\n\nPhone numbers may appear as:\n\n0901234567\n090 123 4567\n090-123-4567\n+84 901234567\n\nGitHub links contain:\ngithub.com\n\nLinkedIn links contain:\nlinkedin.com\n\nOUTPUT FORMAT\n\n{\n  \"personal_info\": {\n    \"full_name\": \"\",\n    \"phone\": \"\",\n    \"email\": \"\",\n    \"github\": \"\",\n    \"linkedin\": \"\"\n  },\n  \"text_content\": \"\"\n}\n\n\"text_content\" MUST be exactly the same as the input resume text.\n\nThe output MUST start with { and end with }."
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        -1712,
        16
      ],
      "id": "7fefead1-a300-4620-aee8-15690bfb58b5",
      "name": "SLM Pre-processing"
    },
    {
      "parameters": {
        "model": "llama3.2:3b",
        "options": {
          "temperature": 0,
          "topP": 0.9,
          "numGpu": 0,
          "numThread": 8,
          "repeatPenalty": 1.1,
          "useMMap": false,
          "format": "json"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        -1760,
        208
      ],
      "id": "0637d819-80e8-4b0c-a093-ec93c6631d1e",
      "name": "ollama",
      "credentials": {
        "ollamaApi": {
          "id": "5UV79EpXVnQk7vut",
          "name": "Ollama CPU-only"
        }
      }
    },
    {
      "parameters": {
        "model": "llama3.2:3b",
        "options": {
          "temperature": 0,
          "numGpu": 0,
          "numThread": 8,
          "repeatPenalty": 1.1,
          "useMMap": false,
          "format": "json"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        -1424,
        224
      ],
      "id": "52039d21-b5fc-477d-91a1-5a2f69218e73",
      "name": "ollama-1",
      "credentials": {
        "ollamaApi": {
          "id": "5UV79EpXVnQk7vut",
          "name": "Ollama CPU-only"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Extract this text\n\n```\n{{ $('SLM Pre-processing').item.json.text_content }}\n```",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "You are a resume document segmenter.\n\nTASK\nSplit the resume text into logical sections.\n\nSECTIONS\n\neducation\nemployment_history\npersonal_projects\n\nRULES\n\n1. Preserve the EXACT original text.\n2. Do NOT summarize.\n3. Do NOT rewrite sentences.\n4. Copy the text exactly as it appears.\n5. If a section does not exist return \"\".\n6. A resume may contain headings like:\n\nEducation\nWork Experience\nProfessional Experience\nProjects\nPersonal Projects\n\nMap them to these sections:\n\nEducation → education\nWork Experience / Experience → employment_history\nProjects → personal_projects\n\nOUTPUT FORMAT\n\n{\n  \"education\": \"\",\n  \"employment_history\": \"\",\n  \"personal_projects\": \"\"\n}\n\nEach value must contain the RAW text belonging to that section.\n\nThe output MUST start with { and end with }."
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        -1376,
        16
      ],
      "id": "e132c01e-0504-4068-ac45-5f788101ae25",
      "name": "SLM Section Segmentation"
    }
  ],
  "connections": {
    "On form submission": {
      "main": [
        [
          {
            "node": "Docling PDF File to Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Docling PDF File to Markdown": {
      "main": [
        [
          {
            "node": "SLM Pre-processing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLM Pre-processing": {
      "main": [
        [
          {
            "node": "SLM Section Segmentation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ollama": {
      "ai_languageModel": [
        [
          {
            "node": "SLM Pre-processing",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "ollama-1": {
      "ai_languageModel": [
        [
          {
            "node": "SLM Section Segmentation",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": true,
    "instanceId": "e6335aa52b72b294373f7e9ff2f7b0691634ae094aab25f9e5eea0292f829734"
  }
}