Visión general
El monorepo
Tres paquetes, cada uno con su propio node_modules (no hay workspaces):
| Paquete | Qué es | Se instala con |
|---|---|---|
backend/ | NestJS 11. Gateway de canales y orquestador de bots, todo en un proceso | npm |
frontend/ | Next.js 16 con App Router, Material UI sobre la plantilla Minimal v7 | yarn |
shared/ | Solo tipos de TypeScript, sin lógica | — |
docs/ | Este sitio y el manual de usuario | yarn |
shared/ se importa con el alias @xenpia/shared/* desde los dos lados.
El camino de un mensaje
inbound no tiene consumidor en este repositorioVarios canales encolan en inbound, pero no existe ningún @Processor('inbound') en
backend/src. WhatsApp y Telegram no dependen de ello porque procesan el bot de forma síncrona
dentro del propio webhook, pero para los demás canales esto es una diferencia de comportamiento
real que conviene tener presente antes de depurar «por qué no responde el bot en X».
Qué hace cada mitad
El backend recibe los webhooks de los canales, normaliza cualquier mensaje al mismo formato
(MessageEnvelope), ejecuta el bot con LangGraph y devuelve la respuesta por el canal
correspondiente. También expone la API que consume el panel: agenda, fuentes de datos, pagos,
facturación, canales. Ver Backend.
El frontend es el panel. Habla con Supabase directamente para casi todo (lectura de datos con RLS) y con el backend para lo que necesita lógica de servidor. El menú se construye en tiempo de ejecución según el tenant. Ver Frontend.
Supabase es la base de datos y el sistema de autenticación. El backend usa la clave de servicio y se salta RLS a propósito, porque atiende webhooks que no tienen usuario. El frontend usa la clave anónima y depende de RLS para todo.
Redis sostiene las colas de BullMQ, el límite de peticiones y la caché del runtime del bot.
Multitenencia
Todo cuelga de un tenant. Un tenant tiene bots, cuentas de canal, contactos, conversaciones y módulos activos. El aislamiento se hace con RLS en Supabase, no en el código de la aplicación: si una consulta del frontend devuelve datos de otro tenant, el fallo está en la política de la tabla.
Los módulos activos por tenant (tenant_modules) determinan a la vez qué pantallas aparecen en el
menú y qué herramientas tiene disponibles el bot.
Dos entornos
| Rama | Servidor | Frontend | API | Supabase |
|---|---|---|---|---|
dev | Test | test.xenpia.com | apitest.xenpia.com | proyecto dev |
main | Producción | app.xenpia.com | api.xenpia.com | proyecto main |
Cada uno con su proyecto de Supabase, su .env y sus contenedores. El detalle está en
Operaciones.