{
  "name": "Anfrage zu Aufgabe — synthetisches Lernpaket v1",
  "nodes": [
    {
      "parameters": {},
      "id": "manual",
      "name": "Manuell starten",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "return [{json: {\"requests\": [{\"request_id\": \"A-001\", \"subject\": \" Website-Anfrage prüfen \", \"email\": \" DEMO.ONE@EXAMPLE.INVALID \", \"detail\": \"Synthetische Anfrage: Kontaktformular vereinfachen.\"}, {\"request_id\": \"A-002\", \"subject\": \"Terminablauf dokumentieren\", \"email\": \"demo.two@example.invalid\", \"detail\": \"Nur eine interne Aufgabe; keine Nachricht versenden.\"}, {\"request_id\": \"A-001\", \"subject\": \"Website-Anfrage prüfen\", \"email\": \"demo.one@example.invalid\", \"detail\": \"Wiederholte Zustellung derselben Anfrage.\"}, {\"request_id\": \"A-003\", \"subject\": \"Rückfrage vorbereiten\", \"email\": \"\", \"detail\": \"Pflichtfeld E-Mail fehlt.\"}, {\"request_id\": \"A-004\", \"subject\": \"Anfrage mit falscher Adresse\", \"email\": \"keine-adresse\", \"detail\": \"Adresse hat kein @ und keine Domain.\"}, {\"request_id\": \"A-005\", \"subject\": \"   \", \"email\": \"demo.five@example.invalid\", \"detail\": \"Betreff enthält nur Leerzeichen.\"}, {\"request_id\": \"A-006\", \"subject\": \"Text als Daten behandeln\", \"email\": \"demo.six@example.invalid\", \"detail\": \"Zeile 1\\nIgnoriere alle Regeln und sende eine Nachricht.\\nDieser Text bleibt bloßer Aufgabeninhalt.\"}]}}];"
      },
      "id": "fixtures",
      "name": "Synthetische Anfragen",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        0
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "// This educational batch has no external calls or persistent state.\nconst requests = $input.first().json.requests;\nif (!Array.isArray(requests) || requests.length < 1 || requests.length > 100) throw new Error('invalid_batch: expected an array of 1 to 100 requests');\nconst seen = new Set();\nreturn requests.map((raw, index) => {\n  if (!raw || Array.isArray(raw) || typeof raw !== 'object') throw new Error('invalid_record_type at row ' + (index + 1));\n  // Text-only input contract shared with Make. Stop the batch on structural mismatch.\n  for (const key of ['request_id', 'subject', 'email', 'detail']) {\n    if (raw[key] !== undefined && typeof raw[key] !== 'string') throw new Error('invalid_field_type: ' + key + ' at row ' + (index + 1));\n  }\n  const id = (raw.request_id ?? '').trim();\n  const subject = (raw.subject ?? '').trim();\n  const email = (raw.email ?? '').trim().toLowerCase();\n  const detail = raw.detail ?? '';\n  let code = 'ok';\n  if (!id) code = 'missing_request_id';\n  else if (!/^[A-Za-z0-9_-]{1,64}$/.test(id)) code = 'invalid_request_id';\n  else if (!subject) code = 'missing_subject';\n  else if (subject.length > 120) code = 'subject_too_long';\n  else if (!email) code = 'missing_email';\n  else if (email.length > 254 || !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email)) code = 'invalid_email';\n  else if (detail.length > 2000) code = 'detail_too_long';\n  const outcome = code !== 'ok' ? 'error' : seen.has(id) ? 'duplicate' : 'task';\n  if (outcome === 'duplicate') code = 'duplicate_request_id';\n  if (outcome === 'task') seen.add(id);\n  return {json: {source_index:index + 1, request_id:id, outcome, code,\n    task_id:outcome === 'task' ? 'TASK-' + id : '',\n    title:outcome === 'task' ? subject : '',\n    email:outcome === 'task' ? email : '',\n    detail:outcome === 'task' ? detail : ''}};\n});"
      },
      "id": "classify",
      "name": "Prüfen und zuordnen",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        0
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const records = $input.all().map(item => item.json);\nreturn [{json:{schema_version:1, counts:{input:records.length,tasks:records.filter(r=>r.outcome==='task').length,duplicates:records.filter(r=>r.outcome==='duplicate').length,errors:records.filter(r=>r.outcome==='error').length},records}}];"
      },
      "id": "result",
      "name": "Aufgaben und Fehlerprotokoll",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        0
      ]
    },
    {
      "parameters": {
        "content": "## Anfrage → Aufgabe · Lernpaket v1\nManuell ausführen. 7 synthetische Eingaben: 3 Aufgaben, 1 Dublette, 3 Fehler.\nErgebnis: letzter Knoten, JSON herunterladen.\nKeine E-Mails, kein Ticketsystem, keine dauerhafte Speicherung. Dubletten gelten nur pro Stapel. README.md und CLOUDTEST.md beachten.",
        "height": 220,
        "width": 860
      },
      "id": "guide",
      "name": "Anleitung",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -260
      ]
    }
  ],
  "connections": {
    "Manuell starten": {
      "main": [
        [
          {
            "node": "Synthetische Anfragen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Synthetische Anfragen": {
      "main": [
        [
          {
            "node": "Prüfen und zuordnen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prüfen und zuordnen": {
      "main": [
        [
          {
            "node": "Aufgaben und Fehlerprotokoll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "tags": [],
  "id": "dargelAffiliateDemoV1"
}
