Volver a Proyectos

🏆 Pint League

Reescritura completa de DrinkLegends sobre PHP sin framework: router, JWT y push implementados a mano

Reescritura de DrinkLegends Sin framework Web Push propio

Escala del Proyecto

9Controladores
40Rutas
8Vistas SPA
44Archivos
4.5kLíneas

Descripción General

Pint League es la segunda generación de DrinkLegends. El producto es el mismo — grupos, rondas con foto, muro con likes y comentarios, rankings, MVP, logros, chat, amigos y juegos — pero la implementación se rehízo por completo: fuera Laravel, todo en PHP sin framework.

Eso significó escribir a mano las piezas que un framework regala: el router con soporte de parámetros en la ruta, la autenticación JWT con firma y verificación, el servicio de notificaciones push y el procesado de fotos. Nueve controladores cubren las 40 rutas de la API.

El frontend también es vanilla: una SPA con router propio y ocho vistas, sin React ni build. Y existe migrate_from_drinklegends.php, un script que traslada los datos de la versión anterior, porque una reescritura que pierde los datos de los usuarios no es una reescritura, es un producto nuevo.

Tecnologías Utilizadas


PHP vanilla

MySQL

JWT propio

Router propio

Web Push

SPA vanilla

PWA

PhotoService

Los 9 Controladores de la API

AuthController

Registro, login, refresh de token, perfil, actualización de datos y cambio de contraseña.

GroupController

Creación y acceso a bares (grupos), edición, bebidas personalizadas y salida del grupo.

RoundController

Registro de rondas, muro del grupo, likes, comentarios y rondas propias del usuario.

RankingController

Clasificación del grupo, histórico de MVP y ranking global.

AchievementController

Catálogo de logros con el progreso del usuario.

ChatController

Mensajería del grupo: listado y envío.

FriendController

Búsqueda de usuarios, solicitudes, aceptación, rechazo y eliminación de amigos.

GameController

Verdad o Reto, ¿Quién es más probable?, Yo nunca he… y la ruleta del grupo.

PushController

Registro del dispositivo para recibir notificaciones push.

Arquitectura

Backend estructurado como un mini-framework propio: Router resuelve las rutas con parámetros dinámicos, Auth y Jwt gestionan la autenticación, Database encapsula PDO, y PushService y PhotoService aíslan las dos operaciones con efectos externos.

El frontend es una SPA sin build: router.js gestiona la navegación entre las ocho vistas de views/, api.js centraliza las llamadas y ui.js los componentes compartidos.

PintLeague/
├── index.php · .htaccess
├── backend/src/
│   ├── Router.php          # rutas con parámetros
│   ├── routes.php          # las 40 rutas
│   ├── Auth.php · Jwt.php    # autenticación
│   ├── Database.php        # capa PDO
│   ├── PushService.php     # notificaciones
│   ├── PhotoService.php    # procesado de imágenes
│   └── Controllers/         # los 9 controladores
├── backend/migrate/
│   └── migrate_from_drinklegends.php  # traspaso de datos
└── frontend/
    ├── index.html · sw.js · manifest.webmanifest
    ├── js/                  # app, api, router, ui, players
    └── js/views/            # 8 vistas de la SPA

Las 40 Rutas por Área

  • Autenticación — registro, login, refresh, perfil, edición y cambio de contraseña.
  • Bares — listar, crear, unirse por código, ver, editar, bebidas personalizadas y salir.
  • Rondas y muro — muro del grupo, registrar ronda, like, comentarios y rondas propias.
  • Rankings — clasificación del grupo, histórico de MVP y ranking global.
  • Logros — catálogo con progreso.
  • Chat — mensajes del grupo: leer y enviar.
  • Amigos — buscar, listar, solicitar, aceptar, rechazar y eliminar.
  • Juegos — Verdad o Reto, ¿Quién es más probable?, Yo nunca he… y ruleta.
  • Push — registro del dispositivo para notificaciones.

Seguridad Implementada

  • JWT propio: generación, firma y verificación implementadas en Jwt.php.
  • Endpoint de refresh para renovar el token sin volver a pedir credenciales.
  • Separación explícita entre rutas públicas (registro, login, refresh) y privadas.
  • Contraseñas hasheadas; el cambio de contraseña exige la actual.
  • Consultas mediante la capa Database con PDO y sentencias preparadas.
  • backend/public/uploads/ protegido con .htaccess e index.html.
  • Configuración separada en config.php y config.local.php.

Retos Técnicos y Decisiones de Diseño

¿Por qué reescribir algo que funcionaba?

DrinkLegends en Laravel funcionaba, pero arrastraba el peso del framework para un producto que en realidad hace cuatro cosas: autenticar, guardar rondas, calcular rankings y notificar. Sobre PHP plano la aplicación despliega en cualquier hosting compartido sin Composer, y el coste de mantenimiento deja de depender de las versiones de un framework ajeno.

Escribir el JWT a mano

Un JWT es tres bloques en base64url separados por puntos, con una firma HMAC del encabezado y el cuerpo. Implementarlo en Jwt.php obliga a resolver el base64url — que no es el base64 estándar —, la comparación de firmas en tiempo constante y la validación de la expiración. Es el tipo de código en el que un atajo se convierte en un agujero de seguridad.

Un router con parámetros en 100 líneas

Router.php soporta rutas como /api/groups/{groupId}/rounds: hay que convertir el patrón en una expresión regular, extraer los parámetros con nombre y despachar al par controlador-método. Es la pieza que hace que las 40 rutas de routes.php se lean como una tabla y no como un switch.

Migrar los datos, no solo el código

Una reescritura que obliga a los usuarios a empezar de cero pierde los puntos, los logros y el histórico, que es justamente el valor acumulado del producto. migrate_from_drinklegends.php traslada los datos de la versión Laravel al nuevo esquema; sin ese script la reescritura no habría sido viable.

Mi Rol

Desarrollador full stack — autor único.

Router, capa de autenticación con JWT, servicio de push, procesado de fotos, los nueve controladores, la SPA vanilla con su router y el script de migración desde DrinkLegends.

Estado del Proyecto

Aplicación funcional que sustituye a DrinkLegends. La API cubre las 40 rutas y la SPA sus ocho vistas. Incluye scripts de migración tanto desde DrinkLegends como para producción.

Código y Enlaces

Repositorio no publicado por contener configuración de despliegue. Puedo mostrar el código — en particular el router y la implementación del JWT — en una entrevista.