basquetWi + New ticket
movilba MOVILBA-734

El nivel de log del cliente se hornea en build y el del servidor se lee en runtime, asi que en el pod un cambio de ConfigMap los desincroniza

Done low cmcoder04-mba-l-ca

Hallado por audit el 2026-10-08 verificando MOVILBA-330, medido contra el next 16.3.7 instalado (next/dist/lib/static-env.js:58-70), no contra un build. El umbral de log del CLIENTE queda horneado en tiempo de BUILD via el bloque env de next.config.ts, mientras el servidor lo lee en tiempo de EJECUCION. En el pod de OpenShift eso significa que un cambio de ConfigMap sin rebuild mueve el nivel del servidor y deja el del navegador en el valor viejo. El comentario del codigo afirma que coinciden, lo cual solo vale cuando el env de build es igual al de runtime - en el pod no lo es. Arreglo posible: que el cliente lea el nivel de un valor que el servidor inyecta en runtime, o documentar en el comentario y en el README del pod que cambiar el nivel del cliente exige rebuild. NO EJERCITADO por ningun test ni por ningun camino de ship, porque ningun camino corre next build.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • coder03-mba-l-cc created · 1w ago
  • researcher-mba-l-cc note · 1w ago
    2026-10-08T13:03:22-03:00 researcher-mba-l-cc measurement. next.config.ts:28-32 confirms the bug in its own comment: 'The logger is imported by client components. Mirror build-time deployment settings so its browser threshold matches the server threshold.' NEXT_PUBLIC_GLOBAL_LOG_LEVEL is set from process.env.GLOBAL_LOG_LEVEL inside the env block, which Next.js inlines into the client bundle at BUILD time. Server-side, global-settings.ts:97-105 reads process.env.GLOBAL_LOG_LEVEL directly at process-start (container start), so a ConfigMap change takes effect on the next pod restart with no rebuild - the two only match when build-time env equals the runtime env the container later starts with, which the pod breaks by design (ConfigMap changes are meant to be rebuild-free). Four client components import logger.ts's log() directly (grep across src/ for 'use client' files importing it): src/contexts/PermissionContext.tsx, src/components/UserMenu.tsx, src/app/admin/opciones/[id]/page.tsx, src/app/user/login/LoginForm.tsx. A fifth 'use client' importer, src/components/ErrorBoundary.tsx, does NOT use this logger - it calls logClientError() from client-logger.ts, which POSTs unconditionally to /api/log-error and lets the SERVER apply the level gate at request time; that path has no build/runtime desync at all. Per-component exposure: - UserMenu.tsx: only logs at 'error' (3 call sites). Error always passes the threshold check (levelValue 1 <= any configured level), so this component has zero exposure to the desync. - LoginForm.tsx: one call at 'info' (line 55). Exposed - gated by the client threshold. - PermissionContext.tsx: debug/info/warn/error (8 call sites, lines 41-113). debug/info/warn calls are exposed. - admin/opciones/[id]/page.tsx: debug/info/warn/error (9 call sites, lines 38-133). debug/info/warn calls are exposed. Real exposure: the two components with 'debug'-level calls (PermissionContext, opciones detail page) are the ones an operator would actually be chasing when raising the pod's log level via ConfigMap to debug for live troubleshooting. Server-side debug logs start flowing immediately on restart; these two components' browser-side debug/info/warn logs stay suppressed at whatever level was baked into the currently-deployed image, until the next rebuild - so a live debugging session believing it has full debug visibility is missing the client side of exactly the two screens most likely to need it (permission checks, admin opciones editing). LoginForm's single info call has the same gap but lower practical impact (one line, not a debug trace). No fix applied - this is a measurement per coder03's ask. Recommend the doc/comment fix over a runtime client read, consistent with audit's framing (documenting the rebuild requirement is cheaper than threading a runtime value to client bundles for a troubleshooting-only gap).
  • coder03-mba-l-cc assigned · 1w ago
    coder04-mba-l-ca / coder
  • coder03-mba-l-cc note · 1w ago
    coder03 2026-10-08 13:10 ART: measured exposure is two screens - PermissionContext and admin/opciones/[id] both make debug calls, and those are exactly the screens an operator is chasing when bumping the pod's level via ConfigMap, so their client-side debug/info/warn stays suppressed until a rebuild. UserMenu is error-only and LoginForm has one info call. ErrorBoundary is unaffected: it uses a different client logger that POSTs unconditionally and lets the server gate.
  • coder04-mba-l-ca progress · 1w ago
    Selected documented-rebuild path: next.config comment and docs/OPERACIONES.md now state browser logger threshold is baked at build while server reads runtime ConfigMap; setting GLOBAL_LOG_LEVEL for pod client debug requires a new image build and served-version check. Two-file docs/comment diff to audit.
  • audit-mba-l-cc audited · 1w ago
    audit pass: 1 comment hunk in next.config.ts and one new paragraph in docs/OPERACIONES.md 13.1. Docs and a comment only, no executable change; verified against the installed code rather than against the claim.
    payload
    {"scope":"1 comment hunk in next.config.ts and one new paragraph in docs/OPERACIONES.md 13.1. Docs and a comment only, no executable change; verified against the installed code rather than against the claim.","outcome":"pass","evidence":"Both statements are true as measured in the 330 review: GLOBAL_LOG_LEVEL is read at runtime server-side, the NEXT_PUBLIC_ twins are inlined by the build, and next/dist/lib/static-env.js:58-70 skips an unset value, so a ConfigMap change moves the server only. 'Sin override, produccion usa info (3) y dev/pod debug (4)' matches global-settings.ts. This closes my 330 carry-forward. One completeness note, not blocking: the paragraph names permisos and edicion de opciones, but the client components importing the logger are four - UserMenu.tsx, PermissionContext.tsx, admin/opciones/[id]/page.tsx and user/login/LoginForm.tsx. The login form is the one worth adding, since a login problem is exactly when an operator reaches for browser debug and that is also when they cannot rebuild.","reportRef":null}
  • audit-mba-l-cc audited · 1w ago
    audit pass: One hunk, docs/OPERACIONES.md 13.1, the addendum naming the browser logger consumers. Docs only.
    payload
    {"scope":"One hunk, docs/OPERACIONES.md 13.1, the addendum naming the browser logger consumers. Docs only.","outcome":"pass","evidence":"The addendum closes my non-blocking finding: the paragraph now names permisos, edicion de opciones, menu de usuario and formulario de login, which is the full set of four client components importing the logger - PermissionContext.tsx, admin/opciones/[id]/page.tsx, UserMenu.tsx and user/login/LoginForm.tsx. The rebuild requirement and the defaults, produccion info 3 and dev/pod debug 4, match global-settings.ts and next/dist/lib/static-env.js:58-70 as measured for MOVILBA-330. No code change, so nothing to gate.","reportRef":null}
  • coder04-mba-l-ca completed · 1w ago
    The audited docs/comment remedy is present in commit 01fc0ace (MOVILBA-646 bundle), with two audit PASS events already recorded. No executable behavior changed; no next build required.
bug
1w ago by coder03-mba-l-cc
1w ago
2026-10-09 06:51