Cómo funciona el panel NODO por dentro.
Este documento acompaña al prototipo portal.html. Para cada menú y cada bloque explica qué se muestra, de dónde sale el dato, cómo se calcula y qué acción dispara. El prototipo tiene un interruptor "Lógica para dev" arriba a la derecha que muestra la misma información sobre cada bloque, en contexto.
1. Alcance y entregables
Archivos entregados
index.html— sitio público de NODO con "Iniciar sesión" arriba a la derecha, sección de tecnología (QuadMinds) y los 8 servicios.portal.html— panel completo (marca + admin). Login provisional1 / 1. Datos embebidos de las 17 marcas del consolidado.Logica-Portal-NODO.html— este documento.NODO_Consolidado_Marcas.xlsx— fuente de los datos de marcas (hoja DASHBOARD, BASE_DATOS y una hoja por marca).
Qué es real y qué es simulado en el prototipo
- real Marcas, paquetes/día, paquetes/mes, unidades, m³ y kg por semana, vehículo sugerido, distribución por provincia y localidad, productos y SKUs con medidas, canales de venta y su %, calendario semanal, ticket promedio (donde había extracto), pendientes de datos y lecturas logísticas. Todo sale del Excel.
- simulado Órdenes individuales (generadas a partir de los destinos reales de cada marca), estados del pipeline, tasa de entrega, lead time, choferes, conversaciones, movimientos de saldo, líneas de crédito, operaciones comex. Las fórmulas con que se simulan son las mismas que hay que implementar con datos reales.
2. Roles, login y acceso
| Rol | Quién | Ve | Puede |
|---|---|---|---|
| Admin NODO | Equipo NODO | Todas las marcas + selector + "Todas las marcas" (consolidado) + menú Admin (Marcas, Torre de control, Pendientes) | Todo. Puede "ver como marca". |
| Dueño de marca | Titular | Solo su marca | Todo dentro de su marca, incluyendo finanzas y equipo. |
| Operaciones | Empleado de la marca o ejecutivo NODO asignado | Su marca | Órdenes, envíos, colectas, inventario, atención. No ve saldo ni financiación. |
| Depósito | Armado | Su marca | Solo órdenes por empaquetar, etiquetas y picking. |
| Solo lectura | Contaduría | Su marca | Saldo, cobros, facturas y reportes. |
Login provisional del prototipo
1/1→ Admin NODO (empieza en "Todas las marcas").<id de marca>/1→ esa marca en rol dueño (ej.meno,tala,nativa-allura,purewall).- Deep links para demos:
portal.html?demo=1&brand=meno&view=envios&dev=1.
Login real
POST /auth/login {email, password} → {access_token (JWT 15 min), refresh_token}
JWT payload: {user_id, role, brand_ids[], is_nodo_admin}
Toda consulta filtra por brand_id del token salvo is_nodo_admin.
Opcional: magic link por WhatsApp (el dueño casi nunca tiene la clave a mano).
3. Arquitectura
- Backend: API REST (o GraphQL) + base relacional (PostgreSQL) + cola de eventos (Redis/SQS) para webhooks e integraciones. Multi-tenant por
brand_id. - Frontend: SPA (React/Vue) con el mismo mapa de vistas que el prototipo. El prototipo ya define layout, componentes y textos.
- Tiempo real: WebSocket para mapa en vivo, pipeline y bandeja de atención.
- IA: servicio separado que expone
/ai/chat(Capitán) y/ai/reply(atención al cliente) usando un modelo de lenguaje con tool use y RAG sobre la base de conocimiento de cada marca. - Jobs: cron 06:30 planificación de rutas y colectas; nocturno recálculo de KPIs, score, reposición, cash flow; cada 2 min polling de canales sin webhook.
4. Modelo de datos
Tablas principales. Todas con brand_id, created_at, updated_at.
| Tabla | Campos clave | Origen |
|---|---|---|
brands | id, nombre, cuit, plan, status, origen_stock, operador_actual, pickup_days, pickup_window, ai_autonomy_level, voice | Onboarding · consolidado |
brand_tariffs | brand_id, zone (AMBA · Interior BA · Interior · Patagonia), base_ars, included_kg, per_kg_ars, valid_until | Contrato |
skus | sku, brand_id, name, dims_cm, m3, kg, own_packaging, needs_bag, needs_label, needs_kit, cost_ars, consumption_days | Tienda + Tabla 1 del consolidado |
orders | order_id, brand_id, channel, external_id, customer{name, phone, email}, address{...geo}, items[{sku, qty, price}], total_ars, paid_at, source (store | ml | manual | subscription) | Webhooks de tienda |
shipments | shipment_id, order_id, status, zone, weight_kg, pieces, cost_ars, label_url, pickup_id, hub_id, route_id, driver_id, window, eta, admitted_at, delivered_at, sla_due_at, pod{...} | NODO + QuadMinds |
shipment_events | id, shipment_id, type, source (store | wms | quadminds | ai | user), payload, created_at | Log inmutable |
routes / route_visits | route_id, date, driver_id, vehicle, hub_id, planned_km, status; visits: sequence, shipment_id, eta, arrived_at, result, fail_reason | QuadMinds |
drivers | driver_id, name, phone, vehicle, plate, zone, metrics | QuadMinds |
pickups / pickup_points | pickup_id, brand_id, point_id, date, window, est_items, scanned_items, est_m3, est_kg, vehicle_type, status, discrepancies[]; points: type (warehouse | manufacturer | home), address, contact, hours | NODO |
stock / stock_movements | sku, hub_id, on_hand, reserved, in_transit; movements: type (inbound | outbound | adjust | transfer | return), qty, ref | WMS |
subscriptions | sub_id, customer_id, items[], frequency_days, next_ship_date, price, discount_pct, payment_token, status, cycles | NODO / Puentify |
conversations / messages | conv_id, customer_id, channel, order_id, status (open | ai | human | closed), csat; messages: from (customer | ai | agent), text, template_id, read_at | WhatsApp API |
message_templates | template_id, brand_id, trigger_event, channel, body, meta_status, enabled | Marca + Meta |
kb_documents · brand_voice · escalation_rules | Contenido, embeddings, tono, reglas de escalado | Marca |
balance_movements | mov_id, brand_id, type (topup | shipment_debit | refund_label | sla_bonus | subscription_payout | advance_repayment | referral_credit | fee), amount, ref_id | NODO |
credit_lines / credit_requests | product (advance | stock | account | campaign), limit, rate_monthly, used; requests: amount, term, status, schedule[] | NODO / fintech |
brand_scores | brand_id, score, components{...}, computed_at | Job semanal |
comex_ops / comex_documents | op_id, type (import | export), origin, destination, mode, incoterm, items[], stage, eta, costs[]; documents: type, file_url, status | NODO + forwarder |
alerts | type, severity, impact_ars, entity_ref, suggested_action, status | Motor de reglas + IA |
ai_actions / action_requests | Lo que el Capitán hizo o propone: tool, params, status (proposed | confirmed | executed | rejected), result | IA |
data_gaps | brand_id, field, reason, priority, status, asked_to, asked_at, resolved_at | Tabla 7 del consolidado |
users / memberships / notification_prefs / integrations / tickets / referrals | Acceso, avisos, conexiones, soporte, referidos | NODO |
5. Estados de un envío
pending_pack ──► ready ──► admitted ──► in_transit ──► out_for_delivery ──► delivered
│ │ (colecta (troncal) │ │
│ │ escaneada) │ ├──► failed_visit ──► out_for_delivery (reprogramado)
│ │ │ │ └──► at_branch ──► delivered | returned
└── address_incomplete ──► ready (al corregir) │ └──► rejected ──► returned
└──► returned ──► received_hub ──► restocked | discarded
| Estado | Quién lo pone | Evento | Qué dispara |
|---|---|---|---|
| pending_pack | Webhook de tienda | orders/paid | WhatsApp "compra confirmada"; suma a la próxima colecta |
| ready | Marca / depósito | label.generated | WhatsApp "preparando tu pedido" |
| admitted | Driver App (colecta) o WMS | pickup.scanned | Arranca SLA; débito de saldo |
| in_transit | WMS / Torre de control | trip.departed | — |
| out_for_delivery | QuadMinds | route.started | WhatsApp "salió a la calle" con chofer; "llega en 30 min" al acercarse |
| delivered | Driver App | visit.completed (POD) | WhatsApp entregado + reseña; cierra SLA; marca fulfilled en tienda |
| failed_visit | Driver App | visit.failed (motivo) | Incidente; Capitán propone 2 ventanas por WhatsApp |
| at_branch | WMS sucursal | branch.received | Recordatorios a las 24 y 48h |
| returned | WMS | return.received | Inspección → restocked (stock +1) o discarded; aviso a la tienda para reembolso |
admitted_at: AMBA 24h · capitales 24h · interior 48h · Patagonia 48h. Si delivered_at > sla_due_at por causa NODO → balance_movements type=sla_bonus automático por el valor del envío (garantía 24hs).6. Integraciones
| Sistema | Para qué | Cómo |
|---|---|---|
| Shopify | Órdenes, stock, fulfillment, tarifa en checkout | OAuth app. Webhooks orders/paid, orders/cancelled, fulfillments/update. Carrier Service API para cotizar por CP. inventory_levels/set para stock. Fulfillment Service para marcar enviado con tracking. |
| Tienda Nube | Ídem | App + OAuth. Webhooks order/paid, order/packed. Shipping carrier con tarifa por CP. PUT /products/{id}/variants/{vid} para stock. |
| Mercado Libre | Órdenes ML, envíos Flex/propios, stock | OAuth. Notificaciones orders_v2, shipments. Para ventas con envío a cargo del vendedor, NODO opera como logística propia y reporta tracking. PUT /items/{id} stock. |
| WooCommerce | Órdenes | REST v3 + webhook order.updated; plugin de tarifa. |
| QuadMinds | Planificación, tracking, Driver App, POD, torre de control | API: POST /orders (alta de visitas), POST /plans (optimización), GET /routes, GET /vehicles/positions, PUT /visits/{id} (reprogramar), POST /routes/{id}/transfer. Webhooks: route.planned/started/finished, visit.arrived/completed/failed, vehicle.position. Portal de órdenes → link público de seguimiento. |
| WhatsApp Business Cloud API | Notificaciones y atención IA | Número por marca (o de NODO). Plantillas utility aprobadas por Meta para cada trigger. Webhook messages para entrantes; ventana de 24h para respuestas libres. |
| Mercado Pago | Cobro de suscripciones, carga de saldo, cobros internacionales | Preapproval (suscripciones), Checkout Pro (topup), tokens de tarjeta. dLocal para LATAM. |
| AFIP | Facturas A/B/E, notas de crédito | WSFE vía facturador partner. |
| Georef AR | Normalizar direcciones | API pública de provincias/departamentos/localidades + geocoding (Google/Mapbox) para lat/lng. |
| el modelo de IA (el proveedor de IA) | Capitán NODO y atención al cliente | Messages API con tool use; modelo-chat para chat, modelo-analisis para análisis. Prompt caching del contexto de marca. |
| Forwarder / despachante | Comex | API de tracking del forwarder si existe; si no, carga manual del especialista NODO. |
| Fintech partner | Fondeo de líneas | API de originación: enviar score + solicitud, recibir aprobación y cronograma. |
| Puentify (opcional) | Club de suscriptores de marcas que ya lo usan | Webhook subscription.upcoming → NODO despacha; NODO devuelve delivered para puntos y regalos. |
7. Eventos y webhooks (bus interno)
Todo cambio relevante se publica como evento en la cola. Los consumidores son: notificaciones (WhatsApp/mail), motor de reglas (alertas), KPIs, tienda (fulfillment), IA (memoria).
| Evento | Productor | Consumidores |
|---|---|---|
| order.created / order.paid / order.cancelled | Integración tienda | Shipments (crear), WhatsApp (confirmación), Colectas (est_items), Stock (reservar) |
| shipment.status_changed {from, to} | Core | WhatsApp, tienda (fulfillment), KPIs, SLA, saldo (débito en admitted) |
| pickup.scheduled / pickup.scanned / pickup.done | Core + Driver App | Shipments (admitted), Stock (inbound si fabricante), WhatsApp a la marca |
| route.planned / route.started / visit.* / vehicle.position | QuadMinds | Shipments, mapa en vivo, WhatsApp (chofer, 30 min, entregado), incidentes |
| stock.changed {sku, hub, available} | WMS | Canales (sync), alertas (cobertura), reposición |
| subscription.charged / charge_failed / shipped / cancelled | Core / MP | Orders, WhatsApp, KPIs |
| conversation.message / escalated / closed | WhatsApp + IA | Bandeja, notificaciones al equipo, CSAT |
| balance.movement | Core | Saldo, alertas (saldo bajo), facturación |
| credit.requested / approved / disbursed / repaid | Financiación | Saldo, notificaciones |
| comex.stage_changed / document.missing | Comex | Inventario (in_transit), Capitán (pedir documento) |
| alert.created | Motor de reglas | Inicio, WhatsApp al dueño según prefs |
8. Importar el consolidado Excel
NODO_Consolidado_Marcas.xlsx tiene tres tipos de hoja. El importador tiene que leerlas así:
Hoja BASE_DATOS (48.316 filas) → semilla de demanda
| Columna | Destino | Nota |
|---|---|---|
| Marca | brands.nombre | Crear si no existe |
| Producto, SKU, m³ unitario, kg unitario | skus | "FALTA DATO" → sku sin dimensiones, marcar data_gap |
| Localidad, Partido, Provincia, CP | demand_seed.location | Normalizar con Georef; "FALTA DATO" en partido se resuelve por CP |
| Paquetes período, Días del período | demand_seed.paq_dia = paq / días | Es la columna I del Excel |
| Unidades período | demand_seed.uni_dia | "FALTA DATO" → null (no 0) |
| Canal de venta | demand_seed.channel | Normalizar: "Tienda propia Shopify" → Shopify; "Mercado Libre (estimado +X%)" → Mercado Libre con flag estimated=true |
| Fecha de carga | demand_seed.loaded_at |
Hojas M01…M17 (una por marca)
- Períodos por canal (filas 4–7): canal, desde, hasta, días →
brand_channels. - Tabla 1 Ficha de productos: producto, SKU, medidas, m³, kg, packaging, bolsa, etiqueta, kit →
skus. Cada "FALTA DATO" →data_gaps. - Tabla 5 Calendario operativo: paquetes por día de semana →
brand_weekday_profile(se usa para colectas hasta tener 8 semanas de datos reales). - Tabla 6 Situación actual: ticket promedio, unidades por pedido, operador actual, dirección de origen, costo de envío actual →
brands+brand_benchmarks. - Lectura logística: texto →
brand_notes(se muestra al admin). - Tabla 7 Pendientes: dato, por qué, prioridad, estado →
data_gaps.
Fórmulas del Excel que el sistema replica
| Métrica | Excel | Sistema |
|---|---|---|
| Paquetes/día por marca | SUMIFS(bdPaqDia, bdMarca, marca) | SUM(demand_seed.paq_dia) WHERE brand_id; luego COUNT(shipments)/días |
| Paquetes/mes | paq/día × 30 | ídem |
| Unidades/mes estimadas | informadas + (uni/paq con dato) × paq sin dato × 30 | ídem hasta tener ítems reales |
| m³/semana, kg/semana | paq/día × 7 × m³ (kg) unitario | ídem con skus.m3; en producción, Σ sobre ítems reales |
| Vehículo sugerido | <0,5 MOTO · <2 UTILITARIO · <6 CAMIONETA · CAMIÓN | misma regla sobre m³ del día de colecta |
| Posiciones de rack | ROUNDUP(m³ 7 días / 1,2) | ídem por hub |
estimated y el panel mostrarlo como "estimado" hasta que se conecte el canal o se confirme el dato.Inicio
| Bloque | Qué muestra | Consulta / fórmula | Acción |
|---|---|---|---|
| Costo promedio de envío | $ por pedido despachado | AVG(shipments.cost_ars) WHERE status ≥ admitted AND admitted_at ∈ periodo | — |
| Envíos diarios prom. | Paquetes por día + variación | COUNT(shipments admitidos)/días; delta vs período anterior de igual largo | — |
| Tasa de entrega | % con resultado final | delivered / (delivered + returned + failed_final) | — |
| Lead time | Pago → entrega | AVG(delivered_at − paid_at) días | — |
| Tiempo de procesamiento | Pago → admitido | AVG(admitted_at − paid_at) horas | — |
| Pipeline · estado actual | 6 contadores en vivo | COUNT(*) GROUP BY status sin filtro de fecha | Click → Órdenes filtrado por ese estado |
| Resultados del período | Entregados, fallidas, reprogramados, devolución, rechazados | COUNT(shipment_events) WHERE type IN (...) AND created_at ∈ periodo | Click → Órdenes |
| El Capitán te sugiere | Alertas ordenadas por impacto | alerts WHERE status=open ORDER BY impact_ars DESC LIMIT 5 | Botón → sección correspondiente |
| Últimos movimientos | 7 eventos recientes | shipment_events ORDER BY created_at DESC LIMIT 7 join orders, drivers | Click → drawer del pedido |
| Envíos por provincia | Mapa + barras | GROUP BY dest_province del período | — |
| Salud del negocio | Facturación, ticket, MRR, margen, costo logístico/venta, recompra | Ver glosario de KPIs | — |
Reglas de alertas (motor)
failed_visits_today ≥ 3→ severidad alta, impacto = n × ticket.stock_cover_days(sku) < 5→ alta, impacto = ventas perdidas estimadas.unused_labels > 10→ media, impacto = n × costo.pickup_tomorrow.status = scheduled→ informativa.credit_line.available > 0 AND saldo_dias < 5→ oferta de financiación.
Capitán NODO (IA)
Agente conversacional con acceso a los datos de la marca y capacidad de ejecutar acciones. Equivale al módulo Mindy de QuadMinds, ampliado con tienda, stock, cobros y financiación.
POST /ai/chat {brand_id, conversation_id, message}
System prompt: contexto de marca (nombre, tono, políticas, KPIs del día) + memoria (ai_memory)
Tools (JSON schema):
get_pipeline(brand_id) → conteos por estado
list_shipments(brand_id, {status, zone, since}) → lista
get_kpis(brand_id, days) → KPIs del período
reschedule_visits(shipment_ids[], window) → QuadMinds PUT /visits + WhatsApp [requiere confirmación]
send_whatsapp(template_id, shipment_ids[], vars)→ WhatsApp API [requiere confirmación]
create_pickup(brand_id, date, window, items) → pickups + QuadMinds [requiere confirmación]
stock_forecast(brand_id, days) → unidades a comprar por SKU
advance_offer(brand_id) → línea disponible y costo
open_ticket(brand_id, subject, order_id) → tickets
Respuesta: texto + acciones propuestas (botones) → action_requests (proposed) → al confirmar: executed
- Nivel de autonomía por marca (
ai_autonomy_level): 0 = solo propone; 1 = ejecuta acciones de bajo riesgo (avisos, reprogramaciones); 2 = ejecuta también colectas y compras sugeridas. - Todo queda en
ai_actionsy se muestra en "Lo que hizo hoy solo". - Memoria:
ai_memorypor marca con preferencias del dueño ("no me avises los sábados", "siempre ventana de mañana en Rosario").
Órdenes
| Elemento | Lógica |
|---|---|
| KPIs | Órdenes del período, ticket promedio, costo logístico/venta, % entregados en 24h (delivered_at − admitted_at ≤ 24h) |
| Filtros | Server-side: status, channel, q (id, cliente, localidad, SKU). Paginación por cursor. |
| Acciones masivas | Generar etiquetas (job PDF 10×15 con QR = shipment_id), avisar al cliente (plantilla), reprogramar (QuadMinds), sumar a colecta, rescatar (visita de retiro urgente), exportar. |
| Nueva orden manual | POST /orders {source: manual}. Normaliza dirección (Georef), cotiza (POST /quotes), crea shipment en pending_pack. |
| Importar CSV | Plantilla con columnas: cliente, teléfono, dirección, localidad, provincia, CP, SKU, cantidad, monto. Validación fila por fila con reporte de errores. |
| Drawer del pedido | Chofer (drivers), recorrido (shipment_events), POD (foto, firma, geo, receptor), comunicaciones (messages por order_id), datos, margen = monto × margen_bruto − costo_envío. Acciones: etiqueta, reprogramar, rescatar, devolución, reclamo. |
| Cotización | cost = base(zone) + max(0, kg − included_kg) × per_kg. Zona por CP: AMBA (CABA + GBA), Interior BA, Interior, Patagonia (Neuquén, Río Negro, Chubut, Santa Cruz, T. del Fuego). |
Envíos (QuadMinds)
| Pestaña | Fuente | Lógica |
|---|---|---|
| En vivo | vehicle.position (WebSocket) | Mapa con vehículos que llevan paquetes de la marca; rutas activas con avance = visitas completadas / total; próximas entregas con ETA de QuadMinds. |
| Rutas del día | Job 06:30 → POST quadminds/plans | Input: shipments ready/admitted por hub, vehículos disponibles, ventanas, capacidad m³/kg, tiempos de servicio (2 min domicilio, 5 min sucursal), prioridad (suscripciones vencidas, reprogramados). Output: rutas con secuencia y ETA. Reoptimización intradía. |
| Choferes | drivers sincronizada | first_attempt_rate, on_time (dentro de ventana), calificación (encuesta WhatsApp 1–5). |
| Incidencias | incidents | Creadas por visit.failed (motivo), address_incomplete, at_branch > 48h. Playbook por tipo ejecutado por el Capitán; se cierra al resolver el envío. |
| Comprobantes (POD) | visit.completed.pod | Foto, firma, lat/lng, receptor, condición del bulto. Copia en storage NODO, retención 5 años. Export PDF/Excel. |
| Logística inversa | returns | Etapas: requested → pickup_scheduled → in_transit → received → inspected. Retiro = visita tipo pickup en QuadMinds. Apto → stock +1 y aviso a tienda para reembolso. |
| SLA y calidad | shipments + balance_movements | % dentro de SLA por zona, bonificado (sla_bonus), reclamos abiertos, NPS post-entrega, motivos de fuera de plazo (fail_reason agrupado). |
Módulos de QuadMinds que se usan
- Planificador de rutas (optimización multi-restricción, multi-depósito).
- Seguimiento de rutas (GPS, cumplimiento de secuencia, alertas, agregar/quitar/transferir órdenes en ruta).
- Driver App (secuencia, llegada, entrega/falla con motivo, foto, firma, cobranza).
- Torre de control (viajes troncales entre hubs, kanban).
- Portal de órdenes (link público de seguimiento por pedido).
- Add-ons: módulo de cobranzas (contra reembolso), liquidación de viajes (transportes terceros), control de emisiones, IoT (temperatura).
Colectas
- Generación: cron nocturno crea la colecta del día siguiente por marca según
pickup_days;est_items = COUNT(orders paid AND shipment.status IN (pending_pack, ready) AND pickup_id IS NULL);est_m3/est_kgdesde skus; vehículo por regla de m³. Se reajusta a las 06:30 con las ventas de la noche. - Ruta de colectas: todas las colectas de la zona se envían a QuadMinds como visitas tipo pickup en una ruta de colectas separada de la de reparto.
- Ejecución: Driver App escanea cada QR →
pickup.scanned→ shipment pasa a admitted. Declarados vs escaneados →discrepanciescon foto. Remito digital firmado. - Colecta en fabricante:
pickup_points.type = manufacturerconexpected_items[](remito). Al ingresar al hub:stock_movements inboundpor SKU y comparación con remito. - Tu semana operativa: perfil por día de semana (Tabla 5 del consolidado, luego promedio móvil 8 semanas).
- Pedir colecta extra / cambiar ventana:
POST /pickups,PUT /pickups/{id}; confirmación por WhatsApp a la marca.
Inventario
- Stock unificado:
available = on_hand − reservedpor SKU (suma de hubs). Se empuja a todos los canales en < 60 s en cada cambio. Race entre canales → backorder + aviso IA al cliente. - Comprometido: suscripciones a 7 días + órdenes pagas no despachadas.
- Cobertura:
on_hand / AVG(units_out_per_day, 14d). Semáforo: ≤ 5 rojo, ≤ 12 ámbar. - Reposición sugerida: punto de pedido =
lead_time_days × salida_dia + stock_seguridad; cantidad =salida_dia × 21 + comprometido. Un clic → pickup en fabricante con remito. - Depósitos: distribución sugerida por % de envíos por región; posiciones de rack =
ROUNDUP(m³ 7 días / 1,2). - Ficha de SKU: medidas, kg, packaging, bolsa, etiqueta, kit, costo, días de consumo (para recompra). Los flags en "FALTA DATO" se muestran como pendientes.
- Kits: si
needs_kit, el picking lista componentes y descuenta SKUs hijos.
Suscripciones
- Modelo y eventos: ver tabla de datos. Cobro D-2 vía Mercado Pago; OK → orden con
channel = Suscripcióny prioridad alta en ruteo; falla → reintento 24h + WhatsApp con link de tarjeta. - Calendario:
GROUP BY next_ship_date; detalle del día = suscripciones, facturación comprometida, unidades a preparar, distribución por provincia, rutas sugeridas (n = ceil(envíos/40)). - Recompra predicha: por SKU
consumption_days; por cliente ajuste con su historial; probabilidad ≥ 70% dispara "se te está por acabar". Botón "ofrecer suscripción" = campaña WhatsApp con 15% off. - Señales: tarjeta por vencer (< 30 d), sin stock para la fecha, top 5% LTV, riesgo de baja (pago fallido o 2 saltos), puede subir de plan (compra extra recurrente).
- KPIs: activas, MRR, churn mensual, LTV = ticket × margen / churn.
- Si la marca usa Puentify, NODO solo despacha (webhook
subscription.upcoming).
Atención al cliente con IA
| Pestaña | Lógica |
|---|---|
| Conversaciones | Bandeja de conversations con estado ia/humano. Identificación del pedido por teléfono. Respuesta IA: modelo de lenguaje + RAG (kb_documents) + tools de pedido. Guardrails: no inventa fechas, no da consejo médico, no promete reembolsos. "Tomar yo" → status human. |
| Automatizaciones | 10 plantillas por trigger (confirmación, preparando, salió con chofer, llega en 30 min, entregado + reseña, no estabas, consulta libre, suscripción se despacha, se te está por acabar, escalado). Cada una: canal, enabled, body con variables, métricas (enviados, leídos, respondidos). Plantillas WhatsApp aprobadas por Meta (utility). |
| Base de conocimiento | kb_documents con embeddings: fichas de producto (importadas de la tienda), políticas, tiempos y costos (automático desde tarifas), FAQ, promociones (sincronizadas), horarios. Aprende de respuestas humanas: propone incorporar, la marca aprueba. |
| Reglas de escalado | escalation_rules: sentimiento negativo / palabras clave (denuncia, estafa), pedido de reembolso, 3 turnos sin resolver, producto dañado (pide foto y abre reclamo), consulta médica, cliente VIP, fuera de horario. Al escalar: round-robin a agentes de la marca o de NODO, resumen de 3 líneas. |
| Voz de la marca | brand_voice: tono, tratamiento, emojis, firma, palabras prohibidas, saludo. Se inyecta en el system prompt y valida plantillas. |
KPIs
- Conversaciones del período; % resueltas por IA (
closed_by = ai); tiempo de primera respuesta; CSAT; reclamos evitados (consultas de estado resueltas sin humano); ventas recuperadas (carritos + fallidas recuperadas + recompras atribuidas).
Rentabilidad
- Insumos: ventas por línea, costo de envío real, costo de producto por SKU (carga la marca), gasto en ads (manual o API Meta/Google), CAC por primera compra.
- Por producto: facturación, envío prorrateado, CAC atribuido, margen real =
(fact − producto − envío − CAC) / fact. Señal: > 40% escalar · > 30% sostener · > 18% revisar precio · else no rinde. - Por zona:
GROUP BY zone, margen después del envío. - Jugadas:
playbook_itemspor reglas (zona con margen bajo → mínimo de envío gratis; SKU rentable fuera de suscripción → crear plan; clientes one-shot > 90 d → campaña; densidad kg/m³ alta → cotizar por peso) revisadas en la sesión de escala; estado y medición de impacto a 30 días.
Saldo y cobros
- Prepago: carga por transferencia / Mercado Pago / débito automático. Débito por envío al evento admitted. Alerta saldo < 3 días; con cuenta corriente activa se cubre automáticamente.
- Liquidaciones (si NODO cobra por la marca): semanal =
cobros − fee pasarela − envíos − adelantos. Factura AFIP por liquidación. - Movimientos:
balance_movementscon tipo y referencia. Export Excel. - Cash flow proyectado: tendencia 12 semanas × estacionalidad + MRR comprometido; recálculo nocturno.
- Tarifa:
brand_tariffscon vigencia; los conceptos incluidos (inversa, colecta, panel, IA) se listan en $0.
Financiación
| Producto | Límite | Plazo | Tasa ref. | Repago |
|---|---|---|---|---|
| Adelanto de liquidación | 80% de la liquidación estimada | Hasta que ingresa | 3,9% mensual | Descuento automático de la liquidación |
| Financiación de stock | 60% de la facturación mensual | 3 a 6 cuotas | 4,4% | Desembolso al proveedor; cuotas desde saldo/liquidaciones |
| Cuenta corriente de envíos | 1,5× gasto logístico mensual | 30 días | 2,9% | Débito a 30 días |
| Capital para campañas | 25% de la facturación mensual | 3 cuotas | 4,9% | Cuotas desde liquidaciones |
- Score (0–100, semanal): antigüedad, volumen, tasa de entrega, regularidad de colectas, saldo promedio, reclamos. ≥ 65 habilita adelanto y cuenta corriente; ≥ 75 stock y campañas.
- Simulador: cuota francesa
M·i·(1+i)^n / ((1+i)^n − 1); adelantoM·(1+i). - Flujo:
credit_requestsrequested → approved (auto si dentro de límite, si no revisión) → disbursed → repaid. Contrato con firma electrónica; validación de identidad RENAPER la primera vez; CFT informado. - Fondeo: propio o fintech partner por API.
Comex
- Operaciones:
comex_opscon etapas quote → booking → shipped → in_transit → customs → cleared → in_warehouse. Tracking del forwarder por API o carga manual. Al llegar:stock_movements inbound. Stock en tránsito visible en Inventario. - Cotizador: flete (tarifas de forwarders por ruta y modo) + seguro + derechos (tabla NCM por posición) + tasa estadística 3% + IVA/percepciones (separados como crédito fiscal) + despachante y puerto (tabla NODO) + flete interno. Devuelve desglose y ETA.
- Vender en LATAM: activación por país en checkout; pedidos con
country ≠ ARse agrupan semanalmente en una operación de exportación courier simplificada (factura E); última milla con partners locales; cobro en moneda local (dLocal / MP país) y liquidación a la marca. - Documentos: checklist obligatorio por tipo y modo (proforma, factura comercial, packing list, BL/AWB, certificado de origen, despacho, seguro). El Capitán reclama faltantes.
- Habilitaciones: registro importador/exportador, clave fiscal, ANMAT/INAL/SENASA según rubro, poder al despachante, cuenta en USD. Se inician en el onboarding.
- Cruce con financiación: la línea de stock puede pagar directamente al proveedor del exterior.
Referidos
referralspor linknodo.ar/r/{brand_id}o código en onboarding. Crédito = 10% de los envíos del referido en su primer mes, para ambos, comobalance_movements type=referral_credit. 3 referidos activos → sesión extra de escala.
Soporte
ticketscon categoría, pedido asociado, asignado, SLA (primera respuesta 30 min en horario; resolución 24h). Se abren desde el panel, desde un pedido, desde WhatsApp del ejecutivo o los abre el Capitán al escalar.- Estado de servicios:
GET /statuscon hubs, troncales, integraciones. - Ejecutivo asignado por marca (
brands.account_manager) con WhatsApp directo.
Configuración
- Conexiones:
integrationscon OAuth por proveedor, estado, última sincronización, secreto de webhook. - Datos de la marca:
brand_settings(origen del stock, operador actual, días y ventana de colecta, stock nacional/importado, lead time, costo de envío actual). Cada campo vacío corresponde a undata_gap; al completarlo se cierra solo. - Ficha de productos: edición de
skuscon los 4 flags de packaging. - Equipo:
membershipscon rol. - Notificaciones:
notification_prefspor evento y canal. - Facturación: datos fiscales y facturas mensuales (PDF).
Admin · Marcas
- Réplica de la hoja DASHBOARD: por marca paq/día, paq/mes, unidades, m³/sem, kg/sem, vehículo, canales, localidades, ticket, pendientes alta. Ordenable y buscable. Click → entra al panel de la marca (setBrand + Inicio).
- Ranking por volumen, mapa de la cartera, lecturas clave.
- Onboarding: alta → conexión de canales (importa 90 días) → ficha de SKUs → punto de retiro y días → tarifa 90 días → WhatsApp y voz → usuarios.
- Importador del consolidado (sección 8).
- "Todas las marcas" = sumas de volumen y promedios ponderados por paquetes.
Admin · Torre de control
- Demanda por región (agrupación de provincias) → input para hubs y troncales.
- Viajes troncales del día (TMS larga distancia de QuadMinds): carga por región = Σ paquetes de todas las marcas con destino ahí.
- Semana de la red (Σ perfiles semanales), flota por marca, capacidad usada = paquetes hoy / capacidad diaria (Σ vehículos × paradas máx.).
- Alertas de red: cortes de ruta, hubs al límite, datos faltantes que bloquean cotización.
Admin · Pendientes de datos
data_gapsde todas las marcas (Tabla 7 del consolidado), filtrable por marca y prioridad. Cada gap está mapeado a un campo real (brand_settings o skus). Resolver = completar el campo o marcar manualmente.- "Pedir todos por WhatsApp": el Capitán manda a cada marca la lista con la explicación de por qué se necesita.
- Los 3 datos que más faltan en la cartera: costo de envío actual, operador actual, dirección de origen. Son las primeras preguntas del onboarding.
Glosario de KPIs
| KPI | Definición |
|---|---|
| Costo promedio de envío | AVG(cost_ars) de envíos admitidos en el período |
| Envíos diarios promedio | Envíos admitidos / días del período |
| Tasa de entrega | delivered / (delivered + returned + failed_final) |
| Entregados en 24h | delivered con (delivered_at − admitted_at) ≤ 24h / delivered |
| Lead time | AVG(delivered_at − paid_at) en días |
| Tiempo de procesamiento | AVG(admitted_at − paid_at) en horas |
| Cumplimiento SLA | delivered_at ≤ sla_due_at / delivered |
| Visitas fallidas % | failed_visit / visitas |
| Ticket promedio | SUM(total_ars) / COUNT(orders) |
| Costo logístico / venta | AVG(cost_ars) / AVG(total_ars) |
| MRR | Σ precio mensualizado de suscripciones activas |
| Churn | canceladas en el mes / activas al inicio |
| LTV | ticket × margen bruto / churn mensual |
| CAC | gasto en ads / clientes nuevos |
| Recompra 90 d | clientes con ≥ 2 compras en 90 d / clientes |
| Margen de contribución | (ticket − producto − envío − CAC) / ticket |
| Cobertura de stock | on_hand / salida diaria promedio 14 d |
| % resueltas por IA | conversaciones cerradas por IA / cerradas |
| Score NODO | 0–100 ponderado: antigüedad, volumen, entrega, colectas, saldo, reclamos |
Roadmap de implementación sugerido
| Fase | Alcance | Resultado |
|---|---|---|
| 0 · Semilla (2 semanas) | Auth, brands, importador del consolidado, Admin Marcas y Pendientes, panel de marca con datos semilla. | Las 17 marcas ven su panel con sus números reales del Excel. |
| 1 · Órdenes y envíos (4–6 semanas) | Integraciones de tienda (Shopify, Tienda Nube, ML), shipments y estados, cotizador, etiquetas, colectas, QuadMinds (planificación, tracking, Driver App, POD), WhatsApp de notificaciones. | Operación real de punta a punta con seguimiento en vivo. |
| 2 · Cliente e IA (4 semanas) | Atención al cliente IA (bandeja, plantillas, KB, escalado), Capitán NODO con tools de lectura y reprogramación, alertas. | 85%+ de consultas resueltas sin humano. |
| 3 · Stock y suscripciones (4 semanas) | WMS básico (inbound/outbound/ajustes), stock unificado multicanal, reposición sugerida, suscripciones con cobro MP y calendario, recompra predicha. | Inventario confiable y recurrencia. |
| 4 · Finanzas (4 semanas) | Saldo y movimientos, liquidaciones, facturación AFIP, score, líneas de crédito con fintech partner, rentabilidad. | Financiación operativa. |
| 5 · Comex y red (6 semanas) | Operaciones comex, cotizador, documentos, exportación LATAM, torre de control global, referidos. | Ecosistema completo. |