Skip to content

fix(web): el login entraba en bucle infinito — nadie podía acceder al portal - #23

Open
beyondnetPeru wants to merge 3 commits into
mainfrom
fix/bucle-login-home-route
Open

fix(web): el login entraba en bucle infinito — nadie podía acceder al portal#23
beyondnetPeru wants to merge 3 commits into
mainfrom
fix/bucle-login-home-route

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Encontrado al ir a escribir las 14 historias sin cobertura e2e. La suite entera estaba bloqueada porque no se podía iniciar sesión.

El bug

Autenticarse con el grafo sembrado dejaba el navegador girando hasta que React cortaba con Maximum update depth exceeded. El API devolvía 200 — el bucle era del cliente:

  1. Login correcto → destinoTrasEntrar() devuelve settings.ui.home_route
  2. El grafo sembrado publica home_route = "/"
  3. navigate("/")App.tsx tenía <Route path="/" element={<Navigate to="/login" replace />} />
  4. /login con sesión abierta → su efecto vuelve a navegar a /vuelta al punto 3

La raíz no era un destino, era un desvío fijo a identificarse.

El arreglo

La raíz decide por sesión: con ella va a la ruta de inicio real, sin ella a /login. Y se descarta un home_route que apunte a / o /login — serían el mismo bucle, publicado desde el servidor.

La decisión se toma en dos sitios (login y raíz) y tenerla duplicada era parte del problema, así que sale a resolverDestinoTrasEntrar con 6 pruebas unitarias, incluida la configuración exacta que rompía el acceso.

Por qué nadie lo vio

Todas las puertas estaban verdes: lint, typecheck, 1626 pruebas unitarias, build. Ninguna abre un navegador. Y e2e no corre en CI.

El informe de cobertura que añadí ayer con TD-012 tampoco lo habría visto: cuenta ficheros, no ejecuta nada.

Lo que se añade para que no se repita

Regresión unitaria resolverDestinoTrasEntrar — 6 casos, corre en la CI de hoy sin infraestructura nueva
Humo e2e en CI En el job de .NET, el único con SDK. Levanta la API en InMemory y corre login, auth, navigation

El humo es deliberadamente parcial: la suite completa tarda ~4 min y arrastra inestabilidad. Lo que no puede fallar nunca es que se pueda entrar.

Verificación

Antes Después
role-state 0/4 suite completa 58 pasan / 3 inestables / 0 fallos
sonda: bucle infinito sonda: aterriza en /tenants, sin errores de consola

vitest 1632/1632 (6 nuevas) · typecheck 0 · build OK · eslint 0

Pendiente

Las 14 historias sin cobertura e2e siguen pendientes — este PR desbloquea poder escribirlas. Escribirlas sobre una app en la que no se podía iniciar sesión habría sido producir pruebas sin poder ejecutarlas.

🤖 Generated with Claude Code

beyondnetPeru and others added 3 commits August 10, 2026 16:59
… portal

Autenticarse con el grafo sembrado dejaba el navegador girando hasta que React cortaba
con «Maximum update depth exceeded». El API devolvía 200; el bucle era del cliente.

La cadena:

  1. Login correcto → `destinoTrasEntrar()` devuelve `settings.ui.home_route`
  2. El grafo sembrado publica `home_route = "/"`
  3. `navigate("/")` → App.tsx tenía `<Route path="/" element={<Navigate to="/login" />} />`
  4. `/login` con sesión abierta → su efecto vuelve a navegar a `/` → vuelta al punto 3

La raíz no era un destino, era un desvío fijo a identificarse. Ahora decide por sesión:
con ella va a la ruta de inicio real, sin ella a `/login`. Se descarta además un
`home_route` que apunte a `/` o a `/login` —serían el mismo bucle, publicado desde el
servidor— tanto en la raíz como en el propio login.

Esto bloqueaba la suite e2e ENTERA, no solo el login: todo caso que empieza
autenticándose moría ahí. `role-state` iba 0/4 y ahora la suite completa pasa.

Por qué nadie lo vio: e2e no corre en CI. El informe de cobertura que se añadió con
TD-012 cuenta ficheros; no ejecuta nada. Un fallo total del acceso al producto no tenía
ninguna puerta que lo detuviera.

Verificado: sonda de login aterriza en /tenants sin errores de consola (antes: bucle);
e2e 58 pasan / 3 inestables / 0 fallos (antes: role-state 0/4); typecheck 0; eslint 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pasos 2 del plan: que la próxima rotura del acceso no vuelva a ser invisible.

## La lógica del destino sale a un módulo propio, y se prueba

`resolverDestinoTrasEntrar` vive aparte porque la decisión se toma en DOS sitios —la
pantalla de login tras autenticar, y la ruta raíz cuando alguien con sesión llega a `/`—
y tenerla duplicada ERA el problema: la raíz redirigía fijo a `/login` mientras el grafo
publicaba `home_route = "/"`, así que cada uno mandaba al otro sin fin.

Seis pruebas unitarias la cubren, incluida la configuración exacta que rompía el acceso
(`home_route = "/"`). Corren en la CI que ya existe hoy, sin infraestructura nueva.

## Humo e2e en el job de .NET

Va ahí porque es el único con el SDK: e2e necesita la API arriba. Levanta la API en
InMemory —sin base externa— y corre login, auth y navigation.

Es HUMO deliberadamente, no la suite entera: esta tarda ~4 min y arrastra inestabilidad.
Lo que no puede fallar nunca es que se pueda entrar.

## Por qué hacía falta

El bucle de login dejó el portal inaccesible y TODAS las puertas estaban verdes: lint,
typecheck, 1626 pruebas unitarias y build. Ninguna abre un navegador. Se descubrió por
casualidad, yendo a escribir otras pruebas. El informe de cobertura de TD-012 tampoco lo
habría visto: cuenta ficheros, no ejecuta nada.

Verificado: vitest 1632/1632 (6 nuevas), e2e login+auth 15/15, sonda aterriza en
/tenants, typecheck 0, build OK, eslint 0, YAML del workflow válido.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
El paso se llamaba «InMemory, sin base externa» y no lo era: solo fijaba
ASPNETCORE_ENVIRONMENT=Development, que apunta a PostgreSQL en localhost:5432. Sin base
en el runner, la API moría al migrar («Connection refused») y el job caía.

Se añade un servicio postgres:16 al job, con la base, usuario y contraseña que declara
ConnectionStrings:DefaultConnection de appsettings.Development, y se corrige el nombre
del paso para que diga lo que hace.

Se prefiere la base real a forzar InMemory por variables de entorno: el humo comprueba
que se puede ENTRAR al producto, y hacerlo contra la persistencia de verdad es
justamente lo que le da valor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant