{
  "name": "Jablytics demo 02 · Control y resumen semanal",
  "nodes": [
    {
      "parameters": {},
      "id": "manual",
      "name": "Ejecutar demo",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const exportaciones = [\n  { semana: '2026-W42', fuente: 'GA4', sesiones: 48, contactos: 2 },\n  { semana: '2026-W42', fuente: 'CRM', sesiones: 0, contactos: 1 },\n  { semana: '2026-W43', fuente: 'GA4', sesiones: 52, contactos: 3 }\n];\nreturn exportaciones.map(json => ({ json }));"
      },
      "id": "sample",
      "name": "Datos ficticios",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        300
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const grupos = new Map();\nfor (const { json } of $input.all()) {\n  const semana = String(json.semana ?? '');\n  if (!/^\\d{4}-W\\d{2}$/.test(semana)) throw new Error('Semana inválida');\n  if (!grupos.has(semana)) grupos.set(semana, { semana, fuentes: new Set(), sesiones: 0, contactosWeb: 0, contactosCRM: 0 });\n  const fila = grupos.get(semana);\n  if (fila.fuentes.has(json.fuente)) throw new Error('Fuente duplicada en ' + semana);\n  if (!['GA4', 'CRM'].includes(json.fuente) || !Number.isInteger(json.contactos) || json.contactos < 0) throw new Error('Exportación inválida');\n  fila.fuentes.add(json.fuente);\n  if (json.fuente === 'GA4') {\n    if (!Number.isInteger(json.sesiones) || json.sesiones < 0) throw new Error('Sesiones inválidas');\n    fila.sesiones = json.sesiones;\n    fila.contactosWeb = json.contactos;\n  } else fila.contactosCRM = json.contactos;\n}\nreturn [...grupos.values()].map(fila => ({ json: {\n  semana: fila.semana,\n  estado: fila.fuentes.has('GA4') && fila.fuentes.has('CRM') ? 'listo_para_revision' : 'incompleto',\n  sesiones: fila.sesiones,\n  clicsContactoWeb: fila.contactosWeb,\n  consultasConfirmadasCRM: fila.fuentes.has('CRM') ? fila.contactosCRM : null,\n  nota: 'Los clics web no equivalen a consultas confirmadas.'\n} }));"
      },
      "id": "process",
      "name": "Procesar y controlar",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        300
      ]
    }
  ],
  "connections": {
    "Ejecutar demo": {
      "main": [
        [
          {
            "node": "Datos ficticios",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Datos ficticios": {
      "main": [
        [
          {
            "node": "Procesar y controlar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "active": false,
  "pinData": {},
  "tags": []
}
