npm package: @metodokorexmk/tracking
Description: Sistema de tracking reutilizable para landing pages con GA4, GTM y video tracking multi-plataforma
Author: MetodoKorexMK
Latest version: 2.0.0

﻿# @metodokorexmk/tracking

Sistema de tracking reutilizable para landing pages con **Google Analytics 4**, **Google Tag Manager** y **video tracking multi-plataforma** (Wistia, Voomly, HTML5).

## Características

- 🎯 **GA4 con ID multi-tenant**: Cada proyecto/colaborador puede tener su propio GA Tracking ID.
- 📊 **Integración GTM**: Envía eventos simultáneamente a GA4 y al `dataLayer` de GTM.
- 📹 **Video tracking**: Adaptadores para Wistia, Voomly e HTML5 nativo.
- 📜 **Scroll tracking**: Milestones automáticos (25%, 50%, 75%, 100%).
- 🖱️ **Click heatmap**: Captura coordenadas de clicks por sección.
- 📝 **Form auto-tracking**: Detecta automáticamente inicio, campos y envío de formularios.
- ⏱️ **Dwell time por sección**: Mide tiempo de permanencia con IntersectionObserver.
- 🎯 **Funnel tracking**: Quiz, Thank You Page y WhatsApp click (Regla 1).
- 🔗 **Attribution completa**: `campaign_id`, `adset_id`, `ad_id`, UTMs (Regla 3).
- ⚛️ **Hooks React opcionales**: Import separado que no afecta a proyectos sin React.
- 🔧 **Framework-agnostic**: Las capas core funcionan en cualquier entorno con DOM.

## Instalación

```bash
npm install @metodokorexmk/tracking react-ga4
# o
yarn add @metodokorexmk/tracking react-ga4
```

> `react-ga4` es una peer dependency. Si usas los hooks React, también necesitas `react >= 18`.

## Quick Start

### Vanilla JavaScript / TypeScript

```ts
import { initGA, trackPageView, trackEvent, createLandingTracker } from '@metodokorexmk/tracking';

// 1. Inicializar GA4
initGA({ trackingId: 'G-XXXXXXX' });

// 2. Trackear pageview
trackPageView('/mi-landing');

// 3. Crear tracker completo para la landing
const tracker = createLandingTracker({
  pagePath: '/mi-landing',
  pageName: 'Mi Landing Page',
  gtmId: 'GTM-XXXXXXX', // Opcional
});

// 4. Trackear eventos manuales
trackEvent('CTA', 'click', 'Botón Principal');

// 5. Al desmontar:
tracker.destroy();
```

### React / Next.js

```tsx
import { initGA } from '@metodokorexmk/tracking';
import { useLandingPageTracking, useVideoTracking } from '@metodokorexmk/tracking/react';

// Inicializar una vez en la app
initGA({ trackingId: 'G-XXXXXXX' });

function MiLanding() {
  // Tracking automático de la landing
  const tracker = useLandingPageTracking({
    pagePath: '/mi-landing',
    pageName: 'Mi Landing Page',
  });

  // Tracking de video HTML5
  const videoRef = useRef<HTMLVideoElement>(null);
  const { progress, isPlaying } = useVideoTracking({
    videoId: 'hero-video',
    videoElement: videoRef.current,
    onComplete: () => console.log('Video completado'),
  });

  return (
    <>
      <video ref={videoRef} src="/video.mp4" />
      <button onClick={() => tracker?.trackCTAClick('Unirse', 'hero')}>Unirse</button>
    </>
  );
}
```

## Documentación

| Doc                                                           | Descripción                                                                                    |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [GUIA-COMPLETA.md](./docs/GUIA-COMPLETA.md)                   | Guía paso a paso completa: despliegue, integración y ejemplos                                  |
| [ARCHITECTURE.md](./docs/ARCHITECTURE.md)                     | Arquitectura de 4 capas, patrones de diseño, reglas de implementación y convenciones de código |
| [INTEGRATION-GUIDE.md](./docs/INTEGRATION-GUIDE.md)           | Guía paso a paso de integración + tabla de migración desde KOREX-WEB-PROD                      |
| [backend_rules_tracking.md](./docs/backend_rules_tracking.md) | Requerimientos de backend derivados de `rules_context.md`                                      |
| [rules_context.md](./docs/rules_context.md)                   | Reglas de negocio del sistema de métricas de ads                                               |

## Arquitectura

La librería usa una arquitectura de **4 capas** con dependencias unidireccionales:

```
React Hooks (opcional)  ← @metodokorexmk/tracking/react
        ↓
Orchestrator            ← LandingTracker (sesión completa)
        ↓
Trackers                ← video-tracker, events, wistia/voomly/html5 adapters
        ↓
Core                    ← analytics (GA4), gtm, types
```

> **Regla:** Las capas 1-3 son **framework-agnostic**. Solo la capa 4 importa React.

### Patrones de diseño aplicados

| Patrón        | Uso                                                         | Archivo                                  |
| ------------- | ----------------------------------------------------------- | ---------------------------------------- |
| **Singleton** | Una instancia global de VideoTracker                        | `video-tracker.ts`                       |
| **Factory**   | `createLandingTracker(config)` crea instancias              | `landing-tracker.ts`                     |
| **Observer**  | Callbacks `onUpdate()` en adaptadores de video              | `wistia-adapter.ts`, `voomly-adapter.ts` |
| **Strategy**  | `resolveTrackingId` inyecta lógica de resolución de GA ID   | `analytics.ts`                           |
| **Dual Send** | Cada evento se envía por `gtag` + `ReactGA` simultáneamente | `analytics.ts`                           |

Ver [ARCHITECTURE.md](./docs/ARCHITECTURE.md) para detalles completos.

## Convenciones de nombrado de archivos

| Tipo            | Patrón                    | Ejemplo                   |
| --------------- | ------------------------- | ------------------------- |
| Módulo core     | `{nombre}.ts`             | `analytics.ts`, `gtm.ts`  |
| Adaptador video | `{plataforma}-adapter.ts` | `wistia-adapter.ts`       |
| Clase tracker   | `{nombre}-tracker.ts`     | `video-tracker.ts`        |
| Hook React      | `use-{nombre}.ts`         | `use-landing-tracking.ts` |
| Test unitario   | `{módulo}.test.ts`        | `analytics.test.ts`       |

> Todos los archivos usan **kebab-case**. Exports usan `camelCase` (funciones) y `PascalCase` (clases/tipos).

## API Pública

### Core (`@metodokorexmk/tracking`)

| Export                                           | Descripción                                       |
| ------------------------------------------------ | ------------------------------------------------- |
| `initGA(config)`                                 | Inicializa Google Analytics 4                     |
| `trackEvent(cat, action, label?, value?, data?)` | Envía evento a GA4                                |
| `trackPageView(path)`                            | Envía pageview                                    |
| `captureUTMParams()`                             | Extrae UTM params de la URL                       |
| `captureUserIdFromURL()`                         | Lee `?user_id=` de la URL                         |
| `createLandingTracker(config)`                   | Crea orquestador de sesión completa               |
| `trackWistiaByMediaId(id)`                       | Tracking de video Wistia                          |
| `trackVoomlyByEmbedId(id)`                       | Tracking de video Voomly                          |
| `trackHTML5Video(id, element)`                   | Tracking de `<video>` nativo                      |
| `trackCTAClick(btn, section)`                    | Evento CTA click                                  |
| `trackFormSubmit(name, success)`                 | Evento formulario enviado                         |
| `trackConversion(type, value?)`                  | Evento de conversión                              |
| `trackQuizStart(quizName)`                       | Evento inicio de quiz                             |
| `trackQuizAnswer(quizName, index, answer)`       | Evento respuesta a pregunta del quiz              |
| `trackQuizComplete(quizName, total?, score?)`    | Evento quiz completado                            |
| `trackThankYouPageVisit(source?)`                | Evento visita a Thank You Page                    |
| `trackWhatsAppClick(phone?, section?)`           | Evento clic en enlace WhatsApp                    |
| `extractUrlParams(url?)`                         | Extrae params de tracking incl. `adsetId`, `adId` |
| `pushToDataLayer(event, data)`                   | Push directo al GTM dataLayer                     |
| `injectGTMScript(gtmId)`                         | Inyecta script de GTM                             |

### React Hooks (`@metodokorexmk/tracking/react`)

| Export                            | Descripción                 |
| --------------------------------- | --------------------------- |
| `useLandingPageTracking(config)`  | Hook orquestador de landing |
| `useVideoTracking(options)`       | Hook para HTML5 video       |
| `useWistiaVideoTracking(mediaId)` | Hook para Wistia video      |

## Calidad de código

La librería usa **ESLint (Airbnb)** + **Prettier** para mantener estándares de código consistentes:

```bash
npm run lint          # Verificar errores de ESLint
npm run lint:fix      # Auto-corregir errores de ESLint
npm run format        # Formatear código con Prettier
npm run format:check  # Verificar formato sin modificar
```

### Config

| Herramienta    | Config           | Estilo                                                  |
| -------------- | ---------------- | ------------------------------------------------------- |
| **ESLint**     | `.eslintrc.json` | Airbnb base + TypeScript + Prettier                     |
| **Prettier**   | `.prettierrc`    | `singleQuote`, `semi`, `printWidth: 140`, `tabWidth: 2` |
| **TypeScript** | `tsconfig.json`  | `strict: true`, ES2020, bundler module resolution       |

## Scripts

```bash
npm run build         # Build ESM + CJS + d.ts con tsup
npm test              # Tests unitarios con Vitest
npm run test:coverage # Tests con cobertura
npm run typecheck     # Verificación de tipos
npm run lint          # Lint con ESLint Airbnb
npm run lint:fix      # Lint + auto-fix
npm run format        # Formatear con Prettier
npm run format:check  # Verificar formato
```

## Licencia

MIT