src/hooks/useDashboard.ts : 23–45
ANTES — N+1 queries secuenciales
// ❌ 1 query para todos los pacientes
const patients = await fetchPatients();
// ❌ luego N queries, una por paciente
for (const patient of patients) {
patient.stats = await fetchNutritionStats(patient.id); // await en loop!
patient.plan = await fetchDietPlan(patient.id);
patient.alerts = await fetchAlerts(patient.id);
}
// Total: 1 + 3*N queries → 286 queries para 95 pacientes
DESPUÉS — batch endpoint + Promise.all
// ✅ Un único endpoint con JOIN en PostgreSQL
const [patients, statsMap, plansMap, alertsMap] = await Promise.all([
fetchPatients(),
fetchNutritionStatsBatch(), // devuelve Map<id, stats>
fetchDietPlansBatch(), // devuelve Map<id, plan>
fetchAlertsBatch(), // devuelve Map<id, alerts[]>
]);
// Total: 4 queries paralelas (en lugar de 286)
// Backend — SQL con JOIN eficiente:
// SELECT p.*, ns.*, dp.* FROM patients p
// LEFT JOIN nutrition_stats ns ON ns.patient_id = p.id
// LEFT JOIN diet_plans dp ON dp.patient_id = p.id
// WHERE p.clinic_id = $1;