El operador ?? solo hace fallback con null/undefined, no con cadena vacía.
Si Google devuelve user_metadata.full_name: "", la cadena de propagación es:
buildAuthUser → name="" → upsertUserOnLogin inserta "" → syncProfileFromDB
devuelve "" → AuthContext setUser → "" ?? prev.name = "" → ProfileSheet
setName("") → name.trim() === '' → botón disabled → click no hace nada.
Fix: cambiar ?? por || en todos los puntos donde full_name o name de DB
se propagan al estado: buildAuthUser, syncProfileFromDB, getUserFromStorage,
useEffect IIFE en AuthContext. Agregar fallback a email en ProfileSheet
setName() para usuarios cuya fila en DB ya tiene name="" de sesiones anteriores.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
upsertUserOnLogin + syncProfileFromDB (AuthContext useEffect) adquieren el
processLock de supabase-js al cargar la página. Si el servidor tarda, ese lock
queda ocupado y supabase.from('users').update() en handleSave espera para siempre
en la misma cola — congelando la UI indefinidamente.
Fix: reemplazar el cliente Supabase por fetch nativo en ProfileSheet. El token
se lee directamente de localStorage (donde GoTrueClient lo escribe tras cada
login/refresh), eliminando toda dependencia del processLock. Si el token no
está disponible o el servidor responde con error, se muestra el mensaje inline
en lugar de colgar el botón.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SupabaseAuthService: solo leer company/name de DB en INITIAL_SESSION y SIGNED_IN;
ignorar TOKEN_REFRESHED y USER_UPDATED para no sobreescribir ediciones locales
- ProfileSheet: useEffect con solo [open] como dep — inicializa el form al abrir
el sheet, sin resetearlo en cada cambio del objeto user durante la edición
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Feature A — Ver procesos asociados a un recurso:
- resource-repo.ts: getProcessCountsPerResource() (una query, N+1 evitado)
- resource-repo.ts: getProcessesForResource() (on-demand al expandir)
- ResourceCatalogPage: carga conteos en paralelo, columna "Procesos" con
badge naranja clicable, fila expandida con links a /workspace/:id
Feature B — Campo empresa en perfil:
- 013_add_company_to_users.sql: ALTER TABLE users ADD COLUMN IF NOT EXISTS company text
- AuthUser: agrega company? opcional
- SupabaseAuthService: lee company y name de tabla users en onAuthStateChange
- AuthContext: agrega updateUser() para reflejar cambios sin recargar
- ProfileSheet.tsx: Sheet con nombre/empresa editables, email read-only
- AppHeader: muestra empresa en dropdown + item "Editar perfil"
528 tests Vitest verdes. Build limpio.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>