105 lines
4.3 KiB
Markdown
105 lines
4.3 KiB
Markdown
# 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
|