Files
inq-roi-simulador-web/sprints/sprint-5/ETAPA_4C_PROMPT.md
Marcos Benítez a626ff040c
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
fix de guardar perfil - ahora si
2026-06-20 01:31:02 -03:00

4.3 KiB
Raw Blame History

Sprint 5 — Etapa 4C: Fix definitivo — contención de processLock al guardar perfil

Contexto

InQ ROI — React 18 + Vite + TypeScript + TanStack Router + Zustand + shadcn/ui + Tailwind + Supabase.

Etapas 13B completadas con OK formal. Etapa 4 completada con una excepción: guardar perfil congela la app indefinidamente.

Etapa 4B intentó corregirlo con dos fixes (guard en onAuthStateChange, useEffect de ProfileSheet con [open]). Esos fixes fueron insuficientes — el freeze persiste.

Etapa 4D (diagnóstico) confirmó la causa raíz real. Esta etapa la resuelve.


Causa raíz confirmada

Archivo: src/features/library/LibraryPage.tsx (aprox. línea 757)

useEffect(() => {
  if (!user) return
  load()   // ← llama getSessionSafe() → intenta adquirir processLock
}, [load, user])  // ← "user" es el objeto completo, cambia de referencia en cada update

Secuencia del freeze:

  1. Usuario guarda perfil → ProfileSheet.tsx llama updateUser({ name, company })
  2. updateUser hace setUser(prev => ({ ...prev, name, company })) → nueva referencia del objeto user
  3. LibraryPage detecta el cambio en user → dispara load()
  4. load() llama getSessionSafe() → intenta adquirir processLock
  5. En paralelo, el supabase.from('users').update(...) de ProfileSheet ya tiene o está esperando processLock para el token refresh
  6. Contención → uno de los dos queda esperando indefinidamente → freeze

Evidencia del diagnóstico (commit dd361b1):

Los logs en producción muestran la secuencia hasta "local state updated" y luego silencio total — exactamente el momento en que setUser(...) dispara el useEffect de LibraryPage.


Fix — una línea

En src/features/library/LibraryPage.tsx, cambiar la dependencia del useEffect de user a user?.id:

// ANTES (fires en cada cambio de referencia del objeto user):
useEffect(() => {
  if (!user) return
  load()
}, [load, user])

// DESPUÉS (fires solo cuando cambia el ID — distinto usuario o logout/login):
useEffect(() => {
  if (!user) return
  load()
}, [load, user?.id])

Por qué funciona: user?.id es un primitivo estable (string). No cambia cuando updateUser crea un nuevo objeto con el mismo id pero distinto name o company. La biblioteca solo se recarga cuando hay un usuario genuinamente diferente — que es el único caso donde tiene sentido recargar.


Limpieza — remover logs de diagnóstico

El commit dd361b1 agregó console.log temporales en ProfileSheet.tsx para el diagnóstico. Removerlos todos antes del commit final.

Buscar y eliminar cualquier línea console.log con prefijo [ProfileSheet] en src/components/ProfileSheet.tsx.


Pasos de implementación

  1. Abrir src/features/library/LibraryPage.tsx
  2. Localizar el useEffect con dependencia [load, user] que llama load() (aprox. línea 757)
  3. Cambiar useruser?.id en el array de dependencias
  4. Abrir src/components/ProfileSheet.tsx
  5. Remover todos los console.log temporales del diagnóstico
  6. npm run build — 0 errores TypeScript
  7. npm run test — 528+ Vitest verdes
  8. git push origin main — obligatorio antes de validar en producción (Dokploy no autodeploy)
  9. Commit: fix(sprint-5/etapa-4c): library useEffect usa user.id no user ref — corta contención processLock al guardar perfil

Qué NO entra en esta etapa

  • Cambios en processLock, getSessionSafe(), ni en el sistema de auth
  • Cambios en ProfileSheet.tsx más allá de remover los console.log
  • Refactoring de LibraryPage más allá del fix de la dependencia
  • Ninguna feature nueva

Criterios de validación

  • Guardar nombre en el Sheet → app no se congela → nombre actualizado en el dropdown inmediatamente
  • Guardar empresa en el Sheet → app no se congela → empresa aparece en el dropdown
  • Cmd+R después de guardar → los valores persisten (están en Supabase)
  • Navegar a la biblioteca y volver → la lista de procesos sigue correcta
  • No hay console.log de diagnóstico en la consola del browser
  • npm run build limpio
  • npm run test — 528+ Vitest verdes
  • git push origin main ejecutado antes de validar en producción
  • Validación visual del director antes del OK formal