Saltar al contenido principal

Arquitectura del Frontend CDP

Visión General

El frontend del Customer Data Platform (CDP) de Nerdistan es una aplicación web moderna construida con React 18 y optimizada para visualización de datos en tiempo real. La arquitectura está diseñada para manejar grandes volúmenes de datos de clientes (200K+ consumidores) con una experiencia de usuario fluida y responsiva.

Stack Tecnológico

Core

  • React 18.2.0: Framework principal para construcción de UI
  • Vite 5.0.11: Build tool ultra-rápido con HMR (Hot Module Replacement)
  • JavaScript/JSX: Lenguaje principal (sin TypeScript por simplicidad)

UI y Visualización

  • Tremor.so 3.x: Biblioteca de componentes especializados en dashboards
  • Recharts 2.x: Gráficos y visualizaciones interactivas
  • Tailwind CSS 3.x: Sistema de diseño utility-first
  • Heroicons: Iconografía consistente

Estado y Datos

  • React Hooks: useState, useEffect para gestión de estado local
  • Fetch API: Comunicación con backend sin librerías adicionales
  • Local State: Sin Redux/Context API por simplicidad

Estructura del Proyecto

nerdistan-cdp-frontend/
├── src/
│ ├── components/ # Componentes reutilizables
│ │ ├── DashboardTremor.jsx # Dashboard principal con selector de tenants
│ │ ├── CDPAnalytics.jsx # Análisis RFM y segmentación
│ │ ├── DataViewer.jsx # Visualizador de datos raw
│ │ ├── VTEXIntegrationConfig.jsx # Configuración VTEX
│ │ └── GoogleAds/
│ │ └── AudienceManager.jsx # Gestión de audiencias Google Ads
│ ├── App.jsx # Componente raíz
│ ├── main.jsx # Entry point
│ └── index.css # Estilos globales
├── public/ # Assets estáticos
├── dist/ # Build de producción
└── vite.config.js # Configuración de Vite

Componentes Principales

1. DashboardTremor

El componente central que orquesta toda la aplicación:

  • Selector de Tenants: Permite cambiar entre diferentes cuentas (56, 52, 53, etc.)
  • Tabs de Navegación: Overview, CDP Analytics, Data Viewer, Google Ads, VTEX
  • Estado Global: Mantiene tenantId y tenantName para toda la app

2. CDPAnalytics

Sistema completo de análisis de clientes:

  • Análisis RFM: Segmentación por Recency, Frequency, Monetary
  • Churn Prediction: Predicción de abandono con ML
  • Customer Profiles: Perfiles detallados de clientes
  • Lifecycle Stages: Etapas del ciclo de vida del cliente

3. DataViewer

Explorador de datos raw del CDP:

  • Visualización Tabular: Muestra datos directos de la base
  • Exportación CSV: Permite descargar datos para análisis externo
  • Métricas Agregadas: Overview de KPIs principales

Patrones de Diseño

1. Component Composition

// Composición jerárquica clara
<DashboardTremor>
<TenantSelector onChange={handleTenantChange} />
<TabGroup>
<Tab>Overview</Tab>
<Tab>CDP Analytics</Tab>
</TabGroup>
<TabPanels>
<CDPAnalytics tenantId={selectedTenant} />
</TabPanels>
</DashboardTremor>

2. Props Drilling Controlado

// Props fluyen de arriba hacia abajo
const [selectedTenant, setSelectedTenant] = useState(56);

// Pasar solo lo necesario a cada componente
<CDPAnalytics
tenantId={selectedTenant}
tenantName={getTenantName(selectedTenant)}
/>

3. Error Boundaries Implícitos

// Manejo de errores en cada componente
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);

try {
const data = await fetchData();
} catch (err) {
setError(err.message);
// Mostrar UI de error amigable
}

Flujo de Datos

1. Carga Inicial

graph LR
A[App Start] --> B[Load Tenants]
B --> C[Select Default Tenant 56]
C --> D[Fetch Tenant Data]
D --> E[Render Dashboard]

2. Cambio de Tenant

graph LR
A[User Selects Tenant] --> B[Update State]
B --> C[Trigger useEffect]
C --> D[Fetch New Data]
D --> E[Update All Components]

3. Comunicación con API

// Patrón estándar para todas las llamadas API
const API_URL = import.meta.env.VITE_API_URL ||
'https://nerdistan-datalake-production.up.railway.app';

const fetchData = async (tenantId) => {
setLoading(true);
try {
const response = await fetch(
`${API_URL}/api/v2/cdp/analytics/rfm?tenant_id=${tenantId}`
);
if (!response.ok) throw new Error('API Error');
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch error:', error);
throw error;
} finally {
setLoading(false);
}
};

Performance y Optimización

1. Code Splitting

  • Vite automáticamente divide el código en chunks
  • Lazy loading para componentes pesados
  • Dynamic imports para features opcionales

2. Caching Strategy

// Cache local para evitar re-fetches innecesarios
const cache = new Map();

const fetchWithCache = async (key, fetcher) => {
if (cache.has(key)) {
return cache.get(key);
}
const data = await fetcher();
cache.set(key, data);
return data;
};

3. Debouncing y Throttling

// Para búsquedas y filtros
const debounce = (func, wait) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
};

const handleSearch = debounce((query) => {
searchCustomers(query);
}, 300);

Seguridad

1. Sanitización de Inputs

  • Todos los inputs de usuario son validados
  • Escape de HTML en renderizado
  • Validación de tipos en props

2. API Security

  • CORS configurado en backend
  • Sin credenciales sensibles en frontend
  • Variables de entorno para URLs

3. Content Security Policy

// Headers de seguridad en producción
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'unsafe-inline';"
/>

Deployment

Railway Production

Build Process

# Build optimizado para producción
npm run build

# Output en dist/
# - Minified JS/CSS
# - Optimized assets
# - Tree-shaking aplicado

Escalabilidad

1. Manejo de Grandes Datasets

  • Paginación virtual para listas largas
  • Lazy loading de datos on-demand
  • Agregaciones en backend, no frontend

2. Multi-Tenant Architecture

  • Aislamiento completo entre tenants
  • Cache por tenant
  • Rutas dinámicas basadas en tenant_id

3. Futuras Extensiones

  • Fácil agregar nuevos módulos
  • Componentes completamente desacoplados
  • API versioning soportado (v1, v2)

Monitoreo y Debugging

Development

// Logging condicional
if (import.meta.env.DEV) {
console.log('Debug info:', data);
}

Production

  • Railway logs para errores
  • Performance monitoring con Web Vitals
  • Error boundaries para captura de crashes

Mejores Prácticas Aplicadas

  1. Single Responsibility: Cada componente tiene una sola responsabilidad
  2. DRY (Don't Repeat Yourself): Código reutilizable extraído
  3. KISS (Keep It Simple): Sin over-engineering
  4. Composition over Inheritance: Uso de hooks y composición
  5. Fail Fast: Errores detectados temprano con validación

Limitaciones Conocidas

  1. Sin State Management Global: Para simplicidad, no hay Redux/MobX
  2. Sin TypeScript: Decisión consciente para desarrollo rápido
  3. Sin Tests: MVP sin suite de testing (planificado para futuro)
  4. Sin i18n: Solo español por ahora

Roadmap Técnico

Corto Plazo (Q4 2024)

  • ✅ Dashboard funcional con datos reales
  • ✅ Integración con 5 tenants principales
  • ✅ Export CSV básico
  • ⏳ Cache layer con Redis

Mediano Plazo (Q1 2025)

  • TypeScript migration
  • Testing suite (Jest + React Testing Library)
  • Storybook para componentes
  • PWA capabilities

Largo Plazo (2025+)

  • Micro-frontends architecture
  • GraphQL integration
  • Real-time updates con WebSockets
  • Mobile app con React Native