{
  "name": "Tagging_2",
  "nodes": [
    {
      "parameters": {
        "content": "## Datenbank anfragen",
        "height": 360,
        "width": 440
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -544,
        768
      ],
      "id": "a4717fd3-f28d-4bdc-a3a4-7ff38fc1220e",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "jsCode": "/*\n=========================================================\nSINGLE ITEM PICKER & CLEANER\n- Sucht den ersten Eintrag, der noch nicht 'processed'='ok' ist\n- Reinigt alle Felder dieses Eintrags\n- Bereitet den Kontext-String f\u00fcr das LLM vor\n=========================================================\n*/\n\n// KONFIGURATION\nconst statusFieldName = 'processed'; // Deine Kontrollspalte\nconst targetStatus = 'ok';           // Der Wert, den erledigte Zeilen haben\n\n// Felder, die wir NICHT im Prompt wollen (technisches Zeug)\nconst excludedFromPrompt = [\n    \"processed\", \n    \"SO URL\", \n    \"API URL\", \n    \"Image URL\", \n    \"Bildlink\", \n    \"ID\",\n    \"row_scan\",\n    \"_id\",\n    statusFieldName // Die Kontrollspalte selbst auch nicht\n];\n\n// 1. Input holen\nconst items = $input.all();\nlet targetItem = null;\n\n// 2. SEARCH LOOP: Finde das erste \"offene\" Item\nfor (const item of items) {\n    const currentStatus = item.json[statusFieldName];\n    \n    // Bedingung: Wenn Status leer ist ODER ungleich 'ok'\n    if (!currentStatus || currentStatus !== targetStatus) {\n        targetItem = item;\n        break; // WICHTIG: Sofort stoppen, wir wollen nur einen!\n    }\n}\n\n// Wenn alle schon erledigt sind (\"ok\"), geben wir nichts zur\u00fcck -> Workflow stoppt hier meist\nif (!targetItem) {\n    return [];\n}\n\n// -------------------------------------------------------\n// AB HIER: Reinigung nur f\u00fcr das gefundene targetItem\n// -------------------------------------------------------\n\n// Hilfsfunktion: Text reinigen\nfunction cleanText(text) {\n    if (text === null || text === undefined) return \"Keine Angabe\";\n    let cleaned = String(text);\n    cleaned = cleaned.replace(/[\\u200B\\u00A0]/g, ' '); // Zero Width Spaces weg\n    return cleaned.trim();\n}\n\nconst originalJson = targetItem.json;\nconst cleanJson = {};\nlet contextLines = [];\n\n// Dynamisch \u00fcber ALLE Spalten iterieren\nfor (const key of Object.keys(originalJson)) {\n    const rawValue = originalJson[key];\n    \n    // Wert reinigen\n    const cleanValue = cleanText(rawValue);\n    \n    // In das saubere JSON-Objekt speichern\n    cleanJson[key] = cleanValue;\n\n    // Entscheiden, ob es in den Kontext-String kommt\n    if (cleanValue !== \"Keine Angabe\" && cleanValue !== \"\" && !excludedFromPrompt.includes(key)) {\n        contextLines.push(`${key}: ${cleanValue}`);\n    }\n}\n\n// Den Context-String zusammenbauen\nconst contextString = contextLines.join('\\n');\n\n// Daten in das Item schreiben\ntargetItem.json.metadata_clean = cleanJson; \ntargetItem.json.context_data_string = contextString; \n\n// WICHTIG: Wir geben ein Array zur\u00fcck, das NUR dieses eine Item enth\u00e4lt\nreturn [targetItem];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -272,
        928
      ],
      "id": "a8132357-340c-4c12-8da0-f860f0d538cd",
      "name": "Code6"
    },
    {
      "parameters": {
        "operation": "list",
        "tableName": "metadata",
        "viewName": "ok",
        "options": {
          "simple": false
        }
      },
      "type": "n8n-nodes-base.seaTable",
      "typeVersion": 2,
      "position": [
        -464,
        928
      ],
      "id": "77667500-4fc3-44d3-be84-9081525deb0a",
      "name": "Get many rows",
      "credentials": {
        "seaTableApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        -720,
        928
      ],
      "id": "6397e814-120b-4eca-aab0-a34d257f5666",
      "name": "Schedule Trigger"
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "5TaVWQNKBGBnRxPV",
          "mode": "list"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "Bildlink": "={{ $json.Bildlink }}",
            "metadata_clean": "={{ $('Code6').item.json.metadata_clean }}",
            "context_data_string": "={{ $('Code6').item.json.context_data_string }}",
            "metadata_clean__id": "={{ $('Code6').item.json.metadata_clean._id }}"
          },
          "matchingColumns": [
            "Bildlink",
            "metadata_clean",
            "context_data_string",
            "metadata_clean__id"
          ],
          "schema": [
            {
              "id": "Bildlink",
              "displayName": "Bildlink",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "metadata_clean",
              "displayName": "metadata_clean",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "context_data_string",
              "displayName": "context_data_string",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "metadata_clean__id",
              "displayName": "metadata_clean__id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.2,
      "position": [
        0,
        928
      ],
      "name": "Call Tagging_Sub2",
      "id": "0d4c450a-6cdf-4ce5-bc9b-41ffb138a673"
    },
    {
      "parameters": {
        "amount": 2
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        0,
        1152
      ],
      "id": "5f3aaede-6d53-4da4-8f4c-66ecfd63d1f2",
      "name": "Wait"
    }
  ],
  "connections": {
    "Code6": {
      "main": [
        [
          {
            "node": "Call Tagging_Sub2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many rows": {
      "main": [
        [
          {
            "node": "Code6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get many rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call Tagging_Sub2": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Get many rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "902aea4b-0a01-43d3-a85e-0746d58af5b4",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "9Mi6pHBkQW8K4lYM",
  "tags": []
}