fix(web): el login entraba en bucle infinito — nadie podía acceder al portal - #23
Open
beyondnetPeru wants to merge 3 commits into
Open
fix(web): el login entraba en bucle infinito — nadie podía acceder al portal#23beyondnetPeru wants to merge 3 commits into
beyondnetPeru wants to merge 3 commits into
Conversation
… 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:destinoTrasEntrar()devuelvesettings.ui.home_routehome_route = "/"navigate("/")→App.tsxtenía<Route path="/" element={<Navigate to="/login" replace />} />/logincon sesión abierta → su efecto vuelve a navegar a/→ vuelta al punto 3La 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 unhome_routeque 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
resolverDestinoTrasEntrarcon 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
resolverDestinoTrasEntrar— 6 casos, corre en la CI de hoy sin infraestructura nuevalogin,auth,navigationEl 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
role-state0/4/tenants, sin errores de consolavitest1632/1632 (6 nuevas) ·typecheck0 ·buildOK ·eslint0Pendiente
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