perf/cache-hub-dashboard #2

Merged
Kevin_Ramirez merged 4 commits from perf/cache-hub-dashboard into main 2026-07-21 21:33:43 +00:00

4 Commits

Author SHA1 Message Date
b9a0c55719 fix(observability): RequestLoggingMiddleware debe envolver a Tenant/License
Estaba registrado antes que Tenant/License, así que su cronómetro arrancaba
DESPUÉS de que ambos ya habían corrido — el Duration: en los logs nunca
incluyó el costo de verify-license/auth-me contra el Hub, dando la falsa
impresión de que todo respondía en 2-5ms. Reordenado para que sea el más
externo de los tres (CORS sigue siendo el más externo de todos).
2026-07-21 16:32:27 -05:00
beb2f7bdf0 fix(auth): corregir orden de middlewares — Tenant debe correr antes que License
Bug preexistente: LicenseValidationMiddleware se registraba después de
TenantMiddleware, pero add_middleware() de Starlette invierte el orden de
ejecución (el último registrado corre primero) — así que License corría ANTES
que Tenant en la práctica, contradiciendo el comentario en middleware.py que
asumía lo contrario ("TenantMiddleware corre antes... dejó tenant en
user_info").

Efecto real: request.state.user_info nunca existía cuando License intentaba
usarlo como fallback para tenant_override → el caché de licencia (agregado en
a1bbb6b1) nunca podía activarse para requests sin X-Tenant-Override
header/cookie explícito. Confirmado en vivo contra el Hub real
(workspace.aduanasoft.com): verify-license se repetía en cada request pese al
caché. Con el orden corregido, la segunda llamada dentro del TTL ya no golpea
al Hub.
2026-07-21 16:29:15 -05:00
695af2f0b1 perf(dashboard): cachear my-tenants/my-apps del Hub por sesión estable
my-tenants y my-apps no tienen caché propia en el Hub — se repetían en cada
+layout.server.ts load del dashboard, sin importar cuántas veces navegara el
usuario en la misma sesión.

- jwt.ts: getJwtSessionKey() extrae sid/sub del JWT — identificador estable que
  sobrevive al refresh del access token (rota cada ~60s).
- dashboard-shell-cache.ts: caché en memoria (Map + TTL de 30s) para el bundle
  de tenants/apps, keyed por session key — NUNCA por el access token, que
  rotando cada ~60s haría que cada set()/get() usaran llaves distintas y la
  caché nunca acertara.
- +layout.server.ts: usa el caché antes de golpear al Hub; lo llena tras el
  primer fetch exitoso de la sesión.
- dashboard-shell-cache.test.ts: cubre hit/miss, expiración por TTL, y que
  sobrevive a la rotación del access token (llave estable).

Verificado: 5/5 tests nuevos pasan; svelte-check da los mismos 38 errores/8
warnings preexistentes que main (0 nuevos); los 2 fallos de backend.test.ts son
preexistentes (ENOTFOUND backend fuera de Docker, igual en main).
2026-07-21 16:13:02 -05:00
a1bbb6b1b2 perf(auth): extender TTL de token_cache y cachear licencia válida por tenant
Cada navegación al dashboard disparaba verify-license y auth/me contra el Hub sin
ningún caché, sumando 1-6s por llamada del lado del Hub a cada request.

- security.py: token_cache TTL 60s→300s (el access token vive más que el TTL
  anterior; cachear su verificación es seguro).
- middleware.py: nuevo _license_ok_cache (TTLCache, 300s) en
  LicenseValidationMiddleware — SOLO cachea el camino "licencia válida" por
  tenant_override; inválida/expirada/error nunca se cachea y siempre revalida
  contra el Hub (fail-closed: el peor caso es que un tenant recién revocado siga
  pasando hasta 5 min más, nunca al revés).
2026-07-21 16:13:02 -05:00