# 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
