Changelog

Qué ha cambiado en cada versión. El formato sigue Keep a Changelog y el versionado es SemVer.

Todos los cambios relevantes de QuizArena. El formato sigue Keep a Changelog y el versionado es SemVer — ver docs/releases.md para el procedimiento de publicación.

[No publicado]

Cambiado

  • Migración completa de contenedores y despliegue a Podman: comandos podman:*, Containerfile.*, Podman Compose, CI/CD, escaneo de imágenes, publicación en GHCR y clúster Kind con proveedor Podman, sin fallback a Docker.

[1.0.0] — pendiente de publicar

Primera versión estable. Reúne el trabajo de las 14 fases del proyecto: de un monorepo vacío a una plataforma de quizzes en tiempo real con motor de partida autoritativo, escalado horizontal y despliegue reproducible.

Añadido

Partidas en tiempo real

  • Game Engine autoritativo en el servidor: countdown sincronizado, temporizador por pregunta, validación de respuestas, puntuación por velocidad y racha, leaderboard en vivo y podio final. El cliente nunca calcula un resultado.
  • Socket.IO en el namespace /games para lobby y partida: presencia conectado/desconectado, bloqueo de lobby, expulsión de jugadores y reconexión con recuperación de estado.
  • Redis como adaptador de Socket.IO, con locks, presencia y caché — permite varias instancias de API sirviendo la misma partida.
  • Recuperación de partidas activas si el backend se reinicia a mitad de juego.

Host y contenido

  • Autenticación de host: registro con verificación por correo, login, recuperación de contraseña y ajustes de perfil. JWT de acceso + refresh token rotativo en cookie httpOnly.
  • Quiz Builder con autoguardado, reordenamiento por drag-and-drop (accesible con teclado) y publicación.
  • Unión de jugadores invitados por PIN de 6 dígitos y QR, sin cuenta ni app.

Analytics e historial

  • Capa agregada reconstruible (GameAnalytics / GameQuestionAnalytics) con contadores, nunca porcentajes: las tasas se calculan al leer.
  • Historial de partidas, analítica por quiz y por pregunta, y exportación a CSV con protección contra CSV injection.
  • pnpm analytics:backfill para recalcular la agregación sin perder datos.

Infraestructura

  • Imágenes Docker multi-etapa para web, API y migrador; ejecutan como usuario sin privilegios y sin npm en la imagen final.
  • Podman Compose para desarrollo (hot reload) y para validar producción en local, con smoke test end-to-end.
  • Despliegue en Kubernetes local (Kind) con Helm, Gateway API/Envoy Gateway, HPA, PDB, NetworkPolicies y afinidad de sesión por cookie para Socket.IO.
  • CI/CD en GitHub Actions: calidad, pruebas unitarias, integración con PostgreSQL y Redis reales, E2E con Playwright, build y escaneo de imágenes con Trivy, análisis estático con CodeQL, y publicación en GHCR.

Documentación

  • docs/ con arquitectura, API, base de datos, WebSockets, Redis, analytics, Docker, Kubernetes, CI/CD, escalado, recuperación ante fallos y UI/UX.
  • Caso de estudio (docs/portfolio-case-study.md) y material de portfolio (docs/portfolio-summary.md).
  • SECURITY.md, CONTRIBUTING.md, LICENSE (MIT) y este changelog.

Demo

  • pnpm demo:seed / pnpm demo:reset: datos de demostración idempotentes con tres quizzes, tres partidas terminadas, jugadores y respuestas, suficientes para que historial y analytics muestren información real.

Corregido

Correcciones del cierre (fase 14), todas sobre fallos que existían antes de esta versión:

  • Los E2E no podían registrar un host desde que el registro exige verificación por correo: el helper nunca se actualizó y el código va hasheado en base de datos. Ahora siembra un código conocido y completa la pantalla real de verificación.
  • scripts/ci-e2e.sh reutilizaba un stack ya levantado sin comprobar que la API estuviera en modo test, lo que hacía fallar todos los specs que registran un host con un 500 desconcertante.
  • El smoke test de Docker no podía completar el registro: Resend rechaza los destinatarios en dominios reservados como example.com. Se añadió el transporte MAIL_TRANSPORT=console, que no sale a internet y —a diferencia del doble de tests— nunca imprime códigos en el log.
  • El botón de mostrar contraseña no era accesible por teclado (tabIndex={-1}), incumpliendo WCAG 2.1.1.
  • Varios trabajos de CI no construían @quizarena/shared-types antes de ejecutar las pruebas, y otros no definían DATABASE_URL, necesaria desde que prisma.config.ts la exige para prisma generate.
  • El escaneo de imágenes de Trivy nunca llegó a ejecutarse por un tag mal fijado; al arreglarlo aparecieron CVEs reales de node-tar que llegaban dentro de npm, ahora eliminado de las imágenes finales.

Limitaciones conocidas

  • No hay despliegue público: el proyecto corre en local (Podman Compose o Kind).
  • La imagen base de Debian arrastra CVEs de sistema (perl-base, zlib1g) sin parche disponible en la rama estable. Ver SECURITY.md.
  • Code scanning de GitHub no está disponible en el plan de la cuenta, así que CodeQL y Trivy publican sus resultados como artefacto y en el log del job en lugar de en la pestaña _Security_.