# 📊 Unleash AB Testing → Google Analytics - Подробная документация

## 🎯 Общая схема работы

```
1. Пользователь заходит в воронку
   ↓
2. UnleashProvider инициализируется (layout.tsx)
   ↓
3. FunnelUnleashWrapper собирает все флаги из воронки
   ↓
4. Unleash SDK загружает варианты флагов
   ↓
5. useUnleash подписывается на события "impression"
   ↓
6. При активации флага → отправка в Google Analytics
```

---

## 1️⃣ В какой момент отправляется событие

### Цепочка инициализации:

#### Шаг 1: Загрузка воронки
```tsx
// src/app/[funnelId]/layout.tsx
<UnleashProvider>  {/* ← Инициализируется один раз */}
  <PixelsProvider googleAnalyticsId={funnel.meta.googleAnalyticsId}>
    {children}
  </PixelsProvider>
</UnleashProvider>
```

#### Шаг 2: Сбор флагов из воронки
```tsx
// src/components/funnel/FunnelUnleashWrapper.tsx
export function FunnelUnleashWrapper({ funnel }) {
  // Сканирует все экраны и собирает уникальные флаги
  const allFlags = useMemo(() => {
    const flags = new Set<string>();
    
    funnel.screens.forEach((screen) => {
      // Из вариантов экранов
      screen.variants?.forEach(variant => {
        variant.conditions.forEach(condition => {
          if (condition.conditionType === "unleash") {
            flags.add(condition.unleashFlag);
          }
        });
      });
      
      // Из правил навигации
      screen.navigation?.rules?.forEach(rule => {
        rule.conditions.forEach(condition => {
          if (condition.conditionType === "unleash") {
            flags.add(condition.unleashFlag);
          }
        });
      });
    });
    
    return Array.from(flags);
  }, [funnel.screens]);
  
  // Получаем варианты для ВСЕХ флагов сразу
  const flagVariants = allFlags.map(flag => {
    const variant = useVariant(flag);
    return { flag, variant: variant?.name };
  });
}
```

#### Шаг 3: Подписка на события
```tsx
// src/lib/funnel/unleash/useUnleash.ts
useEffect(() => {
  const handleImpression = (impressionEvent) => {
    if (impressionEvent.enabled) {
      // ✅ ОТПРАВКА В GA
      window.gtag("event", "experiment_impression", {
        app_name: "witlab-funnel",
        feature: impressionEvent.featureName,
        treatment: impressionEvent.variant,
      });
    }
  };

  unleashClient.on("impression", handleImpression);
  
  return () => {
    unleashClient.off("impression", handleImpression);
  };
}, [unleashClient]);
```

### ⏰ Timing событий:

| Момент | Действие | Когда отправляется в GA |
|--------|----------|-------------------------|
| **T+0ms** | Пользователь открывает воронку | - |
| **T+100ms** | UnleashProvider подключается к Unleash | - |
| **T+300ms** | Unleash возвращает варианты флагов | ✅ **Здесь!** |
| **T+300ms** | Unleash SDK эмитит событие "impression" | ✅ **И здесь!** |
| **T+301ms** | useUnleash ловит событие → window.gtag() | ✅ **События отправлены** |
| **T+500ms** | Воронка рендерится с правильными вариантами | - |

### 🔄 Повторная отправка:

**НЕТ повторных отправок** для одного флага в рамках сессии:
- Unleash SDK внутри помнит какие impression уже отправлены
- События эмитятся только **один раз** при первой активации флага
- При переходе между экранами события **НЕ отправляются повторно**

---

## 2️⃣ Какие данные отправляются

### Формат события в Google Analytics:

```javascript
window.gtag("event", "experiment_impression", {
  app_name: "witlab-funnel",           // Идентификатор приложения
  feature: "trial-button-test",        // Название флага из Unleash
  treatment: "v1"                      // Вариант который получил пользователь
});
```

### Детали полей:

| Поле | Тип | Значение | Описание |
|------|-----|----------|----------|
| **event** | string | `"experiment_impression"` | Стандартное название для AB тестов в GA |
| **app_name** | string | `"witlab-funnel"` | Фиксированное имя приложения |
| **feature** | string | `impressionEvent.featureName` | Название флага из Unleash |
| **treatment** | string | `impressionEvent.variant` | Вариант: "v0", "v1", "v2", "disabled" и т.д. |

### Пример реальных данных:

```javascript
// AB тест кнопки оплаты
{
  event: "experiment_impression",
  app_name: "witlab-funnel",
  feature: "trial-payment-button",
  treatment: "v1"
}

// AB тест навигации
{
  event: "experiment_impression",
  app_name: "witlab-funnel",
  feature: "onboarding-flow-test",
  treatment: "short"
}

// Несколько флагов → несколько событий
{
  event: "experiment_impression",
  app_name: "witlab-funnel",
  feature: "special-offer-test",
  treatment: "v2"
}
```

### 📊 Как увидеть в Google Analytics:

1. **Realtime → Events**
   - Событие: `experiment_impression`
   - Параметры: `app_name`, `feature`, `treatment`

2. **Reports → Engagement → Events**
   - Найти `experiment_impression`
   - Посмотреть breakdown по `feature`
   - Посмотреть distribution по `treatment`

3. **Создать кастомный отчет:**
   ```
   Dimensions: 
   - Event name (experiment_impression)
   - Event parameter: feature
   - Event parameter: treatment
   
   Metrics:
   - Event count
   - Users
   ```

---

## 3️⃣ Совпадает ли логика с aura-webapp

### ✅ Сходства (95% идентичны):

#### 1. Точно такой же механизм отправки:
```typescript
// ✅ WITLAB-FUNNEL
unleashClient.on("impression", (impressionEvent) => {
  window.gtag("event", "experiment_impression", {
    app_name: "witlab-funnel",
    feature: impressionEvent.featureName,
    treatment: impressionEvent.variant,
  });
});

// ✅ AURA-WEBAPP
unleashClient.on("impression", (impressionEvent: any) => {
  window.gtag?.("event", "experiment_impression", {
    app_name: impressionEvent.context.appName,
    feature: impressionEvent.featureName,
    treatment: impressionEvent.variant,
  });
});
```

#### 2. Одинаковый формат события:
- Название: `"experiment_impression"`
- Параметры: `app_name`, `feature`, `treatment`
- Условие: только если `impressionEvent.enabled === true`

#### 3. Подписка в useEffect:
- В обоих случаях подписка через `unleashClient.on("impression")`
- В обоих случаях cleanup через `unleashClient.off("impression")`

### ⚠️ Различия (минимальные):

| Аспект | witlab-funnel | aura-webapp | Критично? |
|--------|---------------|-------------|-----------|
| **app_name** | Хардкод `"witlab-funnel"` | Из `context.appName` | ⚠️ Да* |
| **window.gtag** | `window.gtag` | `window.gtag?.` | ✅ Нет |
| **Debug логи** | ✅ Есть в dev | ❌ Нет | ✅ Нет |
| **Типизация** | Явная типизация | `any` | ✅ Нет |

**\* Рекомендация:** Можно улучшить чтобы брать из context:

```typescript
// Улучшенная версия (опционально)
window.gtag("event", "experiment_impression", {
  app_name: impressionEvent.context?.appName || "witlab-funnel",
  feature: impressionEvent.featureName,
  treatment: impressionEvent.variant,
});
```

### 📋 Вывод по совместимости:

✅ **Логика полностью совместима**
- События будут выглядеть одинаково в GA
- Можно создать единые отчеты для обоих приложений
- Единственная разница - в `app_name` (можно использовать для фильтрации)

---

## 4️⃣ Что если Google Analytics не установлена

### Сценарий: GA не настроена

```tsx
// В воронке:
{
  "meta": {
    "googleAnalyticsId": undefined  // ← Не указан
  }
}
```

### ✅ Защита от ошибок:

```typescript
// src/lib/funnel/unleash/useUnleash.ts
if (typeof window !== "undefined" && window.gtag) {
  //                                   ^^^^^^^^^^^^
  //                          Проверка что gtag существует
  window.gtag("event", "experiment_impression", {...});
}
```

### Что произойдет:

1. ✅ **Unleash продолжит работать нормально**
   - Флаги загружаются
   - Варианты применяются
   - AB тесты работают

2. ✅ **Событие "impression" будет эмититься**
   - `unleashClient.on("impression")` сработает
   - `handleImpression()` будет вызван

3. ⚠️ **Отправка в GA будет пропущена**
   - Проверка `window.gtag` вернет `false`
   - Блок с `window.gtag()` НЕ выполнится
   - **Никакой ошибки не будет**

4. 🐛 **Debug логи все равно работают**
   ```javascript
   // В консоли браузера (в dev):
   [Unleash Analytics] {
     feature: "trial-button-test",
     variant: "v1"
   }
   ```

### Поведение в разных средах:

| Среда | GA установлена? | window.gtag? | Что происходит |
|-------|----------------|--------------|----------------|
| **Production с GA** | ✅ Да | ✅ Да | ✅ События отправляются |
| **Production без GA** | ❌ Нет | ❌ Нет | ✅ AB тесты работают, GA молчит |
| **Development с GA** | ✅ Да | ✅ Да | ✅ События + debug логи |
| **Development без GA** | ❌ Нет | ❌ Нет | ✅ AB тесты + debug логи |
| **Preview/Staging** | Зависит | Зависит | Зависит от настройки |

### Рекомендации:

#### ✅ Текущая реализация безопасна:
```typescript
// Нет ошибок если GA отсутствует
if (typeof window !== "undefined" && window.gtag) {
  window.gtag(...); // Выполнится только если GA загружен
}
```

#### ⚠️ Можно добавить предупреждение (опционально):
```typescript
if (process.env.NODE_ENV === "development") {
  if (typeof window !== "undefined" && !window.gtag) {
    console.warn("[Unleash Analytics] Google Analytics not loaded");
  }
}
```

---

## 🔍 Debug и мониторинг

### В development режиме:

```javascript
// Консоль браузера автоматически показывает:
[Unleash Analytics] { feature: "trial-test", variant: "v1" }
[Unleash Analytics] { feature: "button-test", variant: "v2" }
```

### Проверка отправки в GA:

#### 1. Через Network tab:
```
1. Откройте DevTools → Network
2. Фильтр: "collect" или "analytics"
3. Ищите POST запросы к:
   - https://www.google-analytics.com/g/collect
   - https://www.google-analytics.com/j/collect
4. В payload должны быть:
   - en=experiment_impression
   - ep.feature=trial-test
   - ep.treatment=v1
```

#### 2. Через Google Analytics DebugView:
```bash
# 1. Включите debug mode
localStorage.setItem('ga_debug', '1')

# 2. Перезагрузите страницу
# 3. Откройте GA → Admin → DebugView
# 4. Увидите события в реальном времени
```

#### 3. Через расширение Google Analytics Debugger:
```
1. Установите Chrome extension "Google Analytics Debugger"
2. Включите его
3. В консоли увидите все GA события с деталями
```

---

## 📊 Пример полного flow

### Сценарий: Воронка с 2 AB тестами

```json
{
  "meta": {
    "googleAnalyticsId": "G-XXXXXXXXXX"
  },
  "screens": [
    {
      "id": "payment",
      "variants": [
        {
          "conditions": [
            {
              "conditionType": "unleash",
              "unleashFlag": "trial-button-test",
              "unleashVariants": ["v1"]
            }
          ]
        }
      ]
    },
    {
      "id": "gender",
      "navigation": {
        "rules": [
          {
            "conditions": [
              {
                "conditionType": "unleash",
                "unleashFlag": "onboarding-flow",
                "unleashVariants": ["short"]
              }
            ]
          }
        ]
      }
    }
  ]
}
```

### Timeline событий:

```
T+0ms:     Пользователь открывает /soulmate/payment
T+50ms:    UnleashProvider инициализируется
T+100ms:   FunnelUnleashWrapper собирает флаги:
           ["trial-button-test", "onboarding-flow"]
T+300ms:   Unleash возвращает варианты:
           trial-button-test → v1
           onboarding-flow → short
T+300ms:   Unleash эмитит 2 impression события
T+301ms:   useUnleash ловит события
T+301ms:   ✅ Отправка в GA #1:
           {
             event: "experiment_impression",
             app_name: "witlab-funnel",
             feature: "trial-button-test",
             treatment: "v1"
           }
T+302ms:   ✅ Отправка в GA #2:
           {
             event: "experiment_impression",
             app_name: "witlab-funnel",
             feature: "onboarding-flow",
             treatment: "short"
           }
T+500ms:   FunnelLoadingScreen исчезает
T+501ms:   Экран рендерится с правильными вариантами
```

### В консоли разработчика:

```
[Unleash Analytics] { feature: "trial-button-test", variant: "v1" }
[Unleash Analytics] { feature: "onboarding-flow", variant: "short" }
```

---

## 🎯 Итоговые выводы

### 1. Момент отправки:
✅ **При первой активации флага** (~300ms после загрузки воронки)
✅ **Только один раз** за сессию для каждого флага
✅ **Автоматически** без необходимости явного вызова

### 2. Данные:
✅ Событие: `"experiment_impression"`
✅ Параметры: `app_name`, `feature`, `treatment`
✅ Формат совместим с Google Analytics 4

### 3. Совместимость с aura-webapp:
✅ **95% идентично**
✅ Можно использовать единые GA отчеты
⚠️ Единственная разница: `app_name` (легко фильтровать)

### 4. Без Google Analytics:
✅ **AB тесты работают нормально**
✅ **Никаких ошибок**
✅ Debug логи в dev режиме
⚠️ События просто не отправляются (graceful degradation)

---

## 📚 См. также

- `AB_TESTING_GUIDE.md` - Общее руководство по AB тестам
- `AB_TESTING_UPDATES.md` - Технические детали и оптимизации
- `UNLEASH_SETUP.md` - Настройка Unleash
