Dos días dándole vueltas a algo que, sobre el papel, suena simple: que cuando pase algo importante en el panel, el equipo se entere al momento, en el ordenador o en el móvil, sin tener que ir a mirar. Lo que empezó siendo "vamos a poner un aviso en tiempo real" terminó siendo una persecución de tres fallos invisibles, uno escondido detrás del otro, y de paso una vuelta completa a cómo decidimos quién se entera de qué.
Queríamos que el equipo se enterara al instante de lo importante — un lead nuevo, un pedido pendiente — en el panel y en el móvil, en vez de tener que ir a mirar o esperar a que la pantalla se refresque sola. La parte del móvil (que llegue un aviso aunque tengas la app cerrada) salió relativamente bien. La parte de "al instante, con todo abierto" nos tuvo dos días enteros persiguiendo un fallo que no daba ni un solo error en ningún sitio — resultaron ser tres piezas rotas, cada una escondida detrás de la anterior. Y de paso, aprovechamos para arreglar algo que llevaba tiempo mal: antes los avisos le llegaban a todo el mundo por igual, ahora le llegan a quien de verdad le toca.
🎬 Por qué nos hacía falta esto
El panel de empleados llevaba tiempo avisando de cosas — leads nuevos, pedidos pendientes de revisar, correcciones de horario por aprobar — pero de la forma más simple posible: la propia pantalla se preguntaba sola cada 30 segundos "¿hay algo nuevo?". Funciona, pero con retraso, y solo si tienes el panel abierto delante. Si no lo tienes abierto, no te enteras de nada hasta que entras.
Queríamos dos cosas a la vez. Una: que si tienes la app del móvil, te llegue un aviso de verdad al teléfono aunque la tengas cerrada del todo — como cualquier otra app. Dos: que si tienes el panel abierto, delante, lo que pase aparezca al instante, sin esperar esos 30 segundos ni tener que refrescar tú mismo.
La primera parte, la del móvil con la app cerrada, salió relativamente bien. Se llama notificación push — el sistema operativo del teléfono se encarga de mostrártela aunque la app no esté corriendo, parecido a como te llega un WhatsApp sin tener la app abierta. Montarlo llevó su tiempo, pero fue un camino más o menos recto: configurarlo, registrar los teléfonos, probarlo, y funcionó.
La segunda parte — el aviso al instante, con el panel abierto — es la que nos tuvo dos días enteros dando vueltas.
🔌 La pieza que faltaba: hablar sin que le pregunten
Para el aviso al instante hace falta algo distinto a preguntar cada 30 segundos. Se llama WebSocket: en vez de que tu pantalla esté todo el rato preguntando "¿algo nuevo? ¿algo nuevo?", se abre una línea entre tu pantalla y el servidor que se queda ahí, abierta, y el servidor le habla en cuanto tiene algo que contar. Es la diferencia entre llamar cada minuto para preguntar si ha llegado un paquete, y que te avisen ellos en cuanto lo dejan en la puerta.
Montamos la pieza que gestiona esas líneas abiertas, la conectamos al panel y a la app, y probamos.
La primera señal fue buena: la línea se abría sin problema, sin ni un error, ni en el navegador ni en el servidor. Todo lo que se supone que tiene que decir "hola, aquí estoy" al conectar, lo decía.
Disparamos un aviso de prueba.
Nada.
Volvimos a intentarlo. Nada. Miramos la consola del navegador — sin errores. Miramos los registros del servidor — sin errores tampoco. Todo, en apariencia, funcionando perfectamente. Y ni un solo aviso llegando a ningún sitio.
Cuando algo da un error, sabes por dónde empezar a mirar. Cuando todo dice "todo bien" y sigue sin funcionar, no tienes ni una pista de por dónde tirar. Es peor un fallo silencioso que uno ruidoso.
🕵️ Las pistas falsas
Antes de encontrar lo que era de verdad, perseguimos varias teorías que parecían buenas candidatas y no lo eran.
La primera: pensamos que quizás dos partes del sistema estaban mirando datos distintos sin darse cuenta — como dos personas del mismo equipo trabajando cada una sobre su propia copia de un documento, sin saber que existía la del otro. Lo comprobamos a fondo, con pruebas cruzadas reales: hicimos que una parte escribiera algo y comprobamos si la otra lo veía. Lo veía. Misma copia, mismo documento. Descartada, después de un buen rato dándole vueltas.
La segunda: pensamos que el propio servidor tenía guardada una versión vieja de cómo debía comportarse, de cuando aún no estaba bien configurado, y que seguía usando esa versión vieja sin darse cuenta de que algo había cambiado. También descartada tras probarlo a fondo.
La tercera la dejamos para el final porque parecía la menos probable, y resultó ser la primera pieza real: una opción de configuración llevaba puesta, sin que nadie se hubiera dado cuenta, algo que le decía al sistema "solo apunta esto en un registro interno" en vez de "mándalo de verdad". Ni error, ni aviso — simplemente hacía justo lo que se le pedía, solo que lo que se le pedía estaba mal desde el principio. Cambiar esa única opción fue el primer paso de verdad hacia adelante.
🧩 La segunda pieza, escondida detrás de la primera
Con esa opción arreglada, la línea seguía abriéndose bien... pero los avisos individuales, esos que solo le tocan a una persona en concreto, seguían sin llegar. Otra vez sin ningún error a la vista.
Encontramos que una versión reciente de una de las piezas del sistema dejó de crear, sola y en silencio, algo pequeño pero necesario para que el navegador pudiera demostrar "soy yo, déjame escuchar mis propios avisos". Antes se creaba automáticamente; ahora ya no, y nadie avisa de ello — simplemente esa comprobación deja de existir, como si nunca hubiera hecho falta. Añadirla de vuelta a mano fue el segundo arreglo.
Con esa pieza puesta, probamos otra vez, convencidos de que ya estaba.
No estaba.
🎭 La tercera pieza: un disfraz perfecto
Esta fue la más rara de las tres. Cada vez que el navegador pedía permiso para escuchar sus propios avisos, el servidor le contestaba con un "vale" — pero un "vale" completamente vacío, sin ningún contenido dentro. Ni un error declarado, ni un mensaje, nada. Un sobre cerrado, sellado, y vacío por dentro.
Resultó que había una regla general en el sistema, pensada para otra cosa completamente distinta —cuando alguien entra a una página que no existe, mandarlo de vuelta a un sitio conocido en vez de enseñarle un error feo—, que sin querer también se estaba aplicando a esta pieza de permiso. El resultado: en vez de contestar con el contenido real, contestaba con un "todo bien" vacío que el navegador no sabía interpretar.
No era un fallo del sistema de avisos en sí. Era una regla de otra parte completamente distinta de la aplicación, escrita meses atrás para un problema que no tenía nada que ver, que por casualidad también afectaba a esto. Tres piezas, tres sitios distintos, ninguna relacionada con las otras a simple vista.
Arreglada esa tercera pieza, probamos una última vez.
Llegó. Al instante, sin esperar los 30 segundos, exactamente como tenía que ser desde el principio. Dos días después de empezar.
🎁 Ya que estábamos, lo hicimos mejor de lo planeado
Con el sistema ya funcionando de verdad, aprovechamos para hacerlo mejor de lo que iba a ser al principio, en dos sentidos.
Antes, todos los avisos de este tipo le llegaban solo a dos personas del equipo, sin importar de qué fueran — un aviso de un pedido pendiente le llegaba igual a quien no tenía nada que ver con pedidos. Ahora cada aviso llega a quien de verdad le corresponde: a quien gestiona pedidos le llegan los pedidos, a quien gestiona leads le llegan los leads, usando el mismo sistema de permisos que ya decide quién puede tocar qué en el resto del panel, en vez de inventar uno aparte.
Y añadimos una función nueva que no estaba planeada al principio: poder mandar un aviso suelto, escrito a mano, a todo el equipo o a una persona en concreto — para cosas como "reunión mañana a las diez" que no encajan en ningún tipo de aviso automático. Buscas a la persona, escribes el mensaje, y llega igual que cualquier otro aviso: en el panel y en el móvil.
📋 El resumen de daños
| Problema | Causa real | Arreglo |
|---|---|---|
| Conectaba bien pero nada llegaba | Una opción de configuración le decía al sistema que solo anotara los avisos, no que los mandara | Corregir esa opción |
| Los avisos individuales seguían sin llegar | Una pieza de permiso que el sistema dejó de crear sola desde cierta versión, sin avisar | Volver a crearla a mano |
| El permiso llegaba vacío, sin contenido | Una regla de otra parte de la aplicación, sin relación aparente, interceptaba la respuesta | Excluir esa ruta de esa regla |
| Solo dos personas veían todos los avisos | No había ningún reparto por responsabilidad | Cada aviso llega ahora a quien le toca de verdad |
| No había forma de mandar un aviso suelto | No existía esa función | Nueva pantalla para mandarlo a todos, a un grupo, o a una persona |
🎓 La moraleja
Dos días para algo que, contado ahora, cabe en un párrafo. Lo que más me quedó no fue ningún arreglo en concreto, fue la propia forma del fallo: todo, en cada paso, decía "todo bien" — la conexión, los registros, las respuestas del servidor. Ni un solo error real en ningún sitio. Y aun así, nada funcionaba.
Un fallo que grita es un fallo fácil. Te dice dónde mirar. Un fallo que se queda calladito, disfrazado de "todo correcto", es el que de verdad te hace dudar de ti mismo a mitad del segundo día. Las tres piezas que encontramos no tenían nada que ver entre sí — cada una, por su cuenta, era casi invisible. Juntas, dejaban el sistema entero mudo.
La única forma de encontrarlas fue dejar de confiar en "no hay error" como sinónimo de "funciona", y comprobar cada tramo del camino por separado, uno a uno, hasta encontrar el que de verdad se quedaba callado. Y ya que estábamos ahí, de paso dejamos el propio sistema de avisos mejor de lo que estaba antes de que se rompiera.