← Volver al índice | Catálogo de Funcionalidades
Especificación — Flow Builder
Tipo: Requisitos Funcionales
Audiencia: Equipo de Desarrollo · DKV Producto
Fecha: 25 de marzo de 2026
Estado: 🟡 En elaboración
Relacionado con: Catálogo de Funcionalidades (Módulos 2 y 3)
1. Visión General
El Flow Builder es el editor visual de flujos de DKV Pet Flows. Permite construir, configurar y monitorizar flujos de engagement arrastrando bloques (nodos) y conectándolos en un lienzo interactivo.
Esta especificación cubre los requisitos técnicos del editor: interacciones, tipos de nodo, sistema de iconos, validaciones y serialización. Para la descripción funcional orientada al cliente, consultar el Catálogo de Funcionalidades.
Tecnología base: React Flow (@xyflow/react) + Zustand
2. Lienzo Interactivo (Canvas)
2.1 Capacidades Base
| Requisito |
Detalle |
Prioridad |
| Zoom y pan |
Scroll para zoom, arrastre del fondo para pan, pinch-to-zoom en tablet |
🔴 P0 |
| Grid con snap |
Grid visible con snap-to-grid configurable (8px, 16px, 32px) |
🔴 P0 |
| Minimapa |
Vista miniatura del flujo completo en esquina inferior derecha |
🔴 P0 |
| Zoom to fit |
Ajustar zoom para ver todo el flujo (fitView()) |
🔴 P0 |
| Zoom a selección |
Ajustar zoom para centrar la selección actual |
🟡 P1 |
| Deshacer / Rehacer |
Ctrl+Z / Ctrl+Y con historial de 50 operaciones |
🔴 P0 |
| Guardado automático |
Guardado tras cada cambio con debounce de 2 segundos |
🔴 P0 |
| Selección múltiple |
Shift+clic, o arrastre de rectángulo para seleccionar varios nodos |
🔴 P0 |
| Copiar / Pegar |
Ctrl+C / Ctrl+V de nodos y sus configuraciones |
🟡 P1 |
| Notas en canvas |
Comentarios flotantes sobre el canvas (no ejecutables) |
🟢 P2 |
2.2 Conexión por Proximidad (Auto-Linking) ⭐
[!IMPORTANT]
Este es un patrón UX diferenciador observado en Make.com. Al arrastrar un nodo lo suficientemente cerca de otro, los conectores aparecen automáticamente y se establece el enlace.
| Aspecto |
Especificación |
| Radio de detección |
120px configurable (CSS variable --proximity-threshold) |
| Feedback visual |
Línea de puntos animada que crece progresivamente hacia el nodo destino |
| Snap al soltar |
Si la distancia < umbral al soltar, se crea el edge y se posiciona el nodo con snap |
| Validación |
Solo se conectan nodos compatibles (e.g., un Trigger no puede recibir input) |
| Animación |
Transición de 300ms con easing ease-out para el posicionamiento final |
APIs de React Flow confirmadas (fuente: reactflow.dev/examples/nodes/proximity-connect):
| API |
Rol |
onNodeDrag |
Callback continuo durante drag; recibe evento + nodo |
getIntersectingNodes |
Utilidad de useReactFlow() que detecta nodos que intersectan un área rectangular; soporta partially: true |
onNodeDragStop |
Momento de crear el edge si la proximidad se mantiene |
addEdge |
Función de utilidad para añadir edge al estado |
MIN_DISTANCE |
Constante del ejemplo oficial: distancia euclídea mínima para conectar |
[!TIP]
React Flow ofrece un ejemplo oficial de Proximity Connect que calcula la distancia euclídea entre nodos y muestra una conexión visual mientras se arrastra. No es necesario implementar R-Tree ni cuadrículas espaciales; la fuerza bruta funciona bien hasta ~1500 nodos (límite confirmado de 60 FPS).
[!WARNING]
El parámetro node en onNodeDrag puede tener la posición ligeramente desfasada respecto a la posición visual durante el drag. Para cálculos precisos en tiempo real, considerar usar las coordenadas del evento.
| Opción |
Icono |
Descripción |
Prioridad |
| Configurar filtro |
🔻 |
Añade condición al edge (filtra datos que pasan entre nodos) |
🔴 P0 |
| Desconectar |
❌ |
Elimina la conexión entre los dos nodos |
🔴 P0 |
| Seleccionar rama completa |
🌿 |
Selecciona el nodo destino y todo su subárbol downstream |
🔴 P0 |
| Insertar bifurcación |
➕ |
Inserta un router entre los dos nodos conectados |
🟡 P1 |
| Insertar bloque |
➕ |
Inserta un nuevo nodo entre los dos conectados |
🟡 P1 |
| Añadir nota |
📝 |
Añade comentario visual al edge |
🟢 P2 |
| Opción |
Descripción |
Prioridad |
| Configurar |
Abre panel de configuración del nodo |
🔴 P0 |
| Duplicar |
Crea copia del nodo con misma configuración |
🔴 P0 |
| Eliminar |
Elimina el nodo y sus conexiones |
🔴 P0 |
| Renombrar |
Editar etiqueta display del nodo |
🟡 P1 |
| Copiar configuración |
Copia la config al portapapeles |
🟡 P1 |
| Desactivar |
Marca el nodo como inactivo (se salta en ejecución) |
🟡 P1 |
| Ver logs |
Abre historial de ejecuciones del nodo |
🟡 P1 |
| Opción |
Descripción |
Prioridad |
| Pegar nodo |
Pega nodo copiado previamente |
🔴 P0 |
| Añadir nota |
Crea nota flotante en esa posición |
🟢 P2 |
| Zoom to fit |
Ajusta vista para mostrar todo el flujo |
🔴 P0 |
| Seleccionar todo |
Selecciona todos los nodos del flujo |
🟡 P1 |
3. Anatomía del Nodo
Cada nodo en el canvas tiene la siguiente estructura visual:
┌────────────────────────┐
│ ┌──────┐ [badge] │ ← Badge: nº ejecuciones (esquina sup-dcha)
│ │ ICON │ │ ← Icono circular (L2 o L3 según dominio)
│ └──────┘ [+] │ ← Botón "+" a la derecha para añadir nodo
│ │
│ 🔧 Nombre del Bloque │ ← Etiqueta + icono de configuración al hover
│ Subtítulo / Acción │ ← Descripción breve de la acción configurada
└────────────────────────┘
Propiedades visuales
| Propiedad |
Valor |
| Forma |
Círculo grande (80–100px diámetro) con etiqueta debajo |
| Color de fondo |
Determinado por la categoría del nodo (ver §4) |
| Icono |
SVG centrado, 32×32px |
| Badge |
Contador naranja, esquina superior derecha |
| Botón "+" |
Aparece a la derecha del nodo, permite añadir nodo siguiente |
| Hover |
Icono 🔧 de configuración rápida |
| Seleccionado |
Borde glow con color de categoría |
| Desactivado |
Opacidad 40%, borde punteado |
4. Catálogo de Nodos — 40 Tipos en 5 Categorías
4.1 Sistema de colores por categoría
| Categoría |
Cantidad |
Color Light |
Color Dark |
Semántica |
| 🟣 Triggers |
10 |
#7C3AED Violet-600 |
#A78BFA Violet-400 |
"Algo inicia el flujo" |
| 🟡 Lógica |
10 |
#D97706 Amber-600 |
#FBBF24 Amber-400 |
"Decisión / control de flujo" |
| 🟢 Acciones |
10 |
#059669 Emerald-600 |
#34D399 Emerald-400 |
"Ejecutar algo" |
| 🩷 Inteligencia |
5 |
#DB2777 Pink-600 |
#F472B6 Pink-400 |
"IA piensa/genera" |
| 🔵 Datos |
5 |
#2563EB Blue-600 |
#60A5FA Blue-400 |
"Consulta/transforma datos" |
4.2 Triggers (10 nodos)
| ID |
Nodo |
Icono |
Descripción |
Fuente |
| T01 |
Evento API |
⚡ |
Escucha eventos del sistema DKV (vía Health Connect → Dapr) |
InterSystems webhook |
| T02 |
Webhook |
🔗 |
Señal HTTP POST externa |
Cualquier sistema |
| T03 |
Programado (Cron) |
📅 |
Se ejecuta en fecha/hora específica |
Scheduler interno |
| T04 |
Evento de App |
📱 |
Acción del usuario en DKV Mascotas |
SDK API events |
| T05 |
Consulta Finalizada |
🩺 |
Videollamada/chat con veterinario completado |
DKV Vet Digital API |
| T06 |
Cambio de Póliza |
📋 |
Alta, baja, renovación de póliza |
Health Connect event |
| T07 |
Cumpleaños Mascota |
🎂 |
Fecha de cumpleaños de la mascota |
PostgreSQL scheduled |
| T08 |
Recordatorio Vacuna |
💉 |
Próxima vacuna programada |
Pet-Cloud data |
| T09 |
Geo-trigger |
📍 |
Entrada/salida de geofence |
SDK geolocation |
| T10 |
Evento de Segmento |
👥 |
Usuario entra/sale de segmento dinámico |
Segmentation engine |
4.3 Lógica / Control de Flujo (10 nodos)
| ID |
Nodo |
Icono |
Descripción |
| L01 |
Condición (If/Else) |
🔍 |
Evalúa regla booleana → dos ramas (Sí/No) |
| L02 |
Router (bifurcación) |
🔀 |
Split en N ramas paralelas con condiciones |
| L03 |
Merge |
🔗 |
Reúne varias ramas en una sola |
| L04 |
Espera (Delay) |
⏱️ |
Pausa temporal: minutos, horas, días |
| L05 |
Espera a Evento |
⏳ |
Pausa hasta evento específico (o timeout) |
| L06 |
Iterator (Lote) |
🔄 |
Itera sobre lista (ej: todas las mascotas del asegurado) |
| L07 |
Aggregator |
📦 |
Reúne resultados de iteración en uno |
| L08 |
A/B Split |
🎲 |
Divide tráfico en % para test A/B |
| L09 |
Rate Limiter |
🚦 |
Controla flujo: máx N envíos por segundo/minuto |
| L10 |
Error Handler |
⚠️ |
Captura errores del nodo anterior → ruta alternativa |
4.4 Acciones (10 nodos)
| ID |
Nodo |
Icono |
Descripción |
Backend |
| A01 |
Push Notification |
📲 |
Envía push iOS/Android (rich content) |
Gorush → APNs + FCM |
| A02 |
Email |
✉️ |
Envía correo con template personalizado |
Dapr Binding SMTP/SendGrid |
| A03 |
SMS |
💬 |
Envía SMS transaccional |
Dapr Binding Twilio/Vonage |
| A04 |
In-App Message |
📢 |
Mensaje dentro de DKV Mascotas |
WebSocket/SSE → App |
| A05 |
In-App Inbox |
📥 |
Añade mensaje al buzón persistente |
PostgreSQL + API |
| A06 |
Actualizar Tags |
🏷️ |
Modifica tags/segmentos en tiempo real |
Segmentation engine |
| A07 |
Actualizar Perfil |
👤 |
Modifica datos del usuario/mascota |
Pet-Cloud API |
| A08 |
Webhook Saliente |
🌐 |
HTTP POST/PUT a sistema externo |
Quarkus HTTP client |
| A09 |
Crear Tarea |
✅ |
Crea tarea en CRM/ticketing |
Dapr Binding |
| A10 |
Registrar Evento |
📊 |
Logs event para analytics/BI |
Event store |
4.5 Inteligencia / IA (5 nodos)
| ID |
Nodo |
Icono |
Descripción |
Backend |
| I01 |
IA: Generar Contenido |
🤖 |
Personaliza mensaje con LLM |
LangChain4j → Azure OpenAI |
| I02 |
IA: Best Time to Send |
🕐 |
Calcula hora óptima de envío |
ML model |
| I03 |
IA: Sentiment Analysis |
💭 |
Analiza sentimiento de respuesta |
LangChain4j |
| I04 |
IA: Clasificar |
🧠 |
Clasifica input (tipo consulta, urgencia) |
LangChain4j |
| I05 |
IA: Recomendar |
💡 |
Sugiere acción basada en historial |
Recommendation engine |
| ID |
Nodo |
Icono |
Descripción |
| D01 |
Consulta BD |
🗄️ |
Lee datos de PostgreSQL / Pet-Cloud |
| D02 |
Transformar Datos |
🔧 |
Mapea, filtra, reestructura datos entre nodos |
| D03 |
Variable |
📝 |
Set/Get variables del flow (contadores, acumulados) |
| D04 |
Template |
📄 |
Renderiza template con variables (Mustache/Handlebars) |
| D05 |
HTTP Request |
🌍 |
Llama API externa y usa la respuesta |
5. Sistema de Iconos — Arquitectura Multi-Capa
5.1 Tres capas de resolución
┌──────────────────────────────────────────────────────────┐
│ L3: ICONOS DE DOMINIO (Vertical-Specific) │
│ "Pet Health", "Telemedicina", "Oceanografía" │
│ → Se cargan dinámicamente según el proyecto │
├──────────────────────────────────────────────────────────┤
│ L2: ICONOS DE CATEGORÍA (Node Type) │
│ Triggers ⚡ · Lógica 🔀 · Acciones ▶️ · IA 🧠 · Datos 🗄️ │
│ → Fijos, parte del core de Jaraxa │
├──────────────────────────────────────────────────────────┤
│ L1: ICONOS DE SISTEMA (UI Chrome) │
│ Play, Stop, Zoom, Settings, Menu... │
│ → lucide-react (framework UI genérico) │
└──────────────────────────────────────────────────────────┘
5.2 Resolución de icono para un nodo
1. ¿Tiene icono en el DomainIconPack registrado? → Usar L3
2. ¿No? → Usar icono de categoría L2 (Trigger/Lógica/Acción/IA/Datos)
3. ¿Ni L2? → Fallback a icono genérico L1 (lucide)
5.3 Interface DomainIconPack (TypeScript)
interface DomainIconPack {
id: string; // "pet-health", "telemedicine", "oceanography"
name: string; // "DKV Pet Health"
version: string; // semver
icons: Record<string, React.ComponentType<IconProps>>;
nodeIconMap: Record<string, string>; // nodeId → iconKey
}
5.4 Packs de dominio previstos
| Pack |
Proyecto |
Iconos específicos |
@dkv/flow-icons |
DKV Pet Flows |
Vacunación, consulta veterinaria, cumpleaños mascota, póliza, geofence clínica |
@ieo/flow-icons |
IEO Oceanografía |
Boya, satélite, muestra biológica, calidad del agua, rastreo embarcación |
| Formato |
Ventajas |
Inconvenientes |
Decisión |
| React Components (SVGR) |
Tree-shaking nativo, tipado TS, currentColor, props de estilo |
Requiere React |
✅ Formato principal |
| SVG sprites |
Cacheable, independiente de framework, <use> element |
Sin tree-shaking fino |
✅ Fallback para SSR |
| Icon fonts |
Simple, cacheable |
Sin color múltiple, peso fijo |
❌ Descartado |
Mejores prácticas de distribución npm (investigación 2025):
- "sideEffects": false en package.json → habilita tree-shaking agresivo
- ESM (import/export) obligatorio, nunca CommonJS para iconos
- /* #__PURE__ */ en forwardRef() wrappers para esbuild
- SVGR con viewBox preservado y width/height removidos
- Un componente por archivo (barrel files puros para re-export)
5.6 Fuentes de iconos de dominio identificadas
6. Validaciones de Conexiones
| Regla |
Detalle |
| Trigger solo como origen |
Un nodo Trigger no puede recibir conexiones entrantes |
| Un solo Trigger por flujo |
Cada flujo tiene exactamente un nodo Trigger como punto de entrada |
| Tipos compatibles |
Solo se permiten conexiones entre tipos compatibles (configurable por nodo) |
| Sin ciclos |
El sistema detecta y rechaza conexiones que crearían bucles infinitos |
| Máximo de conexiones |
Cada puerto (input/output) tiene un máximo de conexiones configurado |
| Edge con filtro |
Un edge puede tener una condición (filtro) que restringe qué datos pasan |
7. Serialización del Flujo (JSON)
Cada flujo se serializa como un objeto JSON con la siguiente estructura:
{
"id": "flow-uuid",
"version": "1.0.0",
"name": "Bienvenida nueva mascota",
"status": "active",
"nodes": [
{
"id": "node-1",
"type": "trigger-policy-change",
"category": "trigger",
"position": { "x": 100, "y": 200 },
"config": { /* configuración específica del tipo */ },
"label": "Alta de póliza"
}
],
"edges": [
{
"id": "edge-1",
"source": "node-1",
"target": "node-2",
"filter": { /* condición opcional */ }
}
],
"metadata": {
"createdAt": "2026-03-25T10:00:00Z",
"updatedAt": "2026-03-25T12:00:00Z",
"createdBy": "user-uuid",
"domainPack": "pet-health"
}
}
8. Deshacer / Rehacer
| Aspecto |
Especificación |
| Historial |
Stack de 50 operaciones máximo |
| Operaciones rastreadas |
Añadir/eliminar nodo, añadir/eliminar edge, mover nodo, cambiar configuración |
| Atajos |
Ctrl+Z (deshacer), Ctrl+Y o Ctrl+Shift+Z (rehacer) |
| Persistencia |
El historial se pierde al cerrar el editor (no persiste en BD) |
| Agrupación |
Las operaciones rápidas consecutivas se agrupan (debounce 500ms) |
9. Responsive
| Breakpoint |
Experiencia |
Limitaciones |
| ≥ 1280px (Desktop) |
Editor completo: canvas + panel lateral + minimap + toolbar |
Ninguna |
| 768–1279px (Tablet) |
Canvas completo, panel lateral como overlay deslizable |
Minimap oculto por defecto |
| < 768px (Móvil) |
Solo vista lectura: visualización del flujo y métricas |
Sin edición, sin drag-and-drop |
10. Temas Visuales
El editor soporta 4 temas seleccionables:
| Tema |
Mode |
Personalidad |
Uso previsto |
| ☀️ Light Vibrant |
Light |
Colores saturados, alto impacto |
Demos, presentaciones |
| ☀️ Light Corporate |
Light |
Tonos suaves, alineado DKV brand |
Producción diaria |
| 🌙 Dark Vibrant |
Dark |
Neon sobre oscuro |
Desarrolladores |
| 🌙 Dark Corporate |
Dark |
Elegante, profesional |
Producción nocturna |
Default: light-vibrant con auto-detección de prefers-color-scheme.
Documentos Relacionados