Reporte — JSONB
Generado por el equipo de agentes PMO | 2026-06-05
Frank, aquí va el desglose detallado basado en datos reales del codebase y la infraestructura actual: --- ## 🔍 Cuellos de Botella Detectados ### 1. `/ecosistema` — 9 queries por carga de página Cada vez que un usuario abre el Hub Central, el servidor dispara **9 consultas simultáneas a Supabase**: conteo de startups, conteo de ICGs, países de startups, países de ICGs, perfil del usuario, startups activas, ICGs activos, y más. Con pocos usuarios esto pasa desapercibido (~200ms), pero a escala: - **50 usuarios simultáneos** = 450 queries/segundo al mismo tiempo - **Supabase Free tiene 15 conexiones de pool** — con picos de 20+ usuarios concurrentes, empezarías a ver errores de "too many connections" **Riesgo:** 🔴 Alto — es la página más visitada del sistema **Prioridad:** P1 — resolver antes de cualquier campaña de crecimiento **Solución:** - Consolidar las 9 queries en **1 o 2 funciones RPC** en Supabase (SQL nativo, mucho más eficiente) - Cachear las métricas públicas (conteo startups/ICGs/países) con un TTL de 5 minutos — esos números no cambian cada segundo - Estimación: tallaje **S** (1-2 días de trabajo del equipo técnico) --- ### 2. Sin paginación en consultas principales Las consultas de startups e ICGs traen **todos los registros de golpe**. Hoy con pocas decenas de entidades no se nota, pero: - **500 startups** = payload de ~2MB por request - **5,000 startups** = el navegador tarda 3-5 segundos en renderizar la lista **Riesgo:** 🟡 Medio — crece proporcional al éxito del sistema **Prioridad:** P2 — implementar cuando se superen ~200 entidades registradas **Solución:** - Implementar paginación server-side con `.range(from, to)` de Supabase (20-50 registros por página) - Agregar búsqueda server-side (hoy todo el filtrado es client-side, lo cual no escala) - Estimación: tallaje **M** --- ### 3. JSONB sin índices GIN El sistema usa columnas JSONB (ej: `annual_revenue_by_year`, `interest_industries`) pero **no tiene índices GIN** sobre ellas. Esto significa que cada consulta que filtre o busque dentro de esos campos hace un **full table scan** — lee toda la tabla fila por fila. **Riesgo:** 🟡 Medio — impacto crece con volumen de datos **Prioridad:** P3 — no urgente hoy, crítico con +1,000 entidades **Solución:** - Crear índices GIN en las columnas JSONB usadas en filtros - Migración SQL simple, sin downtime - Estimación: tallaje **S** --- ### 4. Archivos "monolíticos" en el frontend Hay componentes muy grandes que afectan mantenibilidad y tiempo de carga: | Archivo | Líneas | Riesgo | |---------|--------|--------| | StartupDetailedFormShell | 4,950 | 🔴 | | IcgFormShell | 4,384 | 🔴 | | StartupSimplifiedFormShell | 2,781 | 🟡 | | ecosistema/+page.svelte | 1,881 | 🟡 | Estos archivos son difíciles de mantener, lentos de cargar en el navegador, y propensos a bugs cuando se tocan (un cambio en una parte puede romper otra). **Riesgo:** 🟡 Medio — más de mantenibilidad que de performance para el usuario **Prioridad:** P3 — refactorizar gradualmente, no de golpe **Solución:** - Descomponer cada formulario en sub-componentes por sección (datos generales, financieros, equipo, etc.) - No afecta al usuario, mejora la velocidad de desarrollo y reduce bugs - Estimación: tallaje **L** (hacerlo incremental, no todo de una vez) --- ## ⚠️ Riesgos por Plan Supabase Free | Límite | Valor actual | Umbral crítico | Estado | |--------|-------------|----------------|--------| | Base de datos | 500 MB | ~400 MB (80%) | 🟢 Lejos aún | | Bandwidth | 5 GB/mes | ~4 GB | 🟢 OK | | Storage (archivos) | 1 GB | ~800 MB | 🟢 OK | | Conexiones | 15 pool | 12+ simultáneas | 🟡 Vigilar | | Backups | Diarios, 7 días | Sin PITR | 🔴 Riesgo | | Edge Functions | No hay | — | ℹ️ Oportunidad | ### El riesgo más serio: **sin Point-in-Time Recovery (PITR)** Con el plan Free, si ocurre un error que corrompe datos (un DELETE sin WHERE, un bug en un update masivo), solo puedes restaurar al **backup del día anterior**. Pierdes todo lo que pasó desde la última copia. **Solución:** Migrar a Supabase Pro ($25/mes) cuando el sistema tenga datos reales de producción. Esto da PITR, 8 GB de DB, y más conexiones. --- ## 📋 Prioridades Recomendadas (hoja de ruta) | # | Acción | Tallaje | Impacto | Cuándo | |---|--------|---------|---------|--------| | 1 | Consolidar queries de `/ecosistema` en RPC + cache | S | 🔴 Performance | **Ya** — antes de crecer | | 2 | Paginación server-side en listas | M | 🔴 Escalabilidad | Antes de 200+ entidades | | 3 | Monitoreo de uso de Supabase (dashboard) | S | 🟡 Visibilidad | **Ya** — es gratis | | 4 | Índices GIN en columnas JSONB | S | 🟡 Performance | Antes de 1,000+ entidades | | 5 | Plan de migración a Supabase Pro | — | 🔴 Resiliencia | Cuando haya datos reales de producción | | 6 | Refactorizar formularios grandes | L | 🟡 Mantenibilidad | Gradual, sin fecha fija | --- ## 🏁 Resumen ejecutivo El sistema LPDI **está bien construido para su etapa actual** — stack moderno (SvelteKit + Supabase), código organizado, RLS implementado. Los cuellos de botella no son bugs sino **decisiones de arquitectura que funcionan bien con pocos usuarios pero no escalan solas**. La buena noticia: las soluciones de mayor impacto (consolidar queries, agregar paginación, crear índices) son de tallaje **S a M** — se pueden implementar rápido y sin romper nada existente. ¿Quieres que arranquemos con alguna de estas mejoras? Mi recomendación sería empezar por la **#1 (consolidar queries del ecosistema)** que es la de mayor impacto con menor esfuerzo. _También pendientes (sin acknowledgment todavía): LAP-329, LAP-340, LAP-343, LAP-344_