MatLog
En la academia de Brazilian Jiu-Jitsu lo que se enseñaba en cada clase se perdía al terminar el entrenamiento: nadie sabía qué técnicas se vieron, en qué turno ni cuándo. Construí una plataforma que gestionan los propios alumnos para registrar clases y técnicas, consultarlas después y llevar los torneos y medallas de cada compañero.
Plataforma web mobile-first que funciona como historial técnico de las clases de una academia de BJJ: biblioteca de técnicas reutilizables, registro de clases por turno y modalidad, filtros combinables, calendario, perfiles de compañeros con cinturón y grado, y participaciones en torneos con un flujo de aprobación por administradores.
Que lo enseñado en cada clase no se perdiera al terminar el entrenamiento.
La academia no tenía registro de lo que se enseñaba: el conocimiento técnico dependía de la memoria de cada alumno, y la información sobre compañeros y torneos estaba dispersa.
- No había forma de saber qué técnicas se vieron hoy, la semana pasada o en un turno concreto.
- Una misma técnica aparecía en varias clases sin que nada las relacionara.
- Cinturones, grados y medallas de los compañeros no estaban registrados en ningún sitio fiable.
Un historial técnico que gestionan los propios alumnos y que se carga en menos de dos minutos.
La solución prioriza registrar rápido después de entrenar y consultar con filtros, con permisos que reparten el trabajo entre todos sin perder control sobre lo sensible.
- Registro de clases por turno, modalidad (Gi / No-Gi), tema, instructor, notas, video y técnicas elegidas de la biblioteca.
- Biblioteca de técnicas con búsqueda por categoría y posición, y en cada técnica las clases en las que apareció.
- Listado con filtros combinables, calendario y horario semanal de turnos.
- Sección Compañeros con cinturón, grado, antigüedad y medallero, alimentado por participaciones en torneos aprobadas por un admin.
Dos repos independientes: API y SPA, desplegadas por separado.
Separar backend y frontend permitió desplegar cada uno en el servicio que mejor le sienta y mantener un contrato claro entre ambos, documentado con OpenAPI.
SPA en React 19 y TypeScript con TanStack Query, mobile-first y en modo oscuro con la paleta de la academia. Se sirve como sitio estático en Cloudflare Workers, con CSP y cabeceras de seguridad.
FastAPI con routers por dominio (auth, usuarios, turnos, técnicas, clases, compañeros, torneos, participaciones y auditoría), validación con Pydantic, permisos usuario / admin y límites contra abuso. Desplegada en Railway con Docker y migraciones en el pre-deploy.
PostgreSQL con SQLAlchemy 2 y migraciones con Alembic. Restricciones en el propio esquema (unicidad de participaciones, grados válidos, torneos que no se borran si tienen participaciones) y roles separados para la aplicación y las migraciones.
Cada capa asume que la anterior puede fallar. Para escribir algo, una petición tiene que atravesarlas todas, y cualquiera la puede frenar con su propio código de error. Lo que llega al final queda registrado. Es un proyecto chico, pero guarda datos personales: la seguridad no se dejó para después.
El stack es deliberadamente sobrio: la complejidad está en los permisos, la auditoría y la seguridad operativa, no en la cantidad de herramientas.
- Las reglas que no pueden romperse viven en el propio esquema de PostgreSQL y no solo en la API: CHECK de grados válidos, unicidad de las participaciones en torneos y claves foráneas, para que un error en el código no deje datos inconsistentes.
- Cada alta, cambio o borrado queda auditado con quién, cuándo y el valor anterior y nuevo (la API solo agrega registros y los muestra en modo lectura a los admins), junto a un log de eventos de seguridad (logins fallidos, bloqueos, accesos denegados) que nunca incluye contraseñas ni tokens.
- Los datos que otros ven (cinturón, grado y medallas) no los edita el propio alumno: el cinturón lo asigna un admin y las participaciones en torneos quedan pendientes hasta que un admin las aprueba o rechaza con un motivo.
- El MVP se acotó a propósito a una sola pregunta, «¿qué vimos en las clases y en qué turno?», y se dejaron fuera asistencia, estadísticas y multi-academia hasta comprobar que se usaba de verdad.
- Sesión con JWT de corta duración, renovación mientras se usa y versión de token por usuario para invalidar todas sus sesiones; límite de intentos contra fuerza bruta, límite de tamaño de las peticiones y una CSP estricta generada en el build.
Expone capacidad para llevar un producto de punta a punta: modelado, API, frontend, migraciones, despliegue continuo y documentación funcional.
Muestra criterio de seguridad aplicado a un proyecto pequeño, con defensa en profundidad desde la base de datos hasta las cabeceras del navegador.
Refuerza la disciplina de alcance: un MVP que responde una pregunta concreta y crece según el uso real, respaldado por 128 tests de la API.
