Files
inq-roi-simulador-web/src/features/report/useReportData.ts
Marcos Benítez 3ebfd65a90 fix(sprint-5/etapa-4e): lockAcquireTimeout 30s + eliminar getSessionSafe — corta freeze en guardar perfil
getSessionSafe() tenía un problema de diseño: Promise.race([getSession(), timeout])
abandona la Promise de getSession() cuando gana el timeout. La Promise abandonada
deja una operación en PROCESS_LOCKS[name] que bloquea el chain. Con lockAcquireTimeout=5s
(default), un token refresh lento dispara ProcessLockAcquireTimeoutError cuyo handler
hace await previousOperation (colgada) → freeze permanente.

Fix: lockAcquireTimeout: 30000 (margen para redes lentas) + eliminar getSessionSafe()
de supabase.ts, library-store, process-store y useReportData. Las queries Supabase
llaman getSession() internamente vía _getAccessToken() que espera initializePromise
automáticamente — la barrera era redundante.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 19:05:23 -03:00

58 lines
2.1 KiB
TypeScript

import { useEffect, useState } from 'react'
import { supabaseActivityRepo } from '@/persistence/supabase/activity-repo'
import { supabaseResourceRepo } from '@/persistence/supabase/resource-repo'
import { supabaseProcessRepo } from '@/persistence/supabase/process-repo'
import { supabaseSimulationRepo } from '@/persistence/supabase/simulation-repo'
import type { Process, Activity, Resource, Simulation } from '@/domain/types'
interface ReportData {
process: Process | null
simulation: Simulation | null
activities: Activity[]
resources: Resource[]
isLoading: boolean
error: string | null
}
export function useReportData(processId: string): ReportData {
const [process, setProcess] = useState<Process | null>(null)
const [simulation, setSimulation] = useState<Simulation | null>(null)
const [activities, setActivities] = useState<Activity[]>([])
const [resources, setResources] = useState<Resource[]>([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
let cancelled = false
async function load() {
setIsLoading(true)
setError(null)
try {
const [proc, sim, acts, res] = await Promise.all([
supabaseProcessRepo.getById(processId),
supabaseSimulationRepo.getLatestByProcess(processId),
supabaseActivityRepo.getByProcess(processId),
supabaseResourceRepo.getAll(),
])
if (cancelled) return
if (!proc) throw new Error('Proceso no encontrado en la base de datos local')
if (!sim) throw new Error('Sin simulación disponible. Volvé al workspace y ejecutá "Simular" primero.')
setProcess(proc)
setSimulation(sim)
setActivities(acts)
setResources(res)
} catch (err) {
if (!cancelled) setError(err instanceof Error ? err.message : 'Error al cargar el reporte')
} finally {
if (!cancelled) setIsLoading(false)
}
}
load()
return () => { cancelled = true }
}, [processId])
return { process, simulation, activities, resources, isLoading, error }
}