La app Flutter del servicio con el que 7M de cubanos se conectan

La telecom nacional de Cuba necesitaba una sola superficie móvil para todo lo que toca un abonado — cuenta, saldo de internet, autenticación al portal cautivo. Construí la app Flutter de punta a punta contra los portales Java heredados tal como estaban, sin ninguna reescritura de backend en la que apoyarme.

Cliente
Etecsa (telecom nacional de Cuba)
Rol
Único Ingeniero Móvil · Evaluación de backend
Año
2024
Período
Build móvil multi-trimestre + una evaluación de backend acotada
Flutter Dart Java Spring Boot Jakarta EE PostgreSQL Docker

Problema

La mayoría del acceso a internet en Cuba pasa por el servicio Nauta de Etecsa: te autenticas contra un portal cautivo para conectarte, y gestionas tu cuenta, plan y saldo en otro sitio completamente distinto. Durante años eso significó flujos de navegador de escritorio que no compartían estado — malabarear pestañas, copiar y pegar credenciales, y forzar la vista sobre una página del portal para deducir cuánto tiempo de conexión te quedaba.

Los dos sistemas detrás de esos flujos no se parecen en nada. Uno es una API JSON moderna. El otro es un portal heredado de servlets Java que responde en HTML y que solo fue diseñado para que hablara con él un navegador. La app tenía que aterrizar sobre ambos tal como estaban, sin ningún cambio de backend en el que apoyarse.

La superficie móvil

Construí la app móvil Nauta de punta a punta en Flutter, como único desarrollador móvil. Se entrega como dos apps dentro de un mismo binario, elegidas en un splash de entrada, porque son productos genuinamente distintos hablando con sistemas genuinamente distintos:

El lado Portal es deliberadamente un espejo del portal web público de Etecsa en nauta.cu — misma API, mismas operaciones, mismo modelo de cuenta, reconstruido como producto móvil nativo. Yo no construí ese portal web; lo llevaba un compañero de equipo y trabajábamos el mismo contrato de backend desde extremos opuestos. Mi trabajo era la paridad: todo lo que un abonado podía hacer en un navegador tenía que funcionar en un teléfono, sin el navegador.

Decisiones que vale la pena mencionar:

Loading diagram…
Dos apps en un binario. El lado Portal habla JSON; el lado Navegación reimplementa una sesión de navegador contra un portal heredado de servlets — con la cuenta atrás corriendo fuera de la UI por completo.

Por debajo, cada feature se divide en domain / data / presentation con sus propios casos de uso y repositorios, Riverpod para estado, y fallos tipados vía Either en vez de excepciones lanzadas entre capas. Compila para Android, Windows y Linux desde la misma base de código.

Una nota sobre el backend

Los módulos operativos internos de Etecsa corren sobre un stack heredado de Javax. Aparte de la app, me asignaron uno de esos módulos para responder una pregunta acotada: ¿Spring Boot sería realmente mejor? Porté ese único módulo y llevé ambas implementaciones cara a cara con SoapUI bajo carga comparable — el port a Spring Boot salió unas 3× más rápido, y documenté los números como evidencia para la decisión de plataforma. Mi alcance terminó ahí. Es una medición que me pertenece, no una migración que haya entregado.

Resultado

La app colapsó dos flujos de navegador en un solo producto: conectarte, ver exactamente cuánto tiempo te queda, y gestionar la cuenta sin abrir un navegador nunca. Se entregó contra ambos backends tal como estaban — y esa es la restricción que moldeó cada decisión. Cuando no puedes cambiar el sistema de abajo, la ingeniería consiste en absorber su forma para que el usuario no tenga que hacerlo.

Tecnologías usadas

Flutter Dart Java Spring Boot Jakarta EE PostgreSQL Docker
Visual

Pantallas

Seguir explorando

Más proyectos

Linkeum Wallet: una billetera fintech multimoneda en 30 días
Fintech · 30 días · 2 ingenieros

Linkeum Wallet: una billetera fintech multimoneda en 30 días

Lancé una billetera fintech en producción en 30 días con un equipo de 2 ingenieros — multimoneda, KYC, 2FA, notificaciones en tiempo real. Construida sobre Nest.js + Next.js Server Actions en un monorepo Turborepo.

Nest.js Next.js Turborepo PostgreSQL
Leer el caso de estudio
Un marketplace de combustible y gas para Cuba, con retiro por QR
Combustible y Gas · Web + Android · Integración externa

Un marketplace de combustible y gas para Cuba, con retiro por QR

Muévete y Cocina convierte la búsqueda diaria de combustible y gas en Cuba en un flujo de pedido anticipado: ver servicentros cercanos y precios en vivo, reservar litros o un cilindro de gas, pagar y retirar contra un QR. Tras el paso a white label que hizo el equipo, el mismo código llega hoy al cliente bajo dos marcas que ya venden, Mercaful y Gasolero. Propuse y construí de punta a punta su app Flutter de repartidores offline-first, contribuí de forma sustancial a la app web de cliente junto al líder de frontend y a un diseñador de la empresa, y con el tiempo lo llevé también al backend: evidencia de entrega, control de acceso y documentos legales por marca.

Flutter React Router Vite TypeScript
Leer el caso de estudio
AI News Intelligence — agente n8n sobre FastAPI + Redis + SvelteKit
Proyecto personal · n8n · Agente · RAG

AI News Intelligence — agente n8n sobre FastAPI + Redis + SvelteKit

Proyecto personal: un agente de IA que orquesta datos de noticias vía n8n, los sirve a través de una capa de caché FastAPI + Redis y conversa con el usuario por una UI de chat SvelteKit. Stack completo en contenedores con Docker Compose para despliegue en un comando.

FastAPI Python Redis Docker
Leer el caso de estudio