Volver a proyectos

PROYECTO 02

Generador QR Basic-Fit

Migración a Next.js del mismo generador de códigos QR que desarrollé previamente en Flutter, con mejoras de rendimiento, lógica e interfaz

  • NEXT.JS
  • FIREBASE AUTH
  • FIRESTORE
  • DOCKER
  • TYPESCRIPT

Migración

Flutter → Next.js

El mismo proyecto reescrito en otro stack, no un clon desde cero.

Integración

API oficial

El código de amigo pasa de consultar la web a consumir el endpoint de Basic-Fit.

Continuidad

Firebase

Auth y almacenamiento reutilizados para no migrar datos ni cuentas.

(01)

Introducción

Este proyecto es la migración a Next.js del mismo generador de códigos QR que ya había desarrollado en Flutter. No partí de cero: la lógica de negocio, la integración con Basic-Fit y la infraestructura de usuarios ya existían. Lo que buscaba era consolidar todo en una única aplicación web más sólida, con mejor rendimiento y una experiencia más fiel a la app oficial.

El objetivo final es tener una app web funcional que permita acceder al gimnasio sin instalar ninguna aplicación, mantener un proyecto único en lugar de dos stacks distintos, y seguir aprendiendo con algo que uso de verdad — no un ejercicio de demostración vacío, sino una herramienta personal con utilidad real que refleja lo que soy capaz de construir.

(02)

Por qué migrar desde Flutter

La versión Flutter ya resolvía el acceso al gimnasio mediante QR dinámico y la visualización del código de amigo. Funcionaba, pero acumulaba limitaciones que justificaban una reescritura en Next.js:

  • Rendimiento — La app web compilada con Flutter no ofrecía la fluidez que buscaba en el navegador. Next.js mejoró tiempos de carga, respuesta de la interfaz y mantenimiento del código en producción.
  • Código de amigo — En Flutter el código se obtenía consultando la web de Basic-Fit, un enfoque frágil y dependiente del markup de terceros. En la migración reimplementé esa lógica para consumir directamente la API oficial, con datos más fiables y menos puntos de rotura.
  • Interfaz — La versión web de Flutter no replicaba fielmente el diseño de la aplicación oficial. Con Next.js reconstruí la UI para que coincida con la app de Basic-Fit: mismas pantallas, misma jerarquía visual y misma sensación de uso.
  • Continuidad de datos — Para no obligar a los usuarios a registrarse de nuevo ni migrar información, reutilicé Firebase Authentication y el almacenamiento en Cloud Firestore del proyecto anterior.

(03)

Propósito del proyecto

Más allá de la pila tecnológica, este proyecto responde a necesidades concretas:

  • Acceso sin app instalada — Entrar al gimnasio desde cualquier navegador con el QR dinámico, sin depender de la aplicación móvil de Basic-Fit.
  • Un solo proyecto — Centralizar frontend, lógica de servidor y despliegue en Next.js, en lugar de mantener en paralelo una app Flutter y una variante web.
  • Aprender con algo útil — No es un portfolio ficticio ni un proyecto de ejemplo: es una herramienta que uso, que evoluciona con mis necesidades y que me ha permitido profundizar en ingeniería inversa, integración con APIs y migración entre stacks sin perder continuidad.

(04)

Contexto de uso

Los socios de Basic-Fit necesitan un código QR para acceder al gimnasio. La app oficial muestra un QR que cambia cada pocos segundos como medida de seguridad, de modo que una captura de pantalla no sirve para entrar. Además, cada usuario dispone de un código de amigo para invitar a nuevos socios.

Tanto la versión Flutter como la actual en Next.js cubren esas dos funciones. La diferencia está en cómo lo hacen: rendimiento en navegador, origen del dato del código amigo e interfaz alineada con la app oficial.

(05)

Ingeniería inversa del QR dinámico

El reto técnico principal — ya abordado en Flutter y perfeccionado en Next.js — fue replicar el QR de acceso dinámico que genera la aplicación oficial de Basic-Fit. Para ello se realizó un proceso de ingeniería inversa sobre la app móvil:

  1. Análisis del tráfico de red — Interceptación y estudio de las peticiones que la app oficial realiza al mostrar el QR de acceso, identificando los endpoints, cabeceras y parámetros involucrados.
  2. Deserialización del protocolo — Comprensión del formato del payload que se codifica en el QR, incluyendo los campos temporales que determinan su caducidad.
  3. Replicación del algoritmo de rotación — Implementación en el backend de Next.js de la misma lógica de generación, consiguiendo que el código se renueve automáticamente cada 5 segundos, igual que en la app original.
  4. Validación cruzada — Comparación de los QR generados con los de la app oficial para confirmar que el torno del gimnasio los acepta correctamente.

Resultado

El QR dinámico generado por la aplicación web es funcionalmente equivalente al de la app oficial: se actualiza en tiempo real y permite el acceso al gimnasio sin necesidad de tener instalada la aplicación de Basic-Fit.

(06)

Código de amigo: de scraping web a API oficial

En la versión Flutter, el QR de invitación de amigo no se obtenía desde la API: se resolvía consultando la web de Basic-Fit, extrayendo el código del HTML o del flujo de la página. Funcionaba mientras la web no cambiaba, pero era frágil y difícil de mantener.

En la migración a Next.js reimplementé esa parte por completo. El backend consulta el endpoint oficial de Basic-Fit con las credenciales de sesión del usuario autenticado y devuelve el código vigente. Si Basic-Fit lo renueva, la aplicación lo refleja en la siguiente petición, sin depender del markup de una página externa.

(07)

Reutilización de Firebase (Flutter → Next.js)

Una decisión clave de la migración fue no reinventar la capa de usuarios ni migrar datos. El proyecto Flutter ya utilizaba Firebase Authentication para el login y Cloud Firestore como almacenamiento. Next.js se conecta a la misma infraestructura:

Firebase Auth

Los usuarios existentes pueden iniciar sesión con las mismas credenciales. No hubo migración de cuentas ni pérdida de sesiones activas en la transición de Flutter a la web.

Cloud Firestore

Los datos de perfil, tokens de sesión con Basic-Fit y configuración de usuario se leen y escriben en la misma colección que usaba la app Flutter, evitando duplicidad de esquemas.

Continuidad sin fricción

Quien ya usaba la versión Flutter abre la web, inicia sesión y ve sus QR al instante. La migración fue transparente a nivel de datos y cuentas.

(08)

Arquitectura

La aplicación Next.js concentra en un solo stack lo que antes vivía repartido en Flutter web y lógica auxiliar. Se estructura en tres capas:

  • Frontend (Next.js) — Interfaz alineada con la app oficial: login, QR dinámico con temporizador de renovación y pantalla del código de amigo.
  • API Routes / Server Actions — Generación del QR dinámico (lógica heredada de la versión Flutter) y consulta a la API de Basic-Fit para el código de amigo.
  • Firebase + Docker — Persistencia y autenticación heredadas de la versión Flutter; contenedor Docker para despliegue reproducible en cualquier entorno.

(09)

Interfaz de la aplicación

Uno de los motivos de la migración fue la interfaz. La versión web en Flutter no reproducía con exactitud el diseño de la app oficial de Basic-Fit. En Next.js reconstruí las pantallas para que coincidan: tipografía, disposición de elementos y sensación general de uso. El resultado es una web que se comporta y se ve como la aplicación de referencia, accesible desde cualquier navegador sin instalación.

QR de acceso que se regenera cada 5 segundos. La pantalla replica el diseño de la app oficial, algo que la versión Flutter web no conseguía.

(10)

Conclusiones

La migración de Flutter a Next.js no fue un cambio de stack por moda: respondió a problemas concretos de rendimiento, mantenimiento del código de amigo e interfaz. Al reutilizar Firebase, la transición fue transparente para quien ya usaba la versión anterior. El proyecto sigue cumpliendo su función real — acceder al gimnasio desde el navegador — mientras concentra el desarrollo en una sola codebase y demuestra capacidad técnica más allá de proyectos de demostración.

  • Migración del mismo proyecto Flutter, no un desarrollo paralelo desde cero.
  • Mejor rendimiento web y lógica del código de amigo reimplementada contra la API oficial.
  • Interfaz fiel a la app de Basic-Fit, a diferencia de la versión Flutter web.
  • Firebase Auth y Firestore reutilizados: sin migración de datos ni nuevas cuentas.
  • Herramienta personal funcional, no un ejercicio ficticio de portfolio.