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

105 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
```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