┌──────────────────────────────────────────────────────────────────────────────────────────┐
│                               FLUJOS_APP.js /api/data                                  │
└──────────────────────────────────────────────────────────────────────────────────────────┘
          ▲                                                          ▲
          │                                                          │
          │                                                          │
     HTTP GET                                                     MongoDB
   /api/data?tema=…                                                Collections
          │                                                     ┌─────────────┐
          │                                                     │ noticias    │
          │                                                     ├─────────────┤
          │                                                     │ wikipedia   │
          │                                                     ├─────────────┤
          │                                                     │ torrents    │
          │                                                     ├─────────────┤
          │                                                     │ comparaciones│
          │                                                     └─────────────┘
          │                                                          │
          │                                                          │
          ▼                                                          ▼

┌───────────────────────────────┐                            ┌────────────────────────────────┐
│ 1) Construcción de nodesQuery │                            │ 3) Construcción de linksQuery │
├───────────────────────────────┤                            ├────────────────────────────────┤
│ let nodesQuery = {           │                            │ let linksQuery = {            │
│   tema: <tema>,              │                            │   porcentaje_similitud: {     │
│   ...(subtematica?)          │──┐                         │     $gte: <complejidadMin>    │
│   ...(palabraClave?)         │  │                         │   },                          │
│   ...(fechaInicio/fechaFin?) │  │                         │   noticia1: { $in: nodeIds }, │
│ }                             │  │                         │   noticia2: { $in: nodeIds }  │
└───────────────────────────────┘  │                         └────────────────────────────────┘
           │                       │                                        │
           │                       │                                        │
           │                       │                                        │
           ▼                       │                                        ▼

┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ 2) Búsqueda de nodos (Promise.all)                                                     │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ const [wN, nN, tN] = await Promise.all([                                               │
│   wikipedia.find(nodesQuery).limit(nodosLimit),  // → hasta N wikis                   │
│   noticias.find(nodesQuery).limit(nodosLimit),   // → hasta N noticias               │
│   torrents.find(nodesQuery).limit(nodosLimit)    // → hasta N torrents               │
│ ]);                                                                                     │
│                                                                                         │
│ // Formateo a “Graph Nodes”:                                                             │
│ formattedNodes = [...wN, ...nN, ...tN].map(doc ⇒ ({                                       │
│   id: doc.archivo.trim(),         // identificador único                               │
│   group: doc.subtema || 'sinSub', // color/agrupación visual                            │
│   tema: doc.tema,                 // metadato                                           │
│   content: doc.texto,             // para mostrar al hacer clic                        │
│   fecha: doc.fecha                // filtrado por fecha                                 │
│ }));                                                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────┘
           │
           │  // Extraer lista de IDs de nodos
           │  nodeIds = formattedNodes.map(n ⇒ n.id)
           │
           │
           ▼

┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ 4) Búsqueda de enlaces (comparaciones.find)                                              │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ const links = await comparaciones.find(linksQuery).toArray();                            │
│                                                                                          │
│ // linksQuery:                                                                            │
│ // { porcentaje_similitud: {$gte:Min}, noticia1:{$in:nodeIds}, noticia2:{$in:nodeIds} }   │
│                                                                                          │
│ // Formateo a “Graph Links”:                                                              │
│ formattedLinks = links.map(l ⇒ ({                                                        │
│   source: l.noticia1.trim(),   // coincide con node.id                                  │
│   target: l.noticia2.trim(),   // idem                                                      │
│   value: l.porcentaje_similitud // grosor de la arista                                  │
│ }));                                                                                     │
└──────────────────────────────────────────────────────────────────────────────────────────┘
           │
           │
           ▼

┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ 5) Respuesta al cliente                                                                │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ res.json({                                                                            │
│   nodes: formattedNodes,   // array de {id, group, tema, content, fecha}                │
│   links: formattedLinks    // array de {source, target, value}                         │
│ });                                                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────┘

          ▲
          │
          │
          │
     fetch('/api/data?...')          
          │
          ▼

┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ output_glob_war_prueba.js                                                              │
├──────────────────────────────────────────────────────────────────────────────────────────┤
│ • Inicializa ForceGraph3D   (contenedor DOM)                                           │
│ • getData(paramsObj)                                                              │
│     └─ construye URL: '/api/data?tema=guerra%20global&...'                          │
│     └─ fetch → recibe {nodes,links}                                                │
│     └─ filtra enlaces erróneos (source/target no existentes)                       │
│ • graph.graphData(data)  // renderiza nodos + enlaces                              │
│ • UI: onNodeClick → showNodeContent(), sidebar form → re-getData()                  │
└──────────────────────────────────────────────────────────────────────────────────────────┘
