# 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 1–3B 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) ```ts 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`: ```ts // 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 `user` → `user?.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