Bienvenido

Plataforma

GRAMA

Next.js 16TypeScriptSupabasePostgreSQLpgvectorGemini APIMCPTailwind CSS 4Vercelk6

Motor de aprendizaje con enfoque en IA y LMS para la capacitación docente en varias instituciones, construido para Industrias Roland Print S.A.C. y en producción desde junio de 2026. Un asistente de aprendizaje RAG sobre Google Gemini, integración MCP y contenido de cursos autogenerado, sobre un monolito modular hexagonal/DDD con un esquema PostgreSQL multi-inquilino protegido con Row Level Security.

El problema

Industrias Roland Print necesitaba una única plataforma de capacitación para docentes de varias instituciones. Los LMS genéricos como Moodle exigían mucha configuración y aun así no tenían las reglas de progresión, las analíticas institucionales ni la asistencia con IA que el cliente quería. El reto era construir una plataforma lista para producción que atendiera a muchas instituciones desde un solo despliegue, mantuviera aislados los datos de cada inquilino y escalara a decenas de miles de usuarios con un presupuesto de infraestructura ajustado.

Decisiones clave

Arquitectura hexagonal y DDD con 12 contextos delimitados

Cursos, progreso, evaluaciones, analíticas, IA e inquilinos cambian cada uno por motivos distintos. Modelarlos como contextos delimitados dentro de un monolito modular mantiene la lógica de dominio independiente de Next.js y Supabase detrás de puertos y adaptadores, de modo que cada contexto se puede probar y evolucionar por separado sin pagar el costo operativo de los microservicios.

Multi-inquilino garantizado con Row Level Security, no solo con código de aplicación

Con varias instituciones y roles compartiendo una base de datos, una sola cláusula WHERE olvidada filtraría datos entre inquilinos. Las políticas de Row Level Security hacen que el propio PostgreSQL rechace las filas fuera de la institución y el rol de quien consulta, y cada server action vuelve a obtener el rol desde la sesión en lugar de confiar en lo que envía el cliente. El esquema se dimensionó para 30 000 usuarios y picos de 8000 concurrentes y se validó con pruebas de carga en k6.

pgvector en la misma instancia de Postgres para el asistente RAG

Una base de datos vectorial dedicada habría sido otro servicio que aprovisionar, asegurar y pagar. Los embeddings siempre se consultan junto con datos relacionales como la matrícula y el inquilino, así que mantenerlos en Postgres permite al asistente combinar la búsqueda por similitud con la verificación de permisos en una sola consulta, bajo las mismas políticas RLS.

Analíticas sobre agregados y RPC de PostgreSQL

Los paneles de cada institución agregan datos de avance y progresión de muchos usuarios. Calcular esos agregados dentro de la base de datos y exponerlos mediante RPC evita enviar filas en bruto al servidor y mantiene las consultas pesadas cerca de los datos, bajo las mismas reglas de acceso que el resto de la plataforma.

Server Components para lecturas, estado en el cliente solo donde aporta

Renderizar las páginas con los datos ya obtenidos en el servidor evita cascadas de carga, así que los docentes ven la página completa de inmediato. El estado en el cliente se reserva para flujos interactivos como el envío de cuestionarios, las actualizaciones de progreso y el asistente en streaming.

Resultado

GRAMA está en producción desde junio de 2026 y atiende la capacitación docente de varias instituciones. Más allá de las funcionalidades, el proyecto me enseñó cuánta confiabilidad depende de decisiones tomadas al principio: límites de dominio claros, seguridad aplicada en la base de datos y pruebas de carga antes de que llegue el tráfico real.

Funcionalidades

Arquitectura

  • Monolito modular hexagonal / DDD con 12 contextos delimitados
  • Esquema multi-inquilino con acceso por roles y Row Level Security
  • Dimensionado para 30 000 usuarios y picos de 8000 concurrentes, con pruebas de carga en k6
  • Datos heredados migrados con cargadores idempotentes

Capa de IA

  • Asistente de aprendizaje RAG sobre Google Gemini con streaming y tool calling
  • Búsqueda semántica con pgvector, acotada por matrícula e inquilino
  • Integración MCP
  • Contenido de cursos autogenerado

Motor de aprendizaje

  • Jerarquía Curso → Módulo → Lección → Ítem con varios tipos de contenido
  • Avance secuencial: una lección se desbloquea al completar la anterior
  • Calificación automática ligada a las actualizaciones de progreso

Analíticas e infraestructura

  • Módulo de analíticas sobre agregados y RPC de PostgreSQL
  • Desplegado en Vercel con Supabase (PostgreSQL, Auth, Storage)
  • DNS y caché en el edge con Cloudflare

Trabajemos juntos