{
  "updatedAt": "2026-06-04T00:29:01.241Z",
  "createdAt": "2026-04-28T13:41:41.456Z",
  "id": "97Z8vSF1pNUGGjsB",
  "name": "Takyk Terjime Otomasyonu v2.0",
  "description": "takyk terj\u00fcme otomasyonu",
  "active": false,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "jsCode": "\nconst item = $input.item.json;\nconst body = item.body || item;\nlet updateType = 'other';\nif (body.callback_query) {\n  updateType = 'callback';\n} else if (body.message && (body.message.document || body.message.photo)) {\n  updateType = 'document';\n}\nreturn [{ json: { ...body, _updateType: updateType } }];\n"
      },
      "id": "d47fe8ea-63d4-4b9d-be65-864d1f2c478d",
      "name": "\ud83d\udd00 G\u00fcncelleme T\u00fcr\u00fcn\u00fc Belirle",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1312,
        224
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "cb-1",
              "leftValue": "={{ $json._updateType }}",
              "rightValue": "callback",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "f7f068e2-9422-4412-a1f9-8af590d034e5",
      "name": "\u2753 Callback m\u0131?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -1088,
        224
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "doc-1",
              "leftValue": "={{ $json._updateType }}",
              "rightValue": "document",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "7bd619ad-b4b7-411b-b173-4d2758701cbd",
      "name": "\u2753 Belge/Foto\u011fraf Var m\u0131?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -864,
        704
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n  chat_id: $json.message?.chat?.id || $json.callback_query?.message?.chat?.id,\n  text: \"\u26a0\ufe0f L\u00fctfen bir <b>belge, PDF veya foto\u011fraf</b> g\u00f6nderin.\\n\\nDesteklenen formatlar: PDF, JPG, PNG, DOCX\",\n  parse_mode: \"HTML\"\n}) }}",
        "options": {}
      },
      "id": "89b71324-8bd1-43cf-8882-fb836208519b",
      "name": "\u26d4 Belge Yok Uyar\u0131s\u0131 G\u00f6nder",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -640,
        800
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst body = $input.item.json.body || $input.item.json;\nconst msg = body.message;\n\nlet fileId, mimeType, filename;\n\nif (msg.document) {\n  fileId    = msg.document.file_id;\n  mimeType  = msg.document.mime_type || 'application/octet-stream';\n  filename  = msg.document.file_name || 'belge';\n} else if (msg.photo) {\n  // En b\u00fcy\u00fck foto\u011fraf\u0131 al\n  const photos = msg.photo;\n  const largest = photos.sort((a,b) => b.file_size - a.file_size)[0];\n  fileId   = largest.file_id;\n  mimeType = 'image/jpeg';\n  filename = 'foto.jpg';\n}\n\nreturn [{\n  json: {\n    file_id:   fileId,\n    mime_type: mimeType,\n    filename:  filename,\n    chat_id:   String(msg.chat.id),\n    user_name: msg.from?.first_name || 'Kullan\u0131c\u0131'\n  }\n}];\n"
      },
      "id": "613b1f60-c369-4eb7-964b-212b06f225f8",
      "name": "\ud83d\uddc2 Dosya Bilgisi Al",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -640,
        608
      ]
    },
    {
      "parameters": {
        "url": "={{ 'https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getFile?file_id=' + $json.file_id }}",
        "options": {}
      },
      "id": "a8c91c6d-0e0b-4255-90b8-40c2748c9868",
      "name": "\ud83d\udce1 Telegram: Dosya Yolunu Al",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -416,
        608
      ]
    },
    {
      "parameters": {
        "url": "={{ 'https://api.telegram.org/file/bot<TELEGRAM_BOT_TOKEN>/' + $json.result.file_path }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "id": "ac8ce1d2-6115-491c-9d20-508133bff322",
      "name": "\u2b07\ufe0f Dosyay\u0131 \u0130ndir",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -192,
        608
      ]
    },
    {
      "parameters": {
        "jsCode": "\n// 1. Ham dosyay\u0131 diskten okuyup Base64 format\u0131na \u00e7evir\nconst binaryData = await this.helpers.getBinaryDataBuffer(0, 'data');\nconst base64 = binaryData.toString('base64');\n\nconst item = $input.all()[0];\nconst prevMeta0 = $('\ud83d\uddc2 Dosya Bilgisi Al').item.json;\nconst fn0 = (prevMeta0.filename || '').toLowerCase();\nlet mimeType = item.binary?.data?.mimeType || prevMeta0.mime_type || 'image/jpeg';\n// PDF'i jpeg'e EZME: dosya ad\u0131/uzant\u0131s\u0131 .pdf ise application/pdf kullan\nif (fn0.endsWith('.pdf') || mimeType === 'application/pdf') {\n  mimeType = 'application/pdf';\n} else if (mimeType === 'application/octet-stream' || !mimeType) {\n  mimeType = fn0.endsWith('.png') ? 'image/png' : 'image/jpeg';\n}\n\nconst CLASSIFY_PROMPT = `Bu resmi belgeyi analiz et.\n\u00d6NEML\u0130 \u0130PUCU: Belgede bir ki\u015finin foto\u011fraf\u0131 varsa ve en alt k\u0131s\u0131mda 'P<TKM...' ile ba\u015flayan makine kodlar\u0131 (MRZ \u015feridi) yer al\u0131yorsa, bu KES\u0130NL\u0130KLE \"PASAPORT_ZAGRAN\"d\u0131r.\n\nSADECE a\u015fa\u011f\u0131daki JSON format\u0131nda yan\u0131t ver, ba\u015fka hi\u00e7bir \u015fey yazma:\n{\n  \"document_type\": \"PASAPORT_ZAGRAN|PASAPORT_ICERKI|PASAPORT_ICERKI_ESKI|DOGUM_KISA|DOGUM_UZUN|DOGUM_OLMADIK|LISE_DIPLOMASI|ATESTAT_MODERN|ATESTAT_ESKI|TRANSKRIPT|ADLI_SICIL|SABIKA|BEKARLIK_BELGESI|EVLILIK_KISA|EVLILIK_UZUN|BOSANMA_S|BOSANMA_Z|SAGLIK_RAPORU|TASDIK_BELGESI|IKAMET_IZNI|SEYAHAT_TAAHHUT|MUVAFAKATNAME|SPONSOR_MEKTUBU|VEKALETNAME|PATENT|ISTIHDAM_KAYIT|KEPILNAMA|EMEKLILIK_TEYIT|OLUM|SURUCU_BELGESI|MAAS_BORDRO|NOTER_DILEKCE|KABUL_MEKTUBU|IKAMETGAH|AILE_DURUM|DEKLARASYON|DIGER\",\n  \"source_language\": \"TURKMENCE|RUSCA|INGILIZCE|DIGER\",\n  \"country\": \"\u00fclke ad\u0131\",\n  \"description\": \"k\u0131sa T\u00fcrk\u00e7e a\u00e7\u0131klama\",\n  \"confidence\": 0.95\n}`;\n\nconst isPdf = (mimeType === 'application/pdf');\nconst filePart = isPdf\n  ? { type: 'file', file: { filename: (prevMeta0.filename || 'belge.pdf'), file_data: 'data:application/pdf;base64,' + base64 } }\n  : { type: 'image_url', image_url: { url: 'data:' + mimeType + ';base64,' + base64 } };\nconst geminiBody = {\n  messages: [{ role: 'user', content: [ filePart, { type: 'text', text: CLASSIFY_PROMPT } ] }],\n  temperature: 0.05,\n  response_format: { type: 'json_object' }\n};\nif (isPdf) geminiBody.plugins = [{ id: 'file-parser', pdf: { engine: 'native' } }];\n\nconst prevMeta = $('\ud83d\uddc2 Dosya Bilgisi Al').item.json;\n\nreturn [{\n  json: {\n    geminiBody: geminiBody,\n    _meta: {\n      chat_id:   prevMeta.chat_id,\n      mime_type: mimeType,\n      filename:  prevMeta.filename,\n      base64:    base64,\n      user_name: prevMeta.user_name\n    }\n  }\n}];\n"
      },
      "id": "5a0235c6-e9f4-42f0-9f03-d178f67e2740",
      "name": "\ud83d\udd27 Gemini Classify \u0130ste\u011fi Haz\u0131rla",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        32,
        608
      ]
    },
    {
      "parameters": {
        "jsCode": "\n// === OpenRouter cagrisi (google/gemini-3.5-flash, ucretli tek anahtar) ===\n// Tum item'lar Promise.all ile ESZAMANLI islenir (task-runner zaman limitine takilmamak icin).\n// Gecici hatada node-seviyesi retryOnFail devreye girer; kalici hatada kullaniciya Telegram'dan nazik mesaj.\nconst KEY = '<OPENROUTER_API_KEY>';\nconst MODEL = 'google/gemini-3.5-flash';\nconst TG_TOKEN = '<TELEGRAM_BOT_TOKEN>';\nconst items = $input.all();\nconst helpers = this.helpers;\nlet notified = false;\nconst statusOf = (e) => Number(e?.httpCode ?? e?.statusCode ?? e?.response?.statusCode ?? e?.cause?.statusCode ?? e?.cause?.response?.status ?? 0);\n\nconst notify = async (chatId) => {\n  if (notified || !chatId || !TG_TOKEN || TG_TOKEN[0] === '<') return;\n  notified = true;\n  try {\n    await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://api.telegram.org/bot' + TG_TOKEN + '/sendMessage',\n      body: { chat_id: chatId, text: 'Sistem su an cevap veremedi. Lutfen biraz sonra belgeyi tekrar gonderin.' },\n      json: true, timeout: 15000,\n    });\n  } catch (_) {}\n};\n\nconst callOne = async (item, it) => {\n  const inJson = item.json;\n  const body = inJson.geminiBody;\n  if (!body) return { json: inJson, pairedItem: { item: it } };\n  body.model = MODEL;\n  const chatId = inJson.chat_id || (inJson._meta && inJson._meta.chat_id);\n  try {\n    const resp = await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://openrouter.ai/api/v1/chat/completions',\n      headers: { 'Authorization': 'Bearer ' + KEY, 'Content-Type': 'application/json', 'X-Title': 'Takyk Terjime' },\n      body,\n      json: true,\n      timeout: 120000,\n    });\n    return { json: resp, pairedItem: { item: it } };\n  } catch (e) {\n    await notify(chatId);\n    throw new Error('OpenRouter cagrisi basarisiz item ' + it + ' durum=' + statusOf(e) + ': ' + (e && (e.message || e)));\n  }\n};\n\nreturn await Promise.all(items.map((item, it) => callOne(item, it)));\n"
      },
      "id": "14023c51-f0d0-4ab4-9f02-9925bd794c54",
      "name": "\ud83e\udd16 Gemini: Belge S\u0131n\u0131fland\u0131r",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        256,
        608
      ],
      "retryOnFail": true,
      "waitBetweenTries": 8000,
      "maxTries": 5
    },
    {
      "parameters": {
        "jsCode": "\nconst item = $input.item.json;\nconst geminiResp = item.choices?.[0]?.message?.content || '{}';\n\nlet classification;\ntry {\n  const cleaned = geminiResp.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n  classification = JSON.parse(cleaned);\n} catch(e) {\n  classification = {\n    document_type: 'DIGER',\n    source_language: 'DIGER',\n    description: 'Otomatik tan\u0131ma ba\u015far\u0131s\u0131z',\n    confidence: 0\n  };\n}\n\nconst meta = $('\ud83d\udd27 Gemini Classify \u0130ste\u011fi Haz\u0131rla').item.json._meta;\n\nconst DOC_LABELS = {\n  'PASAPORT':         '\ud83d\udec2 Pasaport (Zagranpasport)',\n  'DOGUM_BELGESI':    '\ud83d\udcdc Do\u011fum Belgesi (Metrika)',\n  'LISE_DIPLOMASI':   '\ud83c\udf93 Lise Diplomas\u0131 (Attestat)',\n  'TRANSKRIPT':       '\ud83d\udcca Transkript / Not D\u00f6k\u00fcm\u00fc',\n  'MUVAFAKATNAME':    '\ud83d\udcdd Muvafakatname (Veli \u0130zni)',\n  'ADLI_SICIL':       '\u2696\ufe0f Adli Sicil (Sab\u0131ka Kayd\u0131)',\n  'BEKARLIK_BELGESI': '\ud83d\udc8d Bekarl\u0131k / Evlenme Ehliyet',\n  'EVLILIK_CUZDANI':  '\ud83d\udc6a Evlilik C\u00fczdan\u0131 (Nika \u015eahadetnamesi)',\n  'SAGLIK_RAPORU':    '\ud83c\udfe5 Sa\u011fl\u0131k Raporu',\n  'VEKALETNAME':      '\ud83d\udcd1 Vekaletname',\n  'NOTER_DILEKCE':    '\ud83d\udcdd Noter Dilek\u00e7esi / Sponsorluk',\n  'SPONSOR_MEKTUBU':  '\ud83e\udd1d Sponsorluk Mektubu',\n  'DIGER':            '\ud83d\udcc4 Di\u011fer Belge'\n};\n\nconst LANG_LABELS = {\n  'TURKMENCE': 'T\u00fcrkmence',\n  'RUSCA': 'Rus\u00e7a',\n  'INGILIZCE': '\u0130ngilizce',\n  'DIGER': 'Bilinmiyor'\n};\n\nconst docLabel  = DOC_LABELS[classification.document_type] || classification.document_type;\nconst langLabel = LANG_LABELS[classification.source_language] || classification.source_language;\n\nreturn [{\n  json: {\n    chat_id:        meta.chat_id,\n    user_name:      meta.user_name,\n    document_type:  classification.document_type,\n    source_language: classification.source_language,\n    description:    classification.description,\n    confidence:     classification.confidence,\n    doc_label:      docLabel,\n    lang_label:     langLabel,\n    mime_type:      meta.mime_type,\n    filename:       meta.filename,\n    file_base64:    meta.base64,\n    add_doc_body: {\n      file_base64:      meta.base64,\n      mime_type:        meta.mime_type,\n      filename:         meta.filename,\n      document_type:    classification.document_type,\n      source_language:  classification.source_language || '',\n      description:      classification.description || '',\n      confidence:       classification.confidence || 0\n    }\n  }\n}];\n"
      },
      "id": "9487507a-a2ea-492f-8ac1-ad391dc1711b",
      "name": "\ud83d\udcca S\u0131n\u0131fland\u0131rma Ayr\u0131\u015ft\u0131r + Klavye Haz\u0131rla",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        608
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ 'http://<SERVICE_HOST>:8005/state/' + $json.chat_id + '/add_document' }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.add_doc_body) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "637e001b-7e1f-4401-93b3-b12155c739b5",
      "name": "\ud83d\udcbe State'i Kaydet",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        704,
        608
      ]
    },
    {
      "parameters": {
        "jsCode": "// Backend zamanlayici ile ozet mesaj gonderilecek\n// Bu dugum sadece pass-through\nreturn $input.all();"
      },
      "id": "cbedd5ea-c547-4111-8922-f93717b35cb4",
      "name": "\u2328\ufe0f Dil Se\u00e7im Klavyesi G\u00f6nder",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        928,
        608
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst body = $input.item.json.body || $input.item.json;\nconst cb = body.callback_query;\nconst chatId = String(cb.message.chat.id);\nconst data = cb.data;\nconst msgId = cb.message.message_id;\n\nlet targetLang = 'TR';\nlet langName = 'T\u00fcrk\u00e7e \ud83c\uddf9\ud83c\uddf7';\n\nif (data === 'lang_TR') { targetLang = 'TR'; langName = 'T\u00fcrk\u00e7e \ud83c\uddf9\ud83c\uddf7'; }\nelse if (data === 'lang_RU') { targetLang = 'RU'; langName = 'Rus\u00e7a \ud83c\uddf7\ud83c\uddfa'; }\nelse if (data === 'lang_EN') { targetLang = 'EN'; langName = '\u0130ngilizce \ud83c\uddec\ud83c\udde7'; }\n\nreturn [{\n  json: {\n    chat_id: chatId,\n    callback_id: cb.id,\n    message_id: msgId,\n    target_language: targetLang,\n    lang_name: langName,\n    raw_data: data\n  }\n}];\n"
      },
      "id": "7dc110ac-5700-4c55-8263-39507cf177a9",
      "name": "\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -880,
        80
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ 'https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/answerCallbackQuery' }}",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ callback_query_id: $json.callback_id, text: $json.lang_name + \" secildi\" }) }}",
        "options": {}
      },
      "id": "b8b11243-e77e-4889-988e-3988515126f1",
      "name": "\u2705 Callback Sorgusunu Yan\u0131tla",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -672,
        80
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ 'https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage' }}",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n  chat_id: $('\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r').item.json.chat_id,\n  text: '\u274c <b>Oturum s\u00fcresi doldu.</b>\\n\\nL\u00fctfen belgeyi tekrar g\u00f6nderin.',\n  parse_mode: 'HTML'\n}) }}",
        "options": {}
      },
      "id": "1fc97d2e-482c-47f5-a1d5-147336dfb115",
      "name": "\u26d4 Oturum S\u00fcresi Doldu",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        224
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({\n  chat_id: $('\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r').item.json.chat_id,\n  text: '\u23f3 <b>Belge i\u015fleniyor...</b>\\n\\n\ud83d\udd0d OCR ve \u00e7eviri yap\u0131l\u0131yor, l\u00fctfen bekleyin (20-60 sn).',\n  parse_mode: 'HTML'\n}) }}",
        "options": {}
      },
      "id": "bf482a9c-3736-47db-9074-ee7cf48a095e",
      "name": "\u23f3 \u0130\u015fleniyor Mesaj\u0131 G\u00f6nder",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst stateData = $('\ud83d\udcc2 State Yukle').item.json;\nconst callback = $('\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r').item.json;\nconst documents = stateData.documents || [];\nconst typeMap = {\"ADLI_SICIL\": \"SABIKA\", \"SABIKA\": \"SABIKA\", \"LISE_DIPLOMASI\": \"ATESTAT_MODERN\", \"ATESTAT\": \"ATESTAT_MODERN\", \"ATESTAT_MODERN\": \"ATESTAT_MODERN\", \"ATESTAT_ESKI\": \"ATESTAT_ESKI\", \"DOGUM_BELGESI\": \"DOGUM_KISA\", \"DOGUM_KISA\": \"DOGUM_KISA\", \"DOGUM_UZUN\": \"DOGUM_UZUN\", \"DOGUM_OLMADIK\": \"DOGUM_OLMADIK\", \"BEKARLIK_BELGESI\": \"BEKARLIK\", \"BEKARLIK\": \"BEKARLIK\", \"EVLILIK_CUZDANI\": \"EVLILIK_KISA\", \"EVLILIK_KISA\": \"EVLILIK_KISA\", \"EVLILIK_UZUN\": \"EVLILIK_UZUN\", \"BOSANMA_S\": \"BOSANMA_S\", \"BOSANMA_Z\": \"BOSANMA_Z\", \"PASAPORT\": \"PASAPORT_ZAGRAN\", \"PASAPORT_ZAGRAN\": \"PASAPORT_ZAGRAN\", \"PASAPORT_ICERKI\": \"PASAPORT_ICERKI\", \"PASAPORT_ICERKI_ESKI\": \"PASAPORT_ICERKI_ESKI\", \"SURUCU_BELGESI\": \"SURUCU_BELGESI\", \"DEKLARASYON\": \"DEKLARASYON\", \"IKAMET_IZNI\": \"IKAMET_IZNI\", \"PATENT\": \"PATENT\", \"ISTIHDAM_KAYIT\": \"ISTIHDAM_KAYIT\", \"TASDIK_BELGESI\": \"TASDIK_BELGESI\", \"KEPILNAMA\": \"KEPILNAMA\", \"EMEKLILIK_TEYIT\": \"EMEKLILIK_TEYIT\", \"OLUM\": \"OLUM\", \"SEYAHAT_TAAHHUT\": \"SEYAHAT_TAAHHUT\", \"MUVAFAKATNAME\": \"MUVAFAKATNAME\", \"SAGLIK_RAPORU\": \"TASDIK_BELGESI\", \"VEKALETNAME\": \"PATENT\", \"DIGER\": \"DEKLARASYON\", \"TRANSKRIPT\": \"TRANSKRIPT\", \"MAAS_BORDRO\": \"MAAS_BORDRO\", \"MAAS_BELGESI\": \"MAAS_BORDRO\", \"BORDRO\": \"MAAS_BORDRO\", \"NOTER_DILEKCE\": \"NOTER_DILEKCE\", \"NATARIUS_ARZA\": \"NOTER_DILEKCE\", \"ARZA\": \"NOTER_DILEKCE\", \"SPONSOR_MEKTUBU\": \"NOTER_DILEKCE\", \"TAAHHUTNAME\": \"NOTER_DILEKCE\", \"KABUL_MEKTUBU\": \"KABUL_MEKTUBU\", \"KABUL_HATY\": \"KABUL_MEKTUBU\", \"DAVET_MEKTUBU\": \"KABUL_MEKTUBU\", \"MEKDEPTE_OKANLYGY\": \"KEPILNAMA\", \"OKUL_BELGESI\": \"KEPILNAMA\", \"OKUDUGU_YER_BELGESI\": \"KEPILNAMA\", \"OGRENIM_BELGESI\": \"KEPILNAMA\", \"OKUL_TASDIK\": \"KEPILNAMA\", \"IKAMETGAH\": \"IKAMETGAH\", \"TASSYKNAMA_YASAYAN\": \"IKAMETGAH\", \"YASAYAN_YER\": \"IKAMETGAH\", \"YASAYAN_YERI_HAKYNDA\": \"IKAMETGAH\", \"YASAYAN_YER_BELGESI\": \"IKAMETGAH\", \"IKAMETGAH_BELGESI\": \"IKAMETGAH\", \"AILE_DURUM\": \"AILE_DURUM\", \"TASSYKNAMA_MASGALA\": \"AILE_DURUM\", \"MASGALA\": \"AILE_DURUM\", \"MASGALASY_HAKYNDA\": \"AILE_DURUM\", \"AILE_DURUM_BELGESI\": \"AILE_DURUM\", \"AILE_BELGESI\": \"AILE_DURUM\", \"ZAHMET_HAKY\": \"MAAS_BORDRO\", \"ZAHMET_HAKY_KEPILNAMA\": \"MAAS_BORDRO\", \"CALISMA_BELGESI\": \"MAAS_BORDRO\"};\nconst SCHEMAS = {\"ATESTAT_ESKI\": {\"fields\": [\"il\", \"ilce\", \"okul_no\", \"belge_no\", \"tarih\", \"ogrenci_ad_soyad\", \"mezuniyet_yili\", \"mudur_adi\", \"mudur_adi2\", \"hazirlayan2\", \"ogretim_yili_1\", \"ogretim_yili_2\", \"ogretim_yili_3\"], \"loops\": [{\"name\": \"dersler1\", \"item_fields\": [\"ders\", \"n9\", \"n10\", \"n11\"], \"note\": \"1. tablo: ders + 9/10/11 s\u0131n\u0131f notlar\u0131\"}, {\"name\": \"dersler2\", \"item_fields\": [\"sira\", \"ders\", \"y1\", \"y2\", \"y3\"], \"note\": \"2. tablo: s\u0131ra + ders + akademik y\u0131l notlar\u0131 (ogretim_yili_1..3 ba\u015fl\u0131klar\u0131)\"}]}, \"ATESTAT_MODERN\": {\"fields\": [\"seri_no\", \"belge_no\", \"ogrenci_ad_soyad\", \"dogum_tarihi_yazi\", \"dogum_yeri\", \"mezuniyet_yili\", \"okul_tam_adi\", \"davranis_notu\", \"duzenleme_tarihi\", \"muhur\"], \"loops\": [{\"name\": \"dersler\", \"item_fields\": [\"ders\", \"puan\"], \"note\": \"Her ders sat\u0131r\u0131: ders ad\u0131 + tek not ('4 (\u0130yi)' gibi). docxtpl {%tr for d in dersler %} sat\u0131r d\u00f6ng\u00fcs\u00fc.\"}]}, \"BEKARLIK\": {\"fields\": [\"ad_soyad_baba\", \"arsiv_kayit_yeri\", \"baslangic_tarihi\", \"bitis_tarihi\", \"cikis_no\", \"dogum_tarihi\", \"dogum_yeri\", \"hazirlayan_adi\", \"mudur_adi\", \"mudur_kurum\", \"muhur\", \"tarih\", \"veren_kurum\"], \"loops\": []}, \"BOSANMA_S\": {\"fields\": [\"belge_seri_no\", \"bosanma_tarihi\", \"duzenleme_tarihi\", \"kari_ad_soyad_baba\", \"kari_bosanma_sonrasi_soyad\", \"kayit_no\", \"kayit_yeri\", \"koca_ad_soyad_baba\", \"muhur\"], \"loops\": []}, \"BOSANMA_Z\": {\"fields\": [\"belge_seri_no\", \"duzenleme_tarihi\", \"kari_ad_soyad_baba\", \"kari_bosanma_sonrasi_soyad\", \"kayit_no\", \"kayit_yeri\", \"koca_ad_soyad_baba\", \"muhur\"], \"loops\": []}, \"DEKLARASYON\": {\"fields\": [\"ad\", \"adres\", \"baba_adi\", \"belge_no\", \"dogum_tarihi\", \"dogum_yeri\", \"donem\", \"ek_vergi\", \"hsb_no\", \"imza_adi\", \"mudur_adi\", \"odenen_vergi\", \"pasaport_no\", \"pasaport_seri\", \"pasaport_veren\", \"pasaport_verilis_tarihi\", \"soyad\", \"tarih\", \"toplam_gelir\", \"vergi_dairesi\", \"vergi_dairesi_tam\", \"vergi_miktari\"], \"loops\": []}, \"DOGUM_KISA\": {\"fields\": [\"ad\", \"soyad\", \"baba_ad\", \"baba_adi\", \"baba_milliyet\", \"anne_ad\", \"anne_soyad\", \"anne_milliyet\", \"belge_seri_no\", \"dogum_tarihi\", \"dogum_tarihi_yazi\", \"dogum_yeri\", \"dogum_yeri_kasaba\", \"dogum_yeri_ilce\", \"dogum_yeri_il\", \"dogum_yeri_ulke\", \"kayit_no\", \"kayit_tarihi\"], \"loops\": []}, \"DOGUM_OLMADIK\": {\"fields\": [\"ad_soyad\", \"arsiv_kayit_yeri\", \"baslangic_yili\", \"bitis_yili\", \"cikis_no\", \"hazirlayan_adi\", \"mudur_adi\", \"mudur_il\", \"muhur\", \"tarih\", \"veren_kurum\"], \"loops\": []}, \"DOGUM_UZUN\": {\"fields\": [\"ad\", \"anne_ad\", \"anne_milliyet\", \"baba_ad\", \"baba_soyad\", \"belge_seri_no\", \"dogum_tarihi\", \"dogum_tarihi_yazi2\", \"dogum_yeri_il\", \"dogum_yeri_ulke\", \"kayit_no\", \"kayit_tarihi\", \"soyad\", \"verilis_tarihi\"], \"loops\": []}, \"EMEKLILIK_TEYIT\": {\"fields\": [\"ad_soyad_baba\", \"adres\", \"belge_no\", \"dayanak\", \"emeklilik_tarihi\", \"il\", \"ilce\", \"tarih\", \"yardim_miktari\"], \"loops\": []}, \"EVLILIK_KISA\": {\"fields\": [\"belge_seri_no\", \"evlilik_tarihi\", \"evlilik_tarihi_yazi1\", \"evlilik_tarihi_yazi2\", \"kari_ad\", \"kari_baba_adi\", \"kari_dogum_tarihi\", \"kari_dogum_yeri\", \"kari_soyad\", \"kayit_no\", \"kayit_tarihi\", \"kayit_yeri\", \"koca_ad\", \"koca_baba_adi\", \"koca_dogum_tarihi\", \"koca_dogum_yeri\", \"koca_soyad\"], \"loops\": []}, \"EVLILIK_UZUN\": {\"fields\": [\"belge_seri_no\", \"evlilik_tarihi\", \"evlilik_tarihi_yazi\", \"kari_ad\", \"kari_baba_adi\", \"kari_dogum_tarihi\", \"kari_dogum_yeri\", \"kari_soyad\", \"kayit_no\", \"koca_ad\", \"koca_baba_adi\", \"koca_dogum_tarihi\", \"koca_dogum_yeri\", \"koca_milliyet\", \"koca_soyad\", \"verilis_tarihi\"], \"loops\": []}, \"IKAMET_IZNI\": {\"fields\": [\"ad\", \"baba_adi\", \"baslangic_tarihi\", \"belge_no\", \"bitis_tarihi\", \"dogum_tarihi\", \"izin_turu\", \"soyad\", \"uyruk\", \"yabanci_kimlik_no\", \"yasayan_il\"], \"loops\": []}, \"ISTIHDAM_KAYIT\": {\"fields\": [\"ad\", \"baba_adi\", \"defter_seri_no\", \"dogum_tarihi\", \"doldurma_tarihi\", \"egitim_durumu\", \"ik_memuru\", \"ilce_mudurlugu\", \"meslek\", \"sorumlu_adi\", \"soyad\"], \"loops\": []}, \"KABUL_MEKTUBU\": {\"fields\": [\"ref_no\", \"ogrenci_ad_soyad\", \"tarih\", \"pasaport_no\", \"fakulte\", \"okuw_yyly\", \"program_suresi\", \"program_adi\", \"yillik_ucret\", \"dil_ucret\", \"yoksis\", \"barlag_kodu\"], \"loops\": []}, \"KEPILNAMA\": {\"fields\": [\"kurum_satir\", \"belge_no\", \"tarih\", \"ogrenci_ad_soyad\", \"mezuniyet_yili\", \"okul_tam_adi\", \"diploma_no\", \"not_ortalamasi\", \"mudur_adi\", \"muhur\"], \"loops\": []}, \"MAAS_BORDRO\": {\"fields\": [\"isletme_adi\", \"isletme_son_satir\", \"belge_no\", \"tarih\", \"mudur_adi\", \"muhasebeci_adi\", \"hazirlayan_muhasebeci\", \"muhur\", \"calisan_adi\", \"unvan\", \"birim\"], \"loops\": [{\"name\": \"aylar\", \"item_fields\": [\"donem\", \"brut\", \"kesinti\", \"net\"], \"note\": \"Her sat\u0131r: d\u00f6nem (ay/y\u0131l ya da 'TOPLAM') + br\u00fct + kesinti + net. Ara/genel toplam sat\u0131rlar\u0131 dahil. Rakam bi\u00e7imi korunur.\"}]}, \"NOTER_DILEKCE\": {\"fields\": [\"basvuran_ad_soyad\", \"basvuran_adres\", \"basvuran_dogum_tarihi\", \"basvuran_pasaport\", \"cocuk_ad_soyad\", \"cocuk_dogum_tarihi\", \"cocuk_yakinlik\", \"taahhut_kapsami\", \"noter_tarih\", \"noter_yer\", \"noter_yer_tam\", \"noter_ad\", \"noter_imza_adi\", \"noter_belge_no\", \"liste_no\", \"harc\", \"noter_muhur\"], \"loops\": []}, \"MUVAFAKATNAME\": {\"fields\": [\"basvuran_ad_soyad\", \"basvuran_adres\", \"basvuran_dogum_tarihi\", \"basvuran_pasaport\", \"cocuk_ad_soyad\", \"cocuk_dogum_tarihi\", \"cocuk_yakinlik\", \"seyahat_amaci\", \"noter_tarih\", \"noter_yer\", \"noter_yer_tam\", \"noter_ad\", \"noter_imza_adi\", \"noter_belge_no\", \"liste_no\", \"harc\", \"noter_muhur\", \"adalet_yer\", \"adalet_bolum\", \"noter_daire\", \"tasdik_tarih\", \"sicil_no\", \"adalet_mudur_adi\", \"adalet_muhur\"], \"loops\": []}, \"OLUM\": {\"fields\": [\"ad\", \"baba_adi\", \"belge_seri_no\", \"dogum_tarihi\", \"dogum_yeri_il_ilce\", \"dogum_yeri_kasaba\", \"kayit_no\", \"kayit_tarihi\", \"kayit_yeri\", \"muhur\", \"olum_tarihi\", \"olum_tarihi_yazi\", \"olum_yeri\", \"soyad\"], \"loops\": []}, \"PASAPORT_ICERKI\": {\"fields\": [\"ad\", \"baba_adi\", \"belge_no\", \"cinsiyet\", \"dogum_tarihi\", \"dogum_yeri_il\", \"dogum_yeri_ilce\", \"dogum_yeri_kasaba\", \"ikamet_adres2\", \"ikamet_emniyet\", \"ikamet_emniyet2\", \"ikamet_kayit_tarihi\", \"milliyet\", \"mrz_satir1\", \"mrz_satir2\", \"pasaport_seri_no\", \"soyad\", \"verilis_tarihi\"], \"loops\": []}, \"PASAPORT_ICERKI_ESKI\": {\"fields\": [\"ad\", \"baba_adi\", \"belge_no\", \"cinsiyet\", \"dogum_tarihi\", \"dogum_yeri\", \"ikamet_emniyet\", \"ikamet_kayit_tarihi\", \"ikamet_no\", \"ikamet_sokak\", \"milliyet\", \"mrz_satir1\", \"mrz_satir2\", \"pasaport_seri_no\", \"soyad\", \"veren_makam_ilce\", \"verilis_tarihi\"], \"loops\": []}, \"PASAPORT_ZAGRAN\": {\"fields\": [\"ad\", \"belge_no\", \"cinsiyet\", \"dogum_tarihi\", \"gecerlilik_tarihi\", \"mrz_satir1\", \"mrz_satir2\", \"seri_no\", \"soyad\", \"verilis_tarihi\"], \"loops\": []}, \"PATENT\": {\"fields\": [\"ad1\", \"ad2\", \"adres1\", \"adres2\", \"baba_adi1\", \"baba_adi2\", \"faaliyet1\", \"faaliyet2\", \"levha_mudur\", \"levha_no\", \"levha_verilis_tarihi\", \"mersis_no\", \"muhur1\", \"muhur2\", \"pasaport_no1\", \"pasaport_no2\", \"pasaport_seri1\", \"pasaport_veren2\", \"patent_donemi\", \"patent_no\", \"patent_vergisi\", \"patent_verilis_tarihi\", \"soyad1\", \"soyad2\", \"tescil_no\", \"tescil_sertifika_no\", \"tescil_tarihi\", \"tescil_verilis_tarihi\", \"vergi_dairesi\", \"vergi_mudur1\", \"vergi_no1\", \"vergi_no2\"], \"loops\": []}, \"SABIKA\": {\"fields\": [\"ad_soyad_baba_adi\", \"adres\", \"basvuru_amaci\", \"belge_no\", \"dogum_tarihi\", \"muhur\", \"noter_kisaltma\", \"noter_sehir\", \"noter_tarih\", \"pasaport_seri\", \"pasaport_verilis_tarihi\", \"sicil_no\", \"veren_makam\"], \"loops\": []}, \"SEYAHAT_TAAHHUT\": {\"fields\": [\"belge_no\", \"davet_edilen_ad_soyad_baba\", \"davet_edilen_dogum_tarihi\", \"davetci_ad_soyad_baba\", \"davetci_adres\", \"davetci_dogum_tarihi\", \"davetci_pasaport_seri\", \"davetci_pasaport_tarih\", \"davetci_pasaport_veren\", \"muhur\", \"noter_adi\", \"noter_tarih\", \"sicil_no\", \"ziyaret_amaci\"], \"loops\": []}, \"SURUCU_BELGESI\": {\"fields\": [\"ad_baba_adi\", \"belge_no1\", \"belge_no2\", \"dogum_tarihi\", \"dogum_yeri\", \"dogum_yeri_il\", \"gecerlilik_tarihi\", \"soyad\", \"verilis_tarihi\"], \"loops\": []}, \"TASDIK_BELGESI\": {\"fields\": [\"belge_no\", \"belge_no4\", \"calisan_adi\", \"calisan_adi4\", \"diger_ucretler\", \"emeklilik_primi\", \"gelir_vergisi\", \"hazirlayan4\", \"kasaba3\", \"maas2\", \"maas_yazi\", \"maas_yazi2\", \"mudur_adi\", \"mudur_adi2\", \"mudur_adi4\", \"muhasebeci2\", \"muhasebeci4\", \"muhtar3\", \"net_maas\", \"tarih\", \"tarih2\", \"tarih3\", \"tarih4\", \"vatandas3\"], \"loops\": []}, \"TRANSKRIPT\": {\"fields\": [\"egitim_mudurlugu\", \"okul_adi\", \"belge_no\", \"tarih\", \"aciklama\", \"ogrenci_ad_soyad\", \"donem_basliklari\", \"mudur_adi\", \"sinif_ogretmeni_adi\", \"kopya_dogrulayan_adi\", \"muhur\"], \"loops\": [{\"name\": \"dersler\", \"item_fields\": [\"sira\", \"ders\", \"notlar\"], \"note\": \"Her ders sat\u0131r\u0131: s\u0131ra + ders ad\u0131 + notlar (donem_basliklari ile AYNI s\u0131ral\u0131/uzunlukta not dizisi). Davran\u0131\u015f/Disiplin notu sat\u0131r\u0131 da dahil.\"}]}, \"IKAMETGAH\": {\"fields\": [\"kurum_satir\", \"kurum_kisa\", \"belge_no\", \"tarih\", \"vatandas_ad_soyad\", \"dogum_tarihi\", \"ikamet_adres\", \"belde_adi\", \"muhtar_adi\", \"muhtar_yardimci_adi\", \"muhur\"], \"loops\": []}, \"AILE_DURUM\": {\"fields\": [\"kurum_satir\", \"kurum_kisa\", \"belge_no\", \"tarih\", \"vatandas_ad_soyad\", \"vatandas_dogum_yili\", \"adres\", \"belde_adi\", \"muhtar_adi\", \"katip_adi\", \"muhur\"], \"loops\": [{\"name\": \"aile_uyeleri\", \"item_fields\": [\"sira\", \"ad_soyad\", \"dogum_yili\", \"yakinlik\"], \"note\": \"Her sat\u0131r bir aile ferdi: s\u0131ra + Soyad\u0131 Ad\u0131 Baba ad\u0131 + do\u011fum y\u0131l\u0131 + akrabal\u0131k (Babas\u0131/Annesi/Karde\u015fi).\"}]}};\nlet results = [];\nfor (let i = 0; i < documents.length; i++) {\n  const doc = documents[i];\n  const mimeType = doc.mime_type || 'image/jpeg';\n  const rawType = doc.document_type || 'DIGER';\n  const tplKey = typeMap[rawType] || rawType;\n  const spec = SCHEMAS[tplKey] || SCHEMAS['DEKLARASYON'];\n  const schema = (spec.fields || []).join(', ');\n  let loopInstr = '';\n  (spec.loops || []).forEach(l => { loopInstr += `\\n- Ayr\u0131ca '${l.name}' adl\u0131 JSON dizisi olarak ver: [{${(l.item_fields||[]).join(', ')}}]. Belgedeki T\u00dcM sat\u0131rlar\u0131 ekle.`; });\n  let noterInstr = '';\n  if (tplKey === 'NOTER_DILEKCE') { noterInstr = `\\n- NOTER D\u0130LEK\u00c7E: 'basvuran_pasaport' = pasaportun TAM verili\u015f ifadesi (veren makam + tarih + seri/numara birlikte; \u00f6r. \"[\u0130l] [il\u00e7e] ad. il\u00e7e valili\u011fi taraf\u0131ndan GG.AA.YYYY tarihinde XX-NN NNNNNN nolu pasaport verilen\"), SADECE numara DE\u011e\u0130L. 'noter_ad' = noterin ADI SOYADI (bi\u00e7im: \"Soyad\u0131 Ad\u0131 Baba Ad\u0131\"), unvan/makam ad\u0131 DE\u011e\u0130L. 'noter_yer' VE 'noter_yer_tam' = i\u015flemin yap\u0131ld\u0131\u011f\u0131 TAM yer (\"T\u00fcrkmenistan, Lebap ili, Kerki il\u00e7esi, Kerki \u015fehri\"), k\u0131saltma/tek kelime DE\u011e\u0130L. 'noter_belge_no' = belgenin k\u00f6\u015fesindeki/en alt\u0131ndaki MATBU form seri numaras\u0131 \u2014 SADECE rakam (bi\u00e7im: 7 haneli, \u00f6r. \"NNNNNNN\"), \u2116 i\u015faretini EKLEME; kay\u0131t/sicil numaras\u0131 DE\u011e\u0130L. 'liste_no' = \"Sanawda ... bellige alyndy\" kay\u0131t numaras\u0131 (bi\u00e7im: \"N-NNNN\"). 'cocuk_yakinlik' = sponsor edilen ki\u015finin belgedeki s\u0131fat\u0131/yak\u0131nl\u0131\u011f\u0131 (ra\u00fdat -> \"vatanda\u015f\"; oglum/gyzym gibi ise aynen \u00e7evir). 'taahhut_kapsami' = ba\u015fvuran\u0131n \u00fcstlendi\u011fi masraf\u0131n T\u00dcR\u00dc/kapsam\u0131, k\u0131sa ifade; \"onun ___ sa\u011flanan masraflar\u0131n\u0131\" bo\u015flu\u011funa oturur (\u00f6r. \u00fda\u015fa\u00fdy\u015f we i\u00fdmit \u00fc\u00e7in -> \"konaklama ve yemek i\u00e7in\"; okuw/bilim \u00fc\u00e7in -> \"e\u011fitim i\u00e7in\"). UYDURMA, belgeden al.`; }\n  const EXTRACT_PROMPT = `Bu resmi belgedeki T\u00dcM bilgileri \u00e7\u0131kart. T\u00fcrkmen/Rus/T\u00fcrk\u00e7e dilinde yaz\u0131lm\u0131\u015f olabilir.\n\n\u015eu alanlar\u0131 JSON olarak d\u00f6nd\u00fcr (bo\u015f olanlar\u0131 \"\" b\u0131rak):\n${schema}\n\nKURALLAR:\n- Anahtar isimlerini AYNEN yukar\u0131daki gibi kullan, DE\u011e\u0130\u015eT\u0130RME.\n- Tarihleri GG.AA.YYYY format\u0131nda yaz.\n- \u0130simleri orijinal Latin harfleriyle yaz (\u00e7evirme).\n- MRZ sat\u0131rlar\u0131n\u0131 oldu\u011fu gibi kopyala.\n- T\u00fcrkmen yer/kurum adlar\u0131n\u0131 standart T\u00fcrk\u00e7e kar\u015f\u0131l\u0131\u011f\u0131yla normalize et (D\u00f6wletli->D\u00f6vletli, K\u00f6\u00fdtendag->K\u00f6ytendag, wela\u00fdat->il [ASLA 'vilayet'/'vilayeti' yazma; 'Lebap ili' gibi], etrap->il\u00e7e, \u015f\u00e4her->\u015fehir, \u015f\u00e4her\u00e7e->kasaba, ge\u0148e\u015f/ge\u0148e\u015flik->muhtarl\u0131k).\n- Anne ve baba i\u00e7in soyad/milliyet alanlar\u0131n\u0131 AYRI \u00e7\u0131kar; kar\u0131\u015ft\u0131rma.\n- _yazi ile biten tarih alanlar\u0131n\u0131 T\u00dcRK\u00c7E yaz\u0131yla ver (\u00f6r: \"on \u00fc\u00e7 \u015eubat iki bin bir\").\n- Bile\u015fik yer alan\u0131n\u0131 (dogum_yeri) \"\u0130l ili \u0130l\u00e7e il\u00e7esi Kasaba\" bi\u00e7iminde birle\u015fik ver; ayr\u0131ca _kasaba/_ilce/_il alanlar\u0131n\u0131 ayr\u0131 doldur.\n- Pasaport: belge_no = pasaport numaras\u0131 (\u00fcstte, A ile ba\u015flar); seri_no = Kimlik/\u015fahsi numara (LG ile ba\u015flar, MRZ 2. sat\u0131r sonunda).\n- Maa\u015f/bordro: isletme_adi = kurumun TAM \u00e7ok sat\u0131rl\u0131 ad\u0131 (bakanl\u0131k \u2192 il \u2192 il\u00e7e \u2192 birim).\n- TRANSKRIPT: 'egitim_mudurlugu' = sol kutudaki kurum blo\u011fu (E\u011fitim Bakanl\u0131\u011f\u0131 + il Genel E\u011fitim M\u00fcd\u00fcrl\u00fc\u011f\u00fc); 'okul_adi' = okul/lise ad\u0131. 'aciklama' = tablonun \u00dcST\u00dcNDEK\u0130 a\u00e7\u0131klay\u0131c\u0131 c\u00fcmleyi TEK paragraf olarak ver (okul tam ad\u0131 + \u00f6\u011fretim y\u0131l\u0131 + tamamlanan/okunan s\u0131n\u0131f + varsa diploma no + \u00f6\u011frenci ad\u0131 + hangi s\u0131n\u0131flar\u0131n notlar\u0131); mezunsa \"... e\u011fitim-\u00f6\u011fretim y\u0131l\u0131nda ... s\u0131n\u0131f\u0131n\u0131 tamamlay\u0131p, ... numaral\u0131 lise diplomas\u0131n\u0131 alan X'in ... s\u0131n\u0131flar\u0131nda ald\u0131\u011f\u0131\", okuyorsa \"... okumakta olan X'in ... s\u0131n\u0131flar\u0131nda ald\u0131\u011f\u0131\"; \"NOTLARININ D\u00d6K\u00dcM\u00dc\" ba\u015fl\u0131\u011f\u0131n\u0131 EKLEME. 'donem_basliklari' = her not s\u00fctununun ba\u015fl\u0131\u011f\u0131n\u0131 i\u00e7eren JSON dizisi; her tam \u00f6\u011fretim y\u0131l\u0131 bir ba\u015fl\u0131k (\u00f6r. \"2024-2025 (11. s\u0131n\u0131f)\"), \u00f6\u011frenci y\u0131l\u0131 bitirmediyse o y\u0131l 4 \u00e7eyre\u011fe b\u00f6l\u00fcn\u00fcr ve HER \u00e7eyrek AYRI ba\u015fl\u0131k olur (\u00f6r. \"2025-2026 I. \u00e7eyrek\", \"2025-2026 II. \u00e7eyrek\" ...). 'dersler' i\u00e7indeki her dersin 'notlar' alan\u0131 bu ba\u015fl\u0131klarla AYNI SIRADA ve AYNI UZUNLUKTA not dizisidir; bo\u015f h\u00fccre i\u00e7in \"\". 'mudur_adi'/'sinif_ogretmeni_adi'/'kopya_dogrulayan_adi' = imza sahipleri; 'muhur' = yuvarlak m\u00fch\u00fcr (tu\u011fral\u0131) metni.\n- Belgede olmayan alan\u0131 \"\" bo\u015f b\u0131rak, UYDURMA.${noterInstr}${loopInstr}\n\nSADECE JSON d\u00f6nd\u00fcr, ba\u015fka bir \u015fey yazma.`;\n  const isPdf = (mimeType === 'application/pdf'); const filePart = isPdf ? { type: 'file', file: { filename: (doc.filename || 'belge.pdf'), file_data: 'data:application/pdf;base64,' + doc.file_base64 } } : { type: 'image_url', image_url: { url: 'data:' + mimeType + ';base64,' + doc.file_base64 } }; const geminiBody = { messages: [{ role: 'user', content: [ filePart, { type: 'text', text: EXTRACT_PROMPT } ] }], temperature: 0.1, response_format: { type: 'json_object' } }; if (isPdf) geminiBody.plugins = [{ id: 'file-parser', pdf: { engine: 'native' } }];\n  results.push({ json: { geminiBody, document_type: rawType, template_key: tplKey, source_language: doc.source_language || '', chat_id: callback.chat_id, target_language: callback.target_language, lang_name: callback.lang_name, doc_index: i, doc_total: documents.length, mime_type: mimeType, filename: doc.filename || 'belge' }});\n}\nif (results.length === 0 && stateData.document_type) {\n  const rawType = stateData.document_type; const tplKey = typeMap[rawType] || rawType;\n  results.push({ json: { geminiBody:{messages:[{role:'user',content:'Belge bulunamad\u0131'}]}, document_type:rawType, template_key:tplKey, chat_id:callback.chat_id, target_language:callback.target_language, lang_name:callback.lang_name, doc_index:0, doc_total:1 }});\n}\nreturn results;\n"
      },
      "id": "1b6eb80c-be4c-453b-871e-98c9e31f2589",
      "name": "\ud83d\udd27 Gemini Extract \u0130ste\u011fi Haz\u0131rla",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        224,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "\n// === OpenRouter cagrisi (google/gemini-3.5-flash, ucretli tek anahtar) ===\n// Tum item'lar Promise.all ile ESZAMANLI islenir (task-runner zaman limitine takilmamak icin).\n// Gecici hatada node-seviyesi retryOnFail devreye girer; kalici hatada kullaniciya Telegram'dan nazik mesaj.\nconst KEY = '<OPENROUTER_API_KEY>';\nconst MODEL = 'google/gemini-3.5-flash';\nconst TG_TOKEN = '<TELEGRAM_BOT_TOKEN>';\nconst items = $input.all();\nconst helpers = this.helpers;\nlet notified = false;\nconst statusOf = (e) => Number(e?.httpCode ?? e?.statusCode ?? e?.response?.statusCode ?? e?.cause?.statusCode ?? e?.cause?.response?.status ?? 0);\n\nconst notify = async (chatId) => {\n  if (notified || !chatId || !TG_TOKEN || TG_TOKEN[0] === '<') return;\n  notified = true;\n  try {\n    await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://api.telegram.org/bot' + TG_TOKEN + '/sendMessage',\n      body: { chat_id: chatId, text: 'Sistem su an cevap veremedi. Lutfen biraz sonra belgeyi tekrar gonderin.' },\n      json: true, timeout: 15000,\n    });\n  } catch (_) {}\n};\n\nconst callOne = async (item, it) => {\n  const inJson = item.json;\n  const body = inJson.geminiBody;\n  if (!body) return { json: inJson, pairedItem: { item: it } };\n  body.model = MODEL;\n  const chatId = inJson.chat_id || (inJson._meta && inJson._meta.chat_id);\n  try {\n    const resp = await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://openrouter.ai/api/v1/chat/completions',\n      headers: { 'Authorization': 'Bearer ' + KEY, 'Content-Type': 'application/json', 'X-Title': 'Takyk Terjime' },\n      body,\n      json: true,\n      timeout: 120000,\n    });\n    return { json: resp, pairedItem: { item: it } };\n  } catch (e) {\n    await notify(chatId);\n    throw new Error('OpenRouter cagrisi basarisiz item ' + it + ' durum=' + statusOf(e) + ': ' + (e && (e.message || e)));\n  }\n};\n\nreturn await Promise.all(items.map((item, it) => callOne(item, it)));\n"
      },
      "id": "4e664775-9713-47fd-8468-48a7c0282d87",
      "name": "\ud83e\udd16 Gemini: OCR & Alan \u00c7\u0131kar",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        448,
        0
      ],
      "retryOnFail": true,
      "waitBetweenTries": 5000,
      "maxTries": 5
    },
    {
      "parameters": {
        "jsCode": "\nconst items = $input.all();\nconst prevItems = $('\ud83d\udd27 Gemini Extract \u0130ste\u011fi Haz\u0131rla').all();\nconst REVERSE = [\"KABUL_MEKTUBU\"];\nconst results = [];\nfor (let i = 0; i < items.length; i++) {\n  const item = items[i].json;\n  const prev = prevItems[i]?.json || {};\n  const raw = item.choices?.[0]?.message?.content || '{}';\n  let extracted;\n  try { extracted = JSON.parse(raw.replace(/```json\\n?/g,'').replace(/```\\n?/g,'').trim()); } catch(e){ extracted = {}; }\n  const LANG_FULL = { TR:'T\u00fcrk\u00e7e', RU:'Rus\u00e7a', EN:'\u0130ngilizce', TKM:'T\u00fcrkmen\u00e7e' };\n  let targetCode = prev.target_language;\n  let langName = prev.lang_name;\n  // TERS AKI\u015e: KABUL gibi t\u00fcrlerde (T\u00fcrk\u00e7e kaynak) hedef otomatik T\u00fcrkmen\u00e7e\n  if (REVERSE.indexOf(prev.template_key) !== -1) { targetCode = 'TKM'; langName = 'T\u00fcrkmen\u00e7e \ud83c\uddf9\ud83c\uddf2'; }\n  const targetLangFull = LANG_FULL[targetCode] || 'T\u00fcrk\u00e7e';\n  const dersSozluk = (prev.template_key === 'TRANSKRIPT') ? `\\n- DERS ADLARI (T\u00fcrkmen\u00e7e->T\u00fcrk\u00e7e F\u0130RMA terimleri, AYNEN kullan): T\u00fcrkmen dili->T\u00fcrkmence; Edebi\u00fdat/T\u00fcrkmen edebi\u00fdaty->T\u00fcrkmen edebiyat\u0131; Rus dili->Rus dili; I\u0148lis dili->\u0130ngilizce; T\u00fcrkmenistany\u0148 taryhy->T\u00fcrkmenistan'\u0131n tarihi; D\u00fcn\u00fd\u00e4 taryhy/Umumy taryh->Genel tarih; Jemgy\u00fdeti \u00f6wreni\u015f->Sosyoloji; Geografi\u00fda->Co\u011frafya; Algebra->Cebir ve analiz ba\u015flang\u0131c\u0131; Geometri\u00fda->Geometri; D\u00fcn\u00fd\u00e4 medeni\u00fdeti->D\u00fcnya k\u00fclt\u00fcr\u00fc; Informatika->Bilgisayar; Fizika->Fizik; Biologi\u00fda->Biyoloji; Himi\u00fda->Kimya; Bedenterbi\u00fde->Beden e\u011fitimi; \u00dda\u015fayy\u015f durmu\u015f esaslary->Temel ya\u015fam bilgileri; T\u00fcrkmenistany\u0148 medeni mirasy->T\u00fcrkmenistan'\u0131n k\u00fclt\u00fcr miras\u0131; Ykdysady\u00fdeti\u0148 esaslary->Ekonomi temelleri; Astronomi\u00fda->Astronomi; Informasi\u00fda-kommunikasi\u00fda we innowasion tehnologi\u00fdalary->Haberle\u015fme ileti\u015fim; Ekologi\u00fda->Ekoloji; \u00d6z\u00fcni alyp barmagy\u0148 medeni\u00fdeti->Davran\u0131\u015f k\u00fclt\u00fcr\u00fc; D\u00f6wrebap tehnologi\u00fdalary\u0148 esaslary->Modern teknolojilerin temelleri; G\u00fcl\u00e7\u00fc-bagban->\u00c7i\u00e7ek\u00e7ilik-bah\u00e7\u0131vanl\u0131k; \u00d6z\u00fcni alyp bar\u015fy->Davran\u0131\u015f notu` : '';\n  const translatePrompt = `Resmi belge \u00e7evirisi yap\u0131yorsun.\\nKaynak dil: ${prev.source_language} \u2192 Hedef dil: ${targetLangFull}\\n\\nKURALLAR (KES\u0130NL\u0130KLE UYULACAK):\\n- Anahtarlar\u0131n isimlerini ASLA DE\u011e\u0130\u015eT\u0130RME.\\n- \u00d6zel isimleri \u00c7EV\u0130RME, SADECE Latin alfabesine transkript et.\n- \u0130S\u0130M HARF D\u00d6N\u00dc\u015e\u00dcM\u00dc (\u00f6zel isim ve soyisimde uygula, T\u00fcrkmence Latin -> T\u00fcrk\u00e7e): \u00e4->a (M\u00e4rem->Marem), \u017e->j (\u017dumakul->Jumakul), \u0148->n (sa\u011f\u0131r kef), w->v (Wepa->Vepa, istisnas\u0131z), \u00fd->y (\u00ddazmyrat->Yazmyrat), y->y AYNEN korunur (Ylham->Ylham), \u015f->\u015f, j->j AYNEN korunur (Jelaleddin->Jelaleddin). Soyad\u0131 ekleri: -ow/-owa->-ov/-ova, -\u00fdew/-\u00fdewa->-yev/-yeva (Amanow->Amanov, Weli\u00fdew->Veliyev).\\n- Pasaport/MRZ/belge/kay\u0131t numaralar\u0131, seri_no ve tarih alanlar\u0131n\u0131 H\u0130\u00c7 DE\u011e\u0130\u015eT\u0130RME.\n- cinsiyet alan\u0131n\u0131 hedef dile \u00c7EV\u0130R, kod gibi b\u0131rakma (T\u00fcrk\u00e7e: MALE->ERKEK, FEMALE->KADIN; Rus\u00e7a: \u041c\u0423\u0416\u0421\u041a\u041e\u0419/\u0416\u0415\u041d\u0421\u041a\u0418\u0419; \u0130ngilizce: MALE/FEMALE aynen). B\u00dcY\u00dcK harfle yaz.\\n- Kurum, meslek, unvan, adresleri resmi ${targetLangFull} kar\u015f\u0131l\u0131\u011f\u0131yla \u00e7evir.\n- YER/KURUM ADLARI: wela\u00fdat -> \\\"il\\\" (ASLA \\\"vilayet\\\"/\\\"vilayeti\\\"; \u00f6r. \\\"Lebap ili\\\"). ge\u0148e\u015f/ge\u0148e\u015flik -> \\\"muhtarl\u0131k\\\". etrap -> \\\"il\u00e7e\\\", \u015f\u00e4her -> \\\"\u015fehir\\\", \u015f\u00e4her\u00e7e -> \\\"kasaba\\\" (\u015f\u00e4her\u00e7e'yi ASLA \\\"\u015fehir\\\" yapma). Yer adlar\u0131ndaki T\u00fcrkmen harflerini de \u00e7evir (w->v, \u00e4->a, \u00fd->y; \u00f6 ve \u00fc AYNEN korunur), \u00f6r. D\u00f6wletli->D\u00f6vletli. R\u00ddN\u00dd / RYNY k\u0131saltmas\u0131n\u0131 -> \\\"N\u00fcfus ve vatanda\u015fl\u0131k i\u015fleri\\\" olarak a\u00e7.\\n- JSON dizilerinin (ders/ay listeleri) her eleman\u0131n\u0131 \u00e7evir, yap\u0131y\u0131 bozma.\\n- M\u00dcH\u00dcR/KA\u015eE metnini de hedef dile TAM \u00e7evir (muhur ve *_muhur alanlar\u0131); T\u00fcrkmen\u00e7e BIRAKMA.\\n- Bo\u015f de\u011ferleri (\"\") oldu\u011fu gibi b\u0131rak.${dersSozluk}\\n\\nGirdi:\\n${JSON.stringify(extracted, null, 2)}\\n\\nSADECE \u00e7evrilmi\u015f JSON d\u00f6nd\u00fcr.`;\n  const geminiBody = { messages: [{ role: 'user', content: translatePrompt }], temperature: 0.1, response_format: { type: 'json_object' } };\n  results.push({ json: { geminiBody, extracted_data: extracted, chat_id: prev.chat_id, target_language: targetCode, lang_name: langName, document_type: prev.document_type, template_key: prev.template_key, doc_index: i, doc_total: items.length }});\n}\nreturn results;\n"
      },
      "id": "d0990221-8b92-42a7-97ec-2a648a7b3d88",
      "name": "\ud83d\udccb \u00c7\u0131kar\u0131m\u0131 Ayr\u0131\u015ft\u0131r + \u00c7eviri Haz\u0131rla",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        672,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "\n// === OpenRouter cagrisi (google/gemini-3.5-flash, ucretli tek anahtar) ===\n// Tum item'lar Promise.all ile ESZAMANLI islenir (task-runner zaman limitine takilmamak icin).\n// Gecici hatada node-seviyesi retryOnFail devreye girer; kalici hatada kullaniciya Telegram'dan nazik mesaj.\nconst KEY = '<OPENROUTER_API_KEY>';\nconst MODEL = 'google/gemini-3.5-flash';\nconst TG_TOKEN = '<TELEGRAM_BOT_TOKEN>';\nconst items = $input.all();\nconst helpers = this.helpers;\nlet notified = false;\nconst statusOf = (e) => Number(e?.httpCode ?? e?.statusCode ?? e?.response?.statusCode ?? e?.cause?.statusCode ?? e?.cause?.response?.status ?? 0);\n\nconst notify = async (chatId) => {\n  if (notified || !chatId || !TG_TOKEN || TG_TOKEN[0] === '<') return;\n  notified = true;\n  try {\n    await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://api.telegram.org/bot' + TG_TOKEN + '/sendMessage',\n      body: { chat_id: chatId, text: 'Sistem su an cevap veremedi. Lutfen biraz sonra belgeyi tekrar gonderin.' },\n      json: true, timeout: 15000,\n    });\n  } catch (_) {}\n};\n\nconst callOne = async (item, it) => {\n  const inJson = item.json;\n  const body = inJson.geminiBody;\n  if (!body) return { json: inJson, pairedItem: { item: it } };\n  body.model = MODEL;\n  const chatId = inJson.chat_id || (inJson._meta && inJson._meta.chat_id);\n  try {\n    const resp = await helpers.httpRequest({\n      method: 'POST',\n      url: 'https://openrouter.ai/api/v1/chat/completions',\n      headers: { 'Authorization': 'Bearer ' + KEY, 'Content-Type': 'application/json', 'X-Title': 'Takyk Terjime' },\n      body,\n      json: true,\n      timeout: 120000,\n    });\n    return { json: resp, pairedItem: { item: it } };\n  } catch (e) {\n    await notify(chatId);\n    throw new Error('OpenRouter cagrisi basarisiz item ' + it + ' durum=' + statusOf(e) + ': ' + (e && (e.message || e)));\n  }\n};\n\nreturn await Promise.all(items.map((item, it) => callOne(item, it)));\n"
      },
      "id": "754c8908-9be4-498f-8ad1-3fe4a21c8f34",
      "name": "\ud83c\udf10 Gemini: \u00c7eviri Yap",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        0
      ],
      "retryOnFail": true,
      "maxTries": 5,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "\nconst items = $input.all();\nconst prevItems = $('\ud83d\udccb \u00c7\u0131kar\u0131m\u0131 Ayr\u0131\u015ft\u0131r + \u00c7eviri Haz\u0131rla').all();\nconst results = [];\n\n// Word icin temizlik: SADECE kontrol karakterleri ayiklanir (ic ice dizi/nesne dahil).\n// HTML/XML kacisi YAPMA \u2014 docxtpl/python-docx XML kacisini kendisi yapar;\n// eski &->&amp; kacisi belgede literal &#39; artefakti birakiyordu (transkript disi tum turler).\nfunction cleanForWord(v) {\n  if (typeof v === 'string') {\n    return v.replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\uFFFE\\uFFFF]/g, '').trim();\n  }\n  if (Array.isArray(v)) return v.map(cleanForWord);\n  if (v !== null && typeof v === 'object') {\n    for (const k in v) v[k] = cleanForWord(v[k]);\n    return v;\n  }\n  return v;\n}\n\nfor (let i = 0; i < items.length; i++) {\n  const item = items[i].json;\n  const prev = prevItems[i]?.json || {};\n\n  const raw = item.choices?.[0]?.message?.content || '{}';\n\n  let translated;\n  try {\n    const cleaned = raw.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n    translated = JSON.parse(cleaned);\n  } catch(e) {\n    translated = prev.extracted_data || {};\n  }\n\n  for (let key in translated) {\n    translated[key] = cleanForWord(translated[key]);\n  }\n\n  // cinsiyet deterministik g\u00fcvence: model MALE/FEMALE'i bazen pasaport kodu san\u0131p\n  // \u00e7evirmeden b\u0131rak\u0131yor (2026-07-07 d\u0131\u015f pasaport vakas\u0131). Prompt kural\u0131na ek emniyet.\n  const GENDER_MAP = {\n    TR: { MALE:'ERKEK', M:'ERKEK', '\u041c\u0423\u0416\u0421\u041a\u041e\u0419':'ERKEK', '\u041c\u0423\u0416':'ERKEK', FEMALE:'KADIN', F:'KADIN', '\u0416\u0415\u041d\u0421\u041a\u0418\u0419':'KADIN', '\u0416\u0415\u041d':'KADIN', 'A\u00ddAL':'KADIN', AYAL:'KADIN', ERKEK:'ERKEK', KADIN:'KADIN' },\n    RU: { MALE:'\u041c\u0423\u0416\u0421\u041a\u041e\u0419', M:'\u041c\u0423\u0416\u0421\u041a\u041e\u0419', ERKEK:'\u041c\u0423\u0416\u0421\u041a\u041e\u0419', FEMALE:'\u0416\u0415\u041d\u0421\u041a\u0418\u0419', F:'\u0416\u0415\u041d\u0421\u041a\u0418\u0419', KADIN:'\u0416\u0415\u041d\u0421\u041a\u0418\u0419', '\u041c\u0423\u0416\u0421\u041a\u041e\u0419':'\u041c\u0423\u0416\u0421\u041a\u041e\u0419', '\u0416\u0415\u041d\u0421\u041a\u0418\u0419':'\u0416\u0415\u041d\u0421\u041a\u0418\u0419' },\n    EN: { ERKEK:'MALE', M:'MALE', '\u041c\u0423\u0416\u0421\u041a\u041e\u0419':'MALE', KADIN:'FEMALE', F:'FEMALE', '\u0416\u0415\u041d\u0421\u041a\u0418\u0419':'FEMALE', MALE:'MALE', FEMALE:'FEMALE' }\n  };\n  if (typeof translated.cinsiyet === 'string' && translated.cinsiyet.trim()) {\n    const gmap = GENDER_MAP[prev.target_language] || {};\n    const gval = gmap[translated.cinsiyet.trim().toUpperCase()];\n    if (gval) translated.cinsiyet = gval;\n  }\n\n  results.push({\n    json: {\n      chat_id:         prev.chat_id,\n      document_type:   prev.document_type,\n      target_language: prev.target_language,\n      lang_name:       prev.lang_name,\n      translated_data: translated,\n      doc_index:       prev.doc_index,\n      doc_total:       prev.doc_total\n    }\n  });\n}\n\nreturn results;\n"
      },
      "id": "5be1020f-6880-4c60-a0e1-8bb784a82658",
      "name": "\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1104,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://<SERVICE_HOST>:8005/generate",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ document_type: $json.document_type, target_language: $json.target_language, extracted_data: $json.translated_data || {} }) }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          },
          "timeout": 30000
        }
      },
      "id": "f6c3e59a-f862-46c8-a276-6dd944180e4f",
      "name": "\ud83d\udcc4 Word Belgesi \u00dcret",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1520,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendDocument",
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "name": "chat_id",
              "value": "={{ $('\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r').item.json.chat_id }}"
            },
            {
              "name": "caption",
              "value": "={{ '\u2705 <b>' + $('\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r').item.json.document_type + '</b> terc\u00fcmesi haz\u0131r!\\n\\n\ud83c\udf10 Dil: ' + $('\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r').item.json.lang_name + '\\n\ud83d\udccb Takyk Terjime \u00c7e\u015fmesi' }}"
            },
            {
              "name": "parse_mode",
              "value": "HTML"
            },
            {
              "parameterType": "formBinaryData",
              "name": "document",
              "inputDataFieldName": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "e6c0f05a-88c1-4ed8-a4d3-26453603bb86",
      "name": "\ud83d\udce4 Belgeyi Telegram'a G\u00f6nder",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1744,
        0
      ]
    },
    {
      "parameters": {
        "method": "DELETE",
        "url": "={{ 'http://<SERVICE_HOST>:8005/state/' + $('\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r').item.json.chat_id }}",
        "options": {}
      },
      "id": "ff400aab-ebc2-4321-b730-43d07607d237",
      "name": "\ud83d\uddd1 State Temizle",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1952,
        0
      ]
    },
    {
      "parameters": {
        "url": "={{ 'http://<SERVICE_HOST>:8005/state/' + $('\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r').item.json.chat_id + '/consume' }}",
        "options": {},
        "method": "POST"
      },
      "id": "06843252-74c6-4659-acb1-29904aea683d",
      "name": "\ud83d\udcc2 State Yukle",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -432,
        80
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "st-1",
              "leftValue": "={{ $json.documents ? $json.documents.length : 0 }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        -224,
        80
      ],
      "id": "3be3646c-1cc3-477e-8689-26b915d69d25",
      "name": "If"
    },
    {
      "parameters": {
        "jsCode": "\nconst items = $input.all();\nconst results = [];\nconst typeMap = {\"ADLI_SICIL\": \"SABIKA\", \"SABIKA\": \"SABIKA\", \"LISE_DIPLOMASI\": \"ATESTAT_MODERN\", \"ATESTAT\": \"ATESTAT_MODERN\", \"ATESTAT_MODERN\": \"ATESTAT_MODERN\", \"ATESTAT_ESKI\": \"ATESTAT_ESKI\", \"DOGUM_BELGESI\": \"DOGUM_KISA\", \"DOGUM_KISA\": \"DOGUM_KISA\", \"DOGUM_UZUN\": \"DOGUM_UZUN\", \"DOGUM_OLMADIK\": \"DOGUM_OLMADIK\", \"BEKARLIK_BELGESI\": \"BEKARLIK\", \"BEKARLIK\": \"BEKARLIK\", \"EVLILIK_CUZDANI\": \"EVLILIK_KISA\", \"EVLILIK_KISA\": \"EVLILIK_KISA\", \"EVLILIK_UZUN\": \"EVLILIK_UZUN\", \"BOSANMA_S\": \"BOSANMA_S\", \"BOSANMA_Z\": \"BOSANMA_Z\", \"PASAPORT\": \"PASAPORT_ZAGRAN\", \"PASAPORT_ZAGRAN\": \"PASAPORT_ZAGRAN\", \"PASAPORT_ICERKI\": \"PASAPORT_ICERKI\", \"PASAPORT_ICERKI_ESKI\": \"PASAPORT_ICERKI_ESKI\", \"SURUCU_BELGESI\": \"SURUCU_BELGESI\", \"DEKLARASYON\": \"DEKLARASYON\", \"IKAMET_IZNI\": \"IKAMET_IZNI\", \"PATENT\": \"PATENT\", \"ISTIHDAM_KAYIT\": \"ISTIHDAM_KAYIT\", \"TASDIK_BELGESI\": \"TASDIK_BELGESI\", \"KEPILNAMA\": \"KEPILNAMA\", \"EMEKLILIK_TEYIT\": \"EMEKLILIK_TEYIT\", \"OLUM\": \"OLUM\", \"SEYAHAT_TAAHHUT\": \"SEYAHAT_TAAHHUT\", \"MUVAFAKATNAME\": \"MUVAFAKATNAME\", \"SAGLIK_RAPORU\": \"TASDIK_BELGESI\", \"VEKALETNAME\": \"PATENT\", \"DIGER\": \"DEKLARASYON\", \"TRANSKRIPT\": \"TRANSKRIPT\", \"MAAS_BORDRO\": \"MAAS_BORDRO\", \"MAAS_BELGESI\": \"MAAS_BORDRO\", \"BORDRO\": \"MAAS_BORDRO\", \"NOTER_DILEKCE\": \"NOTER_DILEKCE\", \"NATARIUS_ARZA\": \"NOTER_DILEKCE\", \"ARZA\": \"NOTER_DILEKCE\", \"SPONSOR_MEKTUBU\": \"NOTER_DILEKCE\", \"TAAHHUTNAME\": \"NOTER_DILEKCE\", \"KABUL_MEKTUBU\": \"KABUL_MEKTUBU\", \"KABUL_HATY\": \"KABUL_MEKTUBU\", \"DAVET_MEKTUBU\": \"KABUL_MEKTUBU\", \"MEKDEPTE_OKANLYGY\": \"KEPILNAMA\", \"OKUL_BELGESI\": \"KEPILNAMA\", \"OKUDUGU_YER_BELGESI\": \"KEPILNAMA\", \"OGRENIM_BELGESI\": \"KEPILNAMA\", \"OKUL_TASDIK\": \"KEPILNAMA\", \"IKAMETGAH\": \"IKAMETGAH\", \"TASSYKNAMA_YASAYAN\": \"IKAMETGAH\", \"YASAYAN_YER\": \"IKAMETGAH\", \"YASAYAN_YERI_HAKYNDA\": \"IKAMETGAH\", \"YASAYAN_YER_BELGESI\": \"IKAMETGAH\", \"IKAMETGAH_BELGESI\": \"IKAMETGAH\", \"AILE_DURUM\": \"AILE_DURUM\", \"TASSYKNAMA_MASGALA\": \"AILE_DURUM\", \"MASGALA\": \"AILE_DURUM\", \"MASGALASY_HAKYNDA\": \"AILE_DURUM\", \"AILE_DURUM_BELGESI\": \"AILE_DURUM\", \"AILE_BELGESI\": \"AILE_DURUM\", \"ZAHMET_HAKY\": \"MAAS_BORDRO\", \"ZAHMET_HAKY_KEPILNAMA\": \"MAAS_BORDRO\", \"CALISMA_BELGESI\": \"MAAS_BORDRO\"};\nfor (const item of items) {\n  const docType = item.json.document_type;\n  const mappedType = typeMap[docType] || docType;\n  results.push({ json: { ...item.json, document_type: mappedType } });\n}\nreturn results;\n"
      },
      "id": "doc-type-mapper-1777404036301",
      "name": "\ud83d\uddc2 Belge T\u00fcr\u00fc E\u015fle\u015ftir",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1312,
        0
      ]
    },
    {
      "parameters": {
        "updates": [
          "message",
          "callback_query"
        ],
        "additionalFields": {}
      },
      "id": "1cf647c8-9ef8-48ae-89ce-b7968b598f8d",
      "name": "\ud83d\udce9 Telegram: Mesaj Al1",
      "type": "n8n-nodes-base.telegramTrigger",
      "typeVersion": 1.1,
      "position": [
        -1520,
        224
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "\ud83d\udd00 G\u00fcncelleme T\u00fcr\u00fcn\u00fc Belirle": {
      "main": [
        [
          {
            "node": "\u2753 Callback m\u0131?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2753 Callback m\u0131?": {
      "main": [
        [
          {
            "node": "\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u2753 Belge/Foto\u011fraf Var m\u0131?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd18 Callback Verisini Ayr\u0131\u015ft\u0131r": {
      "main": [
        [
          {
            "node": "\u2705 Callback Sorgusunu Yan\u0131tla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2705 Callback Sorgusunu Yan\u0131tla": {
      "main": [
        [
          {
            "node": "\ud83d\udcc2 State Yukle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23f3 \u0130\u015fleniyor Mesaj\u0131 G\u00f6nder": {
      "main": [
        [
          {
            "node": "\ud83d\udd27 Gemini Extract \u0130ste\u011fi Haz\u0131rla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd27 Gemini Extract \u0130ste\u011fi Haz\u0131rla": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 Gemini: OCR & Alan \u00c7\u0131kar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 Gemini: OCR & Alan \u00c7\u0131kar": {
      "main": [
        [
          {
            "node": "\ud83d\udccb \u00c7\u0131kar\u0131m\u0131 Ayr\u0131\u015ft\u0131r + \u00c7eviri Haz\u0131rla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udccb \u00c7\u0131kar\u0131m\u0131 Ayr\u0131\u015ft\u0131r + \u00c7eviri Haz\u0131rla": {
      "main": [
        [
          {
            "node": "\ud83c\udf10 Gemini: \u00c7eviri Yap",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83c\udf10 Gemini: \u00c7eviri Yap": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd \u00c7eviriyi Ayr\u0131\u015ft\u0131r": {
      "main": [
        [
          {
            "node": "\ud83d\uddc2 Belge T\u00fcr\u00fc E\u015fle\u015ftir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcc4 Word Belgesi \u00dcret": {
      "main": [
        [
          {
            "node": "\ud83d\udce4 Belgeyi Telegram'a G\u00f6nder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce4 Belgeyi Telegram'a G\u00f6nder": {
      "main": [
        []
      ]
    },
    "\u2753 Belge/Foto\u011fraf Var m\u0131?": {
      "main": [
        [
          {
            "node": "\ud83d\uddc2 Dosya Bilgisi Al",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u26d4 Belge Yok Uyar\u0131s\u0131 G\u00f6nder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\uddc2 Dosya Bilgisi Al": {
      "main": [
        [
          {
            "node": "\ud83d\udce1 Telegram: Dosya Yolunu Al",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce1 Telegram: Dosya Yolunu Al": {
      "main": [
        [
          {
            "node": "\u2b07\ufe0f Dosyay\u0131 \u0130ndir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2b07\ufe0f Dosyay\u0131 \u0130ndir": {
      "main": [
        [
          {
            "node": "\ud83d\udd27 Gemini Classify \u0130ste\u011fi Haz\u0131rla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd27 Gemini Classify \u0130ste\u011fi Haz\u0131rla": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 Gemini: Belge S\u0131n\u0131fland\u0131r",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 Gemini: Belge S\u0131n\u0131fland\u0131r": {
      "main": [
        [
          {
            "node": "\ud83d\udcca S\u0131n\u0131fland\u0131rma Ayr\u0131\u015ft\u0131r + Klavye Haz\u0131rla",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcca S\u0131n\u0131fland\u0131rma Ayr\u0131\u015ft\u0131r + Klavye Haz\u0131rla": {
      "main": [
        [
          {
            "node": "\ud83d\udcbe State'i Kaydet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcbe State'i Kaydet": {
      "main": [
        [
          {
            "node": "\u2328\ufe0f Dil Se\u00e7im Klavyesi G\u00f6nder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcc2 State Yukle": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "\u23f3 \u0130\u015fleniyor Mesaj\u0131 G\u00f6nder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u26d4 Oturum S\u00fcresi Doldu",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\uddc2 Belge T\u00fcr\u00fc E\u015fle\u015ftir": {
      "main": [
        [
          {
            "node": "\ud83d\udcc4 Word Belgesi \u00dcret",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce9 Telegram: Mesaj Al1": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 G\u00fcncelleme T\u00fcr\u00fcn\u00fc Belirle",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "timeSavedMode": "fixed",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": true
  },
  "staticData": null,
  "meta": null,
  "nodeGroups": [],
  "versionId": "a55a6805-41cc-46fa-bf5b-e046c4052fae",
  "activeVersionId": null,
  "versionCounter": 201,
  "triggerCount": 1,
  "shared": [
    {
      "updatedAt": "2026-04-28T13:41:41.456Z",
      "createdAt": "2026-04-28T13:41:41.456Z",
      "role": "workflow:owner",
      "workflowId": "97Z8vSF1pNUGGjsB",
      "projectId": "YIhpA8ngbtr55XUD",
      "project": {
        "updatedAt": "2026-04-19T10:23:57.666Z",
        "createdAt": "2026-04-19T10:20:08.427Z",
        "id": "YIhpA8ngbtr55XUD",
        "name": "<PROJECT_OWNER>",
        "type": "personal",
        "icon": null,
        "description": null,
        "creatorId": "64a95671-3eeb-4ce1-a9ef-6c3f722e1d06"
      }
    }
  ],
  "tags": [],
  "activeVersion": null
}