Jones: la consola para operar un negocio por WhatsApp
Jones vende y entrega edición de fotos por WhatsApp, con un agente que conversa y un sistema que opera una sola persona. Trabajo en la consola donde esa persona observa y gobierna al agente, y lideré su migración a un sistema de diseño completo con modo oscuro, dirigiendo un equipo de agentes de IA.

La consola no es un panel de administración. Es la superficie donde una persona observa y gobierna a un agente que habla con clientes y mueve dinero.
Jones restaura y edita fotografías y hace todo el negocio por WhatsApp, sin app propia: el cliente llega desde un anuncio, conversa con un agente, recibe una vista previa de su foto antes de pagar, paga y recibe el resultado en el mismo chat. Detrás de esa conversación hay un sistema que opera una sola persona, casi siempre desde el teléfono.
Trabajo en Jones con un equipo pequeño. Mi foco es la consola de operación: cómo se organiza, cómo se lee y cómo se mantiene. Este caso cuenta la arquitectura que la sostiene y la migración de la consola a un sistema de diseño completo, que hice dirigiendo un equipo de agentes de IA.
Una arquitectura para una sola persona
Todas las decisiones del sistema parten de una restricción escrita en sus requisitos: que un operador único pueda sostener el sistema entero en la cabeza a las 3 de la mañana. De ahí salen reglas poco comunes. Cualquier transición de estado tiene que encontrarse con un grep en menos de diez segundos. Ningún archivo del núcleo pasa de 400 líneas, y una prueba lo verifica en cada build. Y cambiar un texto, un horario o apagar la operación nunca puede requerir un deploy, porque todo eso vive en la base como dato.

Algunas decisiones que definen el sistema, con su porqué:
- —Código propio y no un motor de workflows. Lo que toca dinero necesita idempotencia, pruebas y poder depurarse, y el desarrollo asistido por IA sobre JSON de workflows opera a ciegas.
- —Postgres como cola, con FOR UPDATE SKIP LOCKED y sin Redis. Así, confirmar un pago y encolar su generación ocurren en la misma transacción.
- —Una sola función para enviar mensajes. Antes de salir, cada mensaje pasa las mismas verificaciones: baja, estado, hora de corte, ventana de 24 horas, ritmo e interruptor de apagado.
- —El agente nunca certifica dinero. El modelo aporta juicio y redacción; el código recalcula la verdad en el mismo turno.
- —Un worker con cuatro bucles independientes. Antes, una generación de imagen larga dejaba a todos los clientes sin respuesta.
- —La consola en React y Vite, servida por el mismo Fastify y no con Next. Un despliegue, una sesión y un solo modelo mental.
Una consola que sigue el arco del negocio
El menú no sigue los módulos del sistema sino las preguntas del operador, en tres grupos: Atender (Dashboard, Chats, Contactos, Pedidos), Entender (Vender, Aprender, El asistente) y Definir (El producto). El Dashboard se lee en orden de decisión: primero el periodo, luego cómo va, el embudo, las cohortes y los anuncios.



Pensada para el teléfono
El operador usa la consola casi siempre desde el celular, así que las vistas tienen versión móvil propia y no una versión recortada. La barra inferior reemplaza al menú lateral, las tablas se vuelven listas con la información que decide y las cifras mantienen su lectura.

Entender: del embudo a lo que el asistente no supo hacer
Las vistas de Entender existen para que la operación mejore sola con el tiempo. Vender muestra el camino de la gente, de anuncio a recompra, y señala el escalón donde se cae. Aprender reúne lo que el asistente no pudo resolver sin ayuda y los experimentos en curso, con una regla: el sistema propone, la persona aprueba. El asistente muestra qué hizo el agente y qué frenó el código, y solo marca en rojo lo que pide a una persona.



Crear un producto: una decisión y cuatro pasos
Jones no vende solo fotos: la consola permite crear productos nuevos sin tocar código. El catálogo muestra cada producto con su estado y, cuando está apagado, lo que le falta para vender.

Crear un producto pide solo dos cosas: el nombre y qué entrega. El precio, las fuentes y el prompt viven en su ficha, porque pedirlos aquí obligaría a decidirlos en el momento de menos información, antes de haber visto nada del producto, y alargaría el único paso que debería ser inmediato.
Qué entrega sí se pide al crear, porque es la única decisión que no se puede cambiar después: el sistema toma caminos distintos en la cola y en el pago según el tipo, y la ficha cambia de secciones. Por eso son dos opciones visibles y excluyentes, no un desplegable: hay que ver las dos para elegir bien la única vez que se puede elegir. Y el producto nace apagado.

Con los productos de documentos apareció un problema de recorrido. El operador no encontraba cómo seguir después de crear uno: la ficha decía «falta la muestra, faltan entregables, falta un paquete» como tres motivos sueltos, sin decir cuál iba primero ni que al final había que encenderlo. La solución fue una sola lista con el recorrido entero, en orden, que se pinta en dos lugares desde la misma fuente para que nunca digan cosas distintas.


La migración a un sistema de diseño
La primera versión de la consola tenía su propia hoja de estilos, componentes hechos a mano y 17 diálogos nativos del navegador para confirmar acciones. El foco, el teclado y el lector de pantalla funcionaban a medias, y el sistema de diseño no tenía dueño. La migramos a la plantilla Finora de shadcn/studio, con modo claro y oscuro, en 32 commits entre el 25 y el 27 de septiembre de 2026.
La plantilla está hecha para Next y la consola corre en Vite. De sus 395 archivos, solo 23 importaban Next, así que en lugar de cambiar el stack resolvimos esa parte con un adaptador que imita los enlaces y la navegación de Next sobre el enrutador propio de la consola.
Las reglas de la migración fueron estrictas a propósito:
- —Solo cambia la interfaz; nunca la API ni la lógica.
- —La migración cambia la representación, no el contenido. Cada pantalla sigue la composición de una vista de la plantilla y conserva sus datos y su orden.
- —Solo entra lo que trae la plantilla. Los 36 componentes base quedan congelados y se comparan por huella contra la versión original.
- —En las pantallas migradas no hay elementos HTML crudos ni estilos en línea, y una prueba lo hace cumplir en cada build.
El trabajo lo hizo un equipo de agentes de IA que yo dirigía: dos de front y uno de QA que validaba cada pantalla en el navegador contra copias fijas. Nada se integró hasta que QA lo aprobaba.

Stack
| Capa | Herramienta |
|---|---|
| Backend | Node 22, TypeScript, Fastify 5, pg sin ORM, zod |
| Base y archivos | Supabase Postgres (con recuperación a un punto en el tiempo) y Storage |
| Cola | Tabla en Postgres con FOR UPDATE SKIP LOCKED |
| Mensajería | WhatsApp Cloud API; Meta Marketing y Conversions API para medir |
| IA | Modelos de lenguaje para conversar, clasificar y leer comprobantes; edición de imagen para generar |
| Consola | React 19, Vite, Tailwind 4, Base UI, TanStack Query y Table, Recharts |
| Sistema de diseño | Plantilla Finora de shadcn/studio, con modo claro y oscuro |
| Despliegue | Railway: servicio web y worker desde el mismo repositorio |
Lo que aprendí
Que el desarrollo guiado por especificaciones puede producir un sistema correcto que su operador no entiende, y eso también es una falla. Las restricciones que parecen de ingeniería, como el grep de diez segundos o el tope de líneas, son en el fondo decisiones de diseño para una persona concreta.
También que el cuello de botella no siempre está donde uno mira. En un momento, la consola se estorbaba a sí misma: su pantalla de escalados releía la tabla de eventos entera en cada refresco. Y que una respuesta 200 no dice que la app arranque. Después de cada cambio hay que abrir la pantalla que se tocó y mirarla.
Y aprendí a dirigir agentes con reglas escritas antes que con instrucciones sueltas. Una regla que una prueba hace cumplir es más confiable que una que depende de que alguien la recuerde.
