Saltar al contenido
Historial técnico para una academia de BJJ← Todos los proyectos

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.

(01)Problema

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.

  1. No había forma de saber qué técnicas se vieron hoy, la semana pasada o en un turno concreto.
  2. Una misma técnica aparecía en varias clases sin que nada las relacionara.
  3. Cinturones, grados y medallas de los compañeros no estaban registrados en ningún sitio fiable.
(02)Solución

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.

  1. Registro de clases por turno, modalidad (Gi / No-Gi), tema, instructor, notas, video y técnicas elegidas de la biblioteca.
  2. Biblioteca de técnicas con búsqueda por categoría y posición, y en cada técnica las clases en las que apareció.
  3. Listado con filtros combinables, calendario y horario semanal de turnos.
  4. Sección Compañeros con cinturón, grado, antigüedad y medallero, alimentado por participaciones en torneos aprobadas por un admin.
(03)Arquitectura

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.

Frontend

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.

API

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.

Base de datos

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.

Fig. 01Defensa en profundidad
Capas que atraviesa una petición en MatLogUna petición atraviesa siete capas: la política de seguridad de contenido del navegador, el borde de la API con límite de tamaño y cabeceras, la autenticación con límite de intentos y tokens versionados, la autorización por rol, la validación con Pydantic y las restricciones de PostgreSQL. Cada una la puede rechazar con su propio código. Si pasa todas, el cambio queda auditado.Petición01Navegador · Cloudflare WorkersCSP estricta generada en el build y cabeceras de seguridad propias del sitio estático02Borde de la APICuerpo de hasta 64 KB · nosniff, frame DENY, no-store y CSP 'none' en cada respuesta03Autenticación5 fallos por usuario y 20 por IP cada 15 min · JWT con versión: subirla cierra toda sesión04AutorizaciónPermisos usuario / admin · cinturón, grado y medallas solo los confirma un admin05ValidaciónEsquemas de Pydantic: tipos, formatos y rangos antes de llegar a la lógica06Esquema · PostgreSQLCHECK de grado válido, UNIQUE por participación y claves foráneas07RastroAltas, cambios y borrados auditados con valor anterior y nuevo · eventos de seguridad sin secretosCSPscript inyectado bloqueado413petición demasiado grande429401fuerza bruta o token viejo403no le corresponde422datos fuera del esquemaCHECKviola una restricción200y el cambio queda auditado

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.

Recorrido de la peticiónRechazoLlega y se registra
(04)Stack y decisiones

El stack es deliberadamente sobrio: la complejidad está en los permisos, la auditoría y la seguridad operativa, no en la cantidad de herramientas.

Python 3.12FastAPISQLAlchemy 2AlembicPostgreSQLJWTpytestReact 19TypeScriptTanStack Query v5React RouterTailwind CSS v4ViteDockerRailwayCloudflare Workers
  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
(05)Resultados
Suite de tests
128API · pytest
01

Expone capacidad para llevar un producto de punta a punta: modelado, API, frontend, migraciones, despliegue continuo y documentación funcional.

02

Muestra criterio de seguridad aplicado a un proyecto pequeño, con defensa en profundidad desde la base de datos hasta las cabeceras del navegador.

03

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.

(06)Siguiente paso

¿Hablamos sobre una oportunidad similar?