01 — DIAGNÓSTICO EN VIVOQué encontré en Railway
Entré al servicio postgres del proyecto IPSmart y conté filas de verdad.
El punto de partida es bueno: no arrancas de cero, arrancas de una empresa de 60.000 abonados que
alguien apagó.
El problema, en un solo dato
| Tabla | Primer movimiento | Último movimiento | Filas |
|---|---|---|---|
| billing.invoice | 2025-04-01 | 2026-09-02 | 723.664 |
| payments.payment | 2026-08-15 | 2026-09-02 | 696.121 |
| subscription.subscription | 2026-08-12 | 2026-09-02 | 60.001 |
| field_ops.work_order | 2026-09-02 | 2026-09-02 | 11.924 |
| party.party | 2026-08-10 | 2026-09-03 | 60.112 |
La foto
Todo se detiene el 2 de septiembre. Hoy es 9. Ningún pago nuevo, ninguna venta, ninguna orden cerrada, ningún cliente dado de alta ni retirado. Lo que se siente estático no es la falta de datos: es la falta de movimiento.
02 — HUECOSLos dominios que están en cero
De los 32 schemas de la base, doce no tienen ni una fila. Sus módulos enseñan pantallas en blanco por más que el resto tenga un millón de facturas.
| Schema | Tablas en 0 | Qué módulo deja ciego | Tratamiento |
|---|---|---|---|
| network | 40 | Red — OLT, ONU, NAP, alarmas, incidencias | sembrar + simular |
| messaging | 16 | Notificaciones y bandeja omnicanal | simular |
| contact_center | 15 | Call center — llamadas, colas, QA | sembrar + simular |
| sales_crm | 12 | Ventas — leads, oportunidades, comisiones | sembrar + simular |
| support | 10 | Soporte — tickets, SLA, PQR | → va a GLPI |
| inventory | 10 | Almacén — stock, seriales, movimientos | sembrar + simular |
| credit | 8 | Crédito / BNPL | simular |
| analytics | 24 | Todos los tableros y reportes agregados | ETL nocturno |
| collections | ~11 | Cobranza — convenios, promesas, cortes | simular |
| audit.outbox_event | 1 fila | La capa de IA y el Pulso del Sistema | emitir siempre |
Dos hallazgos que cambian el plan
Soporte no va a support.ticket. El ADR-0019 dice que GLPI 11 es la fuente
de verdad del dominio y el núcleo lo lee por su API v2; el propio DDL lleva escrito «NO implementar módulo
sobre este schema». Los tickets y quejas simulados se crean en GLPI, y
work_order.ticket_id apunta allá.
Analytics vacío es la razón real de que los tableros se vean planos. Los reportes que
leen OLTP devuelven cifras; los que leen fact_* / mrr_daily / arpu_monthly
devuelven cero. Sin ETL nocturno, el motor mueve tablas pero medio sistema sigue en blanco.
03 — ARQUITECTURAEl motor: cuatro piezas
Un servicio pequeño en Railway que despierta solo, un modelo de operación que convierte tus parámetros en eventos, un panel donde mueves esos parámetros, y una pantalla para ver el resultado. Sin IA en el bucle: el modelo es determinista y auditable; la IA consume lo que el motor produce.
El Reloj
Servicio sim-engine (Node, sin volumen) en el proyecto IPSmart. Solo despierta y llama funciones SQL.
- Latido — cada 3 min: lo que pasa en el momento.
- Cierre del día — 23:50: aging, cortes, ETL, rollups.
- Cierre del mes — día 1: tasa BCV, comisiones, contabilidad.
El Modelo
Schema sim: los parámetros, el modelo de capacidad y los generadores por dominio.
sim.parametro— las ~50 perillas.sim.escenario— juegos de parámetros guardados.sim.tick— bitácora de cada latido.- Todo marcado y borrable de un tirón.
El Panel de Mando
El formulario grande: personal, comercial, churn, cobranza, red, almacén y tiempo.
- Cada cambio recalcula la proyección antes de aplicarlo.
- Escenarios guardados y comparables.
- Aplicar en caliente, sin redesplegar nada.
La Sala de Control
Web propia en latido.ipsmart.app. Es donde se ve la vida pasando.
- Cinta de eventos en vivo (SSE).
- Contadores del día que suben solos.
- Embudo, capacidad y cuello de botella.
- Salud del motor y pausa.
Por dónde escribe
Por SQL directo, en funciones dentro del schema sim, una transacción por
latido. No por la API: aguanta el volumen, no depende de despliegues y reusa los invariantes que ya validó
la siembra (saldo cuadrado, tasa congelada en la fila, PII cifrada, cero cruces entre empresas). Con una
excepción deliberada: cada escritura emite su evento en audit.outbox_event,
que es lo que despierta la capa de IA, alimenta el Pulso horario y le da material al ETL.
04 — EL VOLANTEPanel de Mando
Esto es lo que pediste: mover los números y ver cómo se desenvuelve la operación. La maqueta de abajo funciona de verdad — mueve las perillas y mira qué pasa. Es el mismo modelo que irá dentro del motor, con los valores de arranque calibrados contra tu base.
La idea de fondo
Las instalaciones por día no son un número que se escribe: salen de la capacidad. Vendedores × visitas × conversión te da la demanda; cuadrillas × órdenes por cuadrilla te da la capacidad; y la diferencia es la cola de instalación. Por eso el simulador sirve para planificar y no solo para decorar: si contratas vendedores sin contratar cuadrillas, la cola crece y se ve.
05 — PARÁMETROSTodas las variables del simulador
La maqueta de arriba expone once perillas para que se entienda el mecanismo. El panel real
lleva las ~50 de esta tabla, agrupadas igual, con su valor de arranque y su rango. Todas viven en
sim.parametro y se cambian en caliente.
| Variable | Arranque | Rango | Qué mueve |
|---|---|---|---|
| Personal comercial | |||
| Vendedores de calle | 24 | 0 – 80 | Visitas y ventas diarias |
| Visitas por vendedor / día | 12 | 4 – 24 | Embudo de leads |
| Conversión visita → venta | 22 % | 5 – 45 % | Ventas cerradas |
| Ventas web + call center / día | 12 | 0 – 80 | Canal digital |
| Desistimiento antes de instalar | 8 % | 0 – 25 % | Ventas que nunca se instalan |
| Mix de planes | 6 planes | % por plan | ARPU y consumo de ONU |
| Comisión por venta instalada | USD 12 | 0 – 40 | Nómina comercial |
| Personal de campo | |||
| Cuadrillas | 44 | 5 – 120 | Capacidad total de órdenes |
| Técnicos por cuadrilla | 2 | 1 – 4 | Nómina y rendimiento |
| Órdenes por cuadrilla / día | 6,0 | 2 – 12 | Capacidad total |
| Duración media: instalación | 95 min | 45 – 240 | Mezcla de la agenda |
| Duración media: avería | 55 min | 20 – 180 | Mezcla de la agenda |
| Días laborables por semana | 6 | 5 – 7 | Capacidad semanal |
| Capacidad en sábado / domingo | 60 % / 20 % | 0 – 100 % | Guardia de fin de semana |
| Ausentismo | 6 % | 0 – 25 % | Capacidad efectiva |
| Órdenes reprogramadas (cliente ausente) | 11 % | 0 – 30 % | Cola y reintentos |
| Abonados y churn | |||
| Abonados al arrancar | 60.001 | real | Base de todo |
| Churn mensual | 2,5 % | 0,5 – 6 % | Bajas voluntarias |
| Motivos de baja | 4 | % cada uno | Precio, mudanza, calidad, mora |
| Reactivaciones de retirados | 7 % | 0 – 25 % | Recuperación |
| Cambios de plan (upgrade / downgrade) | 1,8 % / 0,9 % | 0 – 6 % | ARPU |
| Mudanzas | 0,5 %/mes | 0 – 3 % | Órdenes de campo |
| Facturación y cobranza | |||
| Ciclos de facturación | 3 | 1 – 4 | Días 1, 10 y 20 |
| ARPU mensual | USD 40,90 | 10 – 90 | Ingreso |
| Perfil de pago (al día / retraso / mora) | 84 / 12 / 4 % | suma 100 % | Cartera y morosidad |
| Días de gracia tras vencimiento | 5 | 0 – 15 | Cuándo entra en mora |
| Suspensión por mora | 45 días | 15 – 90 | Suspensiones diarias |
| Corte definitivo | 75 días | 45 – 180 | Retiros por mora |
| Reconexión tras pagar | 72 % | 20 – 95 % | Recuperación de cortados |
| Pagos móviles sin conciliar | 6 % | 0 – 20 % | Bandeja de caja |
| Devaluación mensual de la tasa | 2,5 % | 0 – 15 % | Tasa BCV del mes |
| Soporte, red y contacto | |||
| Averías al mes por 100 abonados | 6,5 | 1 – 20 | Carga de campo |
| Tickets al mes por 100 abonados | 8,5 | 2 – 30 | Carga de soporte |
| Mix de tickets | 4 tipos | % cada uno | Falla, factura, consulta, queja |
| Agentes de call center | 12 | 0 – 60 | Llamadas atendidas y abandono |
| Contactos por agente / día | 45 | 15 – 90 | Capacidad de atención |
| Gestores de cobranza | 8 | 0 – 40 | Gestiones y promesas |
| SLA por prioridad | 4 / 8 / 24 h | 1 – 72 h | Cumplimiento y alarmas |
| Alarmas de red / día | 25 | 0 – 200 | Ruido operativo |
| Incidencia mayor: cada | 10 días | 1 – 90 | Picos de tickets y SLA en rojo |
| Abonados afectados por incidencia | 400 – 2.500 | rango | Tamaño del pico |
| Almacén | |||
| Stock inicial de ONU | 3.000 | 0 – 20.000 | Instalaciones posibles |
| Punto de reorden | 1.200 | 0 – 10.000 | Cuándo se compra |
| Tiempo de reposición | 21 días | 3 – 90 | Riesgo de desabastecimiento |
| Equipo recuperado en retiros | 65 % | 0 – 100 % | Reingreso a almacén |
| Motor y tiempo | |||
| Velocidad | tiempo real | ×1 / ×10 / ×60 | Modo demo |
| Cadencia del latido | 3 min | 1 – 30 min | Granularidad de la cinta |
| Aleatoriedad (jitter) | 12 % | 0 – 40 % | Que dos días no salgan iguales |
| Semilla | fija | texto | Reproducibilidad |
| Empresas activas | 2 | demo-andina, demo-caribe | Alcance del motor |
Escenarios guardados
Cada juego completo de parámetros se guarda con nombre en sim.escenario y se cambia
de un clic: Operación base, Campaña de captación, Crisis de red,
Recorte de personal, Temporada alta. Se pueden programar por fecha, que es exactamente
lo que arma el arco de tres meses de la sección 08 — sin que nadie toque nada.
06 — RITMOEl día tipo: todo pasa todos los días
Esta es la corrección importante frente a la primera versión del plan. No es que el día 1 se factura y el resto del mes no pasa nada: todos los días hay ventas, instalaciones, averías, quejas, cobros y retiros. El calendario del mes solo marca los hitos que se concentran en una fecha; el resto es continuo.
| Todos los días, sin excepción | Al día (base) | Cómo se calcula |
|---|---|---|
| Leads que entran | ~300 | Vendedores × visitas + canal digital |
| Ventas cerradas | ~75 | Visitas × conversión + digital |
| Instalaciones ejecutadas | ~69 | Ventas menos desistimiento, limitado por capacidad |
| Averías atendidas | ~130 | Abonados × tasa de avería |
| Órdenes de campo totales | ~250 | Instalación + avería + mudanza + retiro + inspección |
| Pagos recibidos | ~2.000 | Perfil de pago sobre la cartera del mes |
| Tickets y quejas | ~170 | Abonados × tasa de contacto |
| Llamadas al call center | ~520 | Tickets × factor de contacto |
| Bajas de abonado | ~50 | Churn 2,5 % mensual repartido |
| Alarmas de red | ~25 | Planta externa simulada |
| Eventos en el outbox | ~4.000 | Uno por cada cosa que pasa |
Con la forma de un día real
- Curva horaria: arranque 7–9 h, meseta 9–13 h, pico 14–17 h, cola hasta las 20 h, madrugada casi muerta. Nada repartido plano en 24 horas — eso se nota a la legua.
- Semana: lunes y martes cargados, viernes de cierre, sábado al 60 %, domingo al 20 % y solo guardia. Se calcula contra el calendario real, no contra el número del día.
- Encadenado: la venta de hoy es la instalación de dentro de dos a cinco días, que es la primera factura del ciclo siguiente, que es el pago de la semana que viene. Nada aparece de la nada.
07 — HITOSLo que además se concentra en un día
Sobre el fondo continuo de la sección anterior, estos son los picos que caen en fecha fija. Con jitter, para que dos meses nunca salgan idénticos.
08 — NARRATIVAEl arco de septiembre a diciembre
Cada mes cambia de escenario solo, en la fecha programada. Quien mire el sistema en noviembre no ve lo mismo que en septiembre.
| Mes | Qué cambia en el panel | Qué se ve |
|---|---|---|
| Septiembre arranque |
Operación base: 24 vendedores, 44 cuadrillas, churn 2,5 %. | Crecimiento neto suave, cola de instalación estable, campo al día. Es la línea base contra la que se compara todo. |
| Octubre campaña |
Vendedores 24→40, conversión +6 pts, comisión al doble. Las cuadrillas no suben. | Embudo lleno, ventas disparadas — y la cola de instalación creciendo día a día hasta que se ve el cuello de botella. Es la lección que enseña el simulador. |
| Noviembre crisis |
Incidencia mayor de 6 h en una zona completa; tasa de avería ×3 esa semana. | Avalancha de tickets y llamadas, SLA en rojo, cuadrillas desviadas de instalación a avería, notas de crédito por indisponibilidad, y la recuperación día a día. |
| Diciembre temporada |
Perfil de pago al 92 % al día (aguinaldos), ausentismo 6→18 % (vacaciones), ventas −30 %. | Pico de recaudo con la mora derrumbándose, campo lento por personal de vacaciones, cierre fiscal y contable, y el reporte anual con doce meses de curva real. |
09 — FRONTLa Sala de Control
Dos pantallas en una: arriba el volante (el Panel de Mando de la sección 04), abajo el tablero de lo que está pasando ahora mismo. Pensada para dejarla abierta en un monitor.
Qué muestra el tablero
- La cinta. Cada evento que escribe el motor, en el momento en que lo escribe, por SSE. Filtrable por empresa y por tipo. Es la prueba visual de que hay pulso.
- Ocho contadores del día que suben solos: abonados activos, ventas, instalaciones, facturado, cobrado, órdenes cerradas, tickets abiertos, alarmas. Con delta contra ayer y contra el mismo día del mes pasado.
- Capacidad contra demanda en vivo: las dos barras que ves en la maqueta, pero con lo que realmente lleva ejecutado el día — y el cuello de botella dicho con palabras.
- Embudo comercial de hoy: leads → visitas → ventas → instalaciones, con la cola pendiente y los días de espera del cliente.
- Las últimas 24 horas en un área, sobre la curva esperada, para ver si el día va adelantado o atrasado.
- Mapa de zonas. Los 46 sectores de Táchira, Mérida, Nueva Esparta y Sucre se encienden donde está pasando algo. Hace obvio, sin explicarlo, que las dos empresas no se cruzan.
- Salud del motor. Último tick, próximo tick, eventos por minuto, errores de 24 h, y los controles: pausar, reanudar, acelerar, cambiar de escenario y rebobinar el día.
Vive en su propio subdominio, con la paleta canónica de la casa (violeta / índigo / cian, tema claro y
oscuro), y entra como tarjeta en el escritorio IPSmart. Como todo host que sirve tráfico, queda registrada
en uptime.ipsmart.app en el mismo trabajo que la publica.
10 — SEGURIDADBarandas: nada de esto es irreversible
- Candado por empresa. El motor solo escribe en tenants cuyo
slugempieza pordemo-. La empresa de la casa (IPSmart, 4 clientes reales) queda fuera por construcción, verificado en cada tick. - Todo marcado. Cada fila que escribe el motor lleva su marca de origen y el id del tick.
sim.rebobinar(desde, hasta)deja la base exactamente como estaba antes de esa ventana. - Interruptor de emergencia. Una fila en
sim.configapaga el motor sin redesplegar nada; el botón del panel hace lo mismo. - Verificador nocturno. Corre cada noche las mismas comprobaciones que validaron la siembra — cero descuadres de saldo, cero fugas entre empresas en las siete relaciones que podrían cruzarse — y si falla, para el motor y avisa por ntfy. Mejor un motor parado que una base mentirosa.
- Parámetros con tope. Cada perilla tiene rango máximo; no se puede poner el motor a generar un millón de órdenes por descuido.
- Respaldo previo. Antes del primer tick, volcado completo de los dos tenants demo a
~/Downloads, más rama y commit, según la regla de la casa.
11 — EDTCómo se construye
Once jornadas de construcción; después corre solo hasta el 31 de diciembre sin que nadie lo vigile. Esfuerzo en jornadas de trabajo, no en días de calendario.
Respaldo y barandas
Volcado de los tenants demo, rama de trabajo, schema sim, marca de origen, candado por empresa, interruptor y función de rebobinado. Nada escribe todavía.
Modelo de parámetros y capacidad
sim.parametro y sim.escenario con las ~50 variables, el modelo de capacidad (demanda contra capacidad, cola, cuello de botella) y su proyección a 90 días. Es el corazón: todo lo demás lo consume.
Reloj y bitácora
El servicio sim-engine en Railway, el latido, la curva horaria y semanal, el jitter con semilla, la bitácora de ticks y el emisor de outbox. Se prueba con un solo tipo de evento.
Cimientos de los dominios vacíos
Siembra mínima para que puedan tener vida: red (OLT, PON, NAP y ONU derivadas de las 46 zonas existentes), almacén con stock, equipos de venta con metas, agentes y colas del call center. Solo tenants demo; no toca ManagerOLT.
Ciclo comercial diario
Lead → visita → oportunidad → venta → orden de instalación → suscripción activa → primera factura. Con vendedores, metas, comisiones y desistimiento.
Ciclo financiero
Facturación en tres ciclos, pagos por perfil, conciliación, aging, cobranza escalonada, promesas, convenios, suspensiones, reconexiones, cortes y write-off.
Campo, red, soporte y churn
Órdenes con traza y evidencia limitadas por capacidad real, cola de instalación, alarmas, incidencia mayor programable, llamadas, tickets contra la API de GLPI y bajas por churn con su motivo y su retiro de equipo.
Analítica e IA
ETL nocturno de OLTP a dim_* / fact_*, rollups diarios (MRR, ARPU, churn, aging, productividad) y Pulso del Sistema horario. Es lo que enciende los tableros.
Panel de Mando y Sala de Control
El formulario grande con las ~50 perillas, escenarios guardados y proyección en vivo; y el tablero: cinta SSE, contadores, capacidad contra demanda, embudo, curva de 24 h, mapa y salud del motor.
Puesta en marcha
Despliegue en Railway, DNS de latido.ipsmart.app, alta en uptime, avisos por ntfy, ADR de la decisión y manual de operación (arrancar, parar, rebobinar, calibrar).
Total ≈ 12 jornadas · el grueso es delegable al copiloto; la calibración y el cuadre financiero, no.
12 — TU TURNOSeis decisiones antes de escribir código
Cada una lleva mi recomendación. Si estás de acuerdo con todas, basta con que digas «dale» y arranco por la Fase 0.
1 · ¿El motor escribe por SQL o por la API?
Recomiendo SQL directo, con emisión de outbox.
Aguanta el volumen, no depende de despliegues de la API y reusa los invariantes ya validados. El outbox mantiene viva la capa de IA igual que si pasara por el núcleo.
2 · ¿Los tickets y quejas van a GLPI o a support.ticket?
Recomiendo GLPI, por su API v2, respetando el ADR-0019.
Es más trabajo (otro proyecto de Railway y otro motor de base), pero llenar support.ticket crearía el maestro duplicado que la arquitectura prohíbe expresamente.
3 · ¿Se siembra el schema network?
Recomiendo sí, solo para los tenants demo.
Son 40 tablas en cero: sin planta externa no hay alarmas, ni incidencias, ni ONU que apagar al cortar a alguien. La topología se deriva de las 46 zonas ya sembradas y no toca el inventario real de ManagerOLT.
4 · ¿Un ciclo de facturación al mes, o tres?
Recomiendo tres ciclos: días 1, 10 y 20.
Con uno solo, 60.000 facturas caen el día 1 y el resto del mes la facturación está muerta — justo lo que quieres evitar. Con tres hay movimiento repartido, y es como opera un ISP de este tamaño.
5 · ¿Tiempo real o acelerado?
Recomiendo tiempo real, con latido cada 3 minutos, y modo acelerado como botón.
El calendario avanza con el calendario de verdad, así que las fechas siempre cuadran con «hoy». El ×60 queda en el panel para demos: comprime un mes en diez minutos cuando lo necesites enseñar.
6 · ¿Los parámetros arrancan en los valores que propongo?
Recomiendo arrancar con la tabla de la sección 05 y calibrar sobre la marcha.
Están calculados contra tu base real (60.001 suscripciones, 44 cuadrillas, ARPU USD 40,90) y dan una empresa que crece ~0,9 % al mes con la cola de instalación al límite — tensa pero sana. Si tienes cifras de un ISP que conozcas mejor, se cambian en un minuto: son filas de una tabla, no código.
13 — RIESGOSLo que puede salir mal
| Riesgo | Impacto | Cómo se corta |
|---|---|---|
| El motor escribe en la empresa real | Alto | Candado demo-% verificado en cada tick; el verificador nocturno para el motor si falla |
| Se rompe el cuadre de saldos y la demo queda mintiendo | Alto | Las comprobaciones de la siembra corriendo cada noche; motor parado ante el primer descuadre |
| Parámetros mal puestos generan una operación absurda | Medio | El panel proyecta a 90 días antes de aplicar, con rangos topados y aviso cuando el resultado no tiene sentido |
| Crecimiento de disco en Railway | Medio | Retención de 90 días en el outbox, particiones mensuales por adelantado, revisión de tamaño semanal |
| Datos que se ven falsos (curvas planas, todo a la misma hora) | Medio | Curva horaria, estacionalidad semanal y jitter con sal distinta por decisión — igual que hace la siembra actual |
| La API de GLPI cambia o se cae | Medio | El generador de tickets encola y reintenta, sin parar el resto del motor |
| El motor corre y nadie lo mira hasta diciembre | Bajo | Resumen diario por ntfy y la Sala de Control como tablero permanente |