# 🧪 Конкретный анализ AB-тестов в воронке Soulmate

## 📋 Два AB-теста в воронке

1. **`soulmate-onboarding-image`** - тест картинки/видео на первом экране
2. **`soulmate-trial-grid`** - тест навигации после email экрана

---

## 🎯 AB-тест #1: `soulmate-onboarding-image`

### 📍 Где находится в JSON

**Файл:** `public/funnels/soulmate.json`

**Экран:** `"onboarding"` (первый экран воронки)

**Строки:** 51-106

```json
{
  "id": "onboarding",
  "template": "soulmate",
  "variants": [
    {
      "conditions": [{
        "conditionType": "unleash",
        "unleashFlag": "soulmate-onboarding-image",
        "unleashVariants": ["v0"]
      }],
      "overrides": {}
    },
    {
      "conditions": [{
        "conditionType": "unleash",
        "unleashFlag": "soulmate-onboarding-image",
        "unleashVariants": ["v1"]
      }],
      "overrides": {
        "soulmatePortraitsDelivered": {
          "mediaUrl": "/images/90b8c77f-c0cd-475d-a4de-bcabb3708c59.png",
          "mediaType": "image"
        }
      }
    },
    {
      "conditions": [{
        "conditionType": "unleash",
        "unleashFlag": "soulmate-onboarding-image",
        "unleashVariants": ["v2"]
      }],
      "overrides": {
        "soulmatePortraitsDelivered": {
          "mediaUrl": "/images/275472b0-30e0-47d7-a1ab-8090bc9fb236.mp4",
          "mediaType": "video"
        }
      }
    }
  ]
}
```

### 🎬 Что тестируется

Три варианта картинки/видео на первом экране:
- **v0** - дефолтное изображение `/soulmate-portrait-delivered-male.jpg`
- **v1** - альтернативное изображение (PNG)
- **v2** - видео (MP4)

### ⏱️ КОГДА ОТПРАВЛЯЕТСЯ impression событие

```
┌─────────────────────────────────────────────────────────┐
│ T+0ms: Пользователь открывает /soulmate/onboarding     │
│        Это ПЕРВЫЙ экран воронки                          │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+100ms: GoogleAnalytics загружается (gtag.js)          │
│          window.gtag становится доступен                 │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+200ms: FunnelUnleashWrapper сканирует ВСЮ воронку     │
│          Находит флаги:                                  │
│          • soulmate-onboarding-image (из onboarding)     │
│          • soulmate-trial-grid (из email)                │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+300ms: Unleash SDK возвращает варианты                │
│          • soulmate-onboarding-image → "v1" (например)   │
│          • soulmate-trial-grid → "grid" (например)       │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+400ms: FunnelRuntime монтируется                      │
│          currentScreen = onboarding экран                │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+410ms: currentScreenFlags вычисляется                 │
│          Анализирует onboarding экран:                   │
│          • onboarding.variants → soulmate-onboarding-image│
│          • onboarding.navigation → нет флагов            │
│          Результат: ["soulmate-onboarding-image"]        │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+420ms: useEffect срабатывает                          │
│          (FunnelRuntime.tsx, строки 136-150)             │
│                                                          │
│ ✅ sendUnleashImpression(                               │
│      "soulmate-onboarding-image",                       │
│      "v1"                                               │
│    )                                                    │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+421ms: ✅ ОТПРАВКА В GOOGLE ANALYTICS                 │
│                                                          │
│ window.gtag("event", "experiment_impression", {         │
│   app_name: "witlab-funnel",                            │
│   feature: "soulmate-onboarding-image",                 │
│   treatment: "v1"                                       │
│ });                                                     │
│                                                          │
│ sessionStorage.setItem(                                 │
│   "unleash_impression_soulmate-onboarding-image_v1",   │
│   "true"                                                │
│ );                                                      │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ Console (development):                                   │
│ [Unleash Impression] ✅ Sent successfully:              │
│ {                                                        │
│   feature: "soulmate-onboarding-image",                 │
│   variant: "v1"                                         │
│ }                                                        │
└─────────────────────────────────────────────────────────┘
```

### 📊 Когда КОНКРЕТНО

**✅ Impression отправляется:** Сразу при входе пользователя в воронку на ПЕРВЫЙ экран "onboarding"

**⏰ Timing:** ~420ms после загрузки страницы `/soulmate/onboarding`

**🔧 Код:** 
- **Файл:** `src/components/funnel/FunnelRuntime.tsx` (строки 136-150)
- **Функция:** `sendUnleashImpression()` из `src/lib/funnel/unleash/sendImpression.ts`

**📍 Условие отправки:**
```typescript
// В FunnelRuntime.tsx
const currentScreenFlags = useMemo(() => {
  const flags = new Set<string>();
  
  // Сканирует onboarding.variants
  currentScreen.variants?.forEach((variant) => {
    variant.conditions.forEach((condition) => {
      if (condition.conditionType === "unleash" && condition.unleashFlag) {
        flags.add(condition.unleashFlag); // ← "soulmate-onboarding-image"
      }
    });
  });
  
  return Array.from(flags); // ["soulmate-onboarding-image"]
}, [currentScreen]);

useEffect(() => {
  if (currentScreenFlags.length === 0) return;
  
  currentScreenFlags.forEach((flag) => {
    const variant = activeVariants[flag]; // "v1"
    sendUnleashImpression(flag, variant); // ← ОТПРАВКА
  });
}, [currentScreenFlags, activeVariants]);
```

### 🔍 Как проверить в браузере

```javascript
// 1. Открыть /soulmate/onboarding
// 2. Открыть DevTools → Console
// 3. Увидеть:
[Unleash Impression] ✅ Sent successfully: {
  feature: "soulmate-onboarding-image",
  variant: "v1"  // или "v0", "v2"
}

// 4. DevTools → Network → Фильтр "collect"
POST /g/collect?...&en=experiment_impression
  &ep.feature=soulmate-onboarding-image
  &ep.treatment=v1

// 5. DevTools → Application → Session Storage
unleash_impression_soulmate-onboarding-image_v1: "true"
```

---

## 🎯 AB-тест #2: `soulmate-trial-grid`

### 📍 Где находится в JSON

**Файл:** `public/funnels/soulmate.json`

**Экран:** `"email"` (экран ввода email)

**Строки:** 2277-2309

```json
{
  "id": "email",
  "template": "email",
  "navigation": {
    "rules": [
      {
        "conditions": [{
          "conditionType": "unleash",
          "unleashFlag": "soulmate-trial-grid",
          "unleashVariants": ["coupon"]
        }],
        "nextScreenId": "coupon"
      },
      {
        "conditions": [{
          "conditionType": "unleash",
          "unleashFlag": "soulmate-trial-grid",
          "unleashVariants": ["grid"]
        }],
        "nextScreenId": "trial-choice"
      }
    ],
    "defaultNextScreenId": "coupon"
  }
}
```

### 🎬 Что тестируется

Два варианта навигации после email экрана:
- **coupon** - переход на экран с купоном (`coupon`)
- **grid** - переход на экран с выбором тарифов (`trial-choice`)

### ⏱️ КОГДА ОТПРАВЛЯЕТСЯ impression событие

```
┌─────────────────────────────────────────────────────────┐
│ Пользователь прошел всю воронку:                        │
│ onboarding → gender → partner-gender → ... → email       │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+0ms: Пользователь попадает на экран /soulmate/email  │
│        Это 19-й экран воронки (почти в конце)            │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ ВАЖНО: Unleash уже загружен!                            │
│ activeVariants уже содержит:                             │
│ {                                                        │
│   "soulmate-onboarding-image": "v1",  ← уже отправлено  │
│   "soulmate-trial-grid": "grid"       ← еще НЕ отправлено│
│ }                                                        │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+100ms: FunnelRuntime обновляется                      │
│          currentScreen = email экран                     │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+110ms: currentScreenFlags пересчитывается             │
│          Анализирует email экран:                        │
│          • email.variants → нет unleash флагов           │
│          • email.navigation.rules → soulmate-trial-grid  │
│          Результат: ["soulmate-trial-grid"]              │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+120ms: useEffect срабатывает                          │
│          (FunnelRuntime.tsx, строки 136-150)             │
│                                                          │
│ ✅ sendUnleashImpression(                               │
│      "soulmate-trial-grid",                             │
│      "grid"                                             │
│    )                                                    │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+121ms: Проверка sessionStorage:                       │
│          "unleash_impression_soulmate-trial-grid_grid"  │
│          НЕ найдено ✅ (первый раз на этом экране)      │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ T+122ms: ✅ ОТПРАВКА В GOOGLE ANALYTICS                 │
│                                                          │
│ window.gtag("event", "experiment_impression", {         │
│   app_name: "witlab-funnel",                            │
│   feature: "soulmate-trial-grid",                       │
│   treatment: "grid"                                     │
│ });                                                     │
│                                                          │
│ sessionStorage.setItem(                                 │
│   "unleash_impression_soulmate-trial-grid_grid",       │
│   "true"                                                │
│ );                                                      │
└─────────────────────────────────────────────────────────┘
                        │
┌─────────────────────────────────────────────────────────┐
│ Console (development):                                   │
│ [Unleash Impression] ✅ Sent successfully:              │
│ {                                                        │
│   feature: "soulmate-trial-grid",                       │
│   variant: "grid"                                       │
│ }                                                        │
└─────────────────────────────────────────────────────────┘
```

### 📊 Когда КОНКРЕТНО

**✅ Impression отправляется:** Когда пользователь доходит до экрана "email" (19-й экран воронки)

**⏰ Timing:** ~120ms после перехода на `/soulmate/email`

**🔧 Код:** 
- **Файл:** `src/components/funnel/FunnelRuntime.tsx` (строки 136-150)
- **Функция:** `sendUnleashImpression()` из `src/lib/funnel/unleash/sendImpression.ts`

**📍 Условие отправки:**
```typescript
// В FunnelRuntime.tsx
const currentScreenFlags = useMemo(() => {
  const flags = new Set<string>();
  
  // Сканирует email.variants (пусто)
  // ...
  
  // Сканирует email.navigation.rules
  currentScreen.navigation?.rules?.forEach((rule) => {
    rule.conditions.forEach((condition) => {
      if (condition.conditionType === "unleash" && condition.unleashFlag) {
        flags.add(condition.unleashFlag); // ← "soulmate-trial-grid"
      }
    });
  });
  
  return Array.from(flags); // ["soulmate-trial-grid"]
}, [currentScreen]);

useEffect(() => {
  if (currentScreenFlags.length === 0) return;
  
  currentScreenFlags.forEach((flag) => {
    const variant = activeVariants[flag]; // "grid"
    sendUnleashImpression(flag, variant); // ← ОТПРАВКА
  });
}, [currentScreenFlags, activeVariants]);
```

### 🔍 Как проверить в браузере

```javascript
// 1. Пройти всю воронку до экрана email: /soulmate/email
// 2. Открыть DevTools → Console
// 3. Увидеть:
[Unleash Impression] ✅ Sent successfully: {
  feature: "soulmate-trial-grid",
  variant: "grid"  // или "coupon"
}

// 4. DevTools → Network → Фильтр "collect"
POST /g/collect?...&en=experiment_impression
  &ep.feature=soulmate-trial-grid
  &ep.treatment=grid

// 5. DevTools → Application → Session Storage
// Должно быть 2 ключа:
unleash_impression_soulmate-onboarding-image_v1: "true"
unleash_impression_soulmate-trial-grid_grid: "true"
```

---

## 📊 Сравнительная таблица

| Аспект | soulmate-onboarding-image | soulmate-trial-grid |
|--------|---------------------------|---------------------|
| **Экран** | `onboarding` (1-й экран) | `email` (19-й экран) |
| **Позиция в JSON** | `variants` | `navigation.rules` |
| **Что тестирует** | Картинка/видео на первом экране | Навигация после email |
| **Варианты** | v0, v1, v2 | coupon, grid |
| **Когда отправляется** | Сразу при входе в воронку | При достижении email экрана |
| **Timing** | T+420ms после загрузки | T+120ms после перехода на email |
| **URL** | `/soulmate/onboarding` | `/soulmate/email` |

---

## 🎯 Финальная timeline для полной воронки

```
T+0ms      Пользователь открывает /soulmate/onboarding
           │
T+420ms    ✅ IMPRESSION #1: soulmate-onboarding-image → v1
           │
T+5min     Пользователь проходит всю воронку
           │  (gender, partner-gender, analysis-target, partner-age,
           │   partner-ethnicity, partner-eye-color, partner-hair-length,
           │   burnout-support, burnout-result, birthdate,
           │   nature-archetype, love-priority, love-priority-result,
           │   relationship-block, qualities, qualities-result,
           │   progress, progress-result)
           │
T+5min     Пользователь доходит до /soulmate/email
           │
T+5min     ✅ IMPRESSION #2: soulmate-trial-grid → grid
   +120ms  │
           │
T+5min     Пользователь вводит email и нажимает Continue
   +1min   │
           │
           └─ Переход на trial-choice (если variant = "grid")
              ИЛИ
              Переход на coupon (если variant = "coupon")
```

---

## 📝 Ключевые моменты

### 1. Оба флага загружаются ЗАРАНЕЕ

```
FunnelUnleashWrapper сканирует ВСЮ воронку при загрузке
→ Находит оба флага сразу:
  • soulmate-onboarding-image
  • soulmate-trial-grid
→ Unleash SDK загружает варианты для ОБОИХ флагов
→ Варианты сохраняются в activeVariants
```

**Результат:** Быстрый переход между экранами (флаги уже загружены).

### 2. Impression отправляются ПОСЛЕДОВАТЕЛЬНО

```
Экран onboarding → impression для soulmate-onboarding-image
Экран email      → impression для soulmate-trial-grid
```

**Результат:** Точная аналитика - события отправляются только когда пользователь РЕАЛЬНО видит экран.

### 3. Защита от дубликатов работает

```
sessionStorage хранит:
{
  "unleash_impression_soulmate-onboarding-image_v1": "true",
  "unleash_impression_soulmate-trial-grid_grid": "true"
}
```

**Результат:** Даже если пользователь вернется назад или перезагрузит страницу, события НЕ отправятся повторно.

---

## 🐛 Отладка

### Проверка отправки первого теста

```bash
# 1. Открыть /soulmate/onboarding
# 2. В консоли должно появиться:
[Unleash Impression] ✅ Sent successfully: {
  feature: "soulmate-onboarding-image",
  variant: "v1"
}

# 3. В Network tab:
POST /g/collect?...
  &ep.feature=soulmate-onboarding-image
  &ep.treatment=v1
```

### Проверка отправки второго теста

```bash
# 1. Пройти до /soulmate/email
# 2. В консоли должно появиться:
[Unleash Impression] ✅ Sent successfully: {
  feature: "soulmate-trial-grid",
  variant: "grid"
}

# 3. В Network tab:
POST /g/collect?...
  &ep.feature=soulmate-trial-grid
  &ep.treatment=grid
```

### Проверка что оба события отправлены

```javascript
// В консоли браузера:
Object.keys(sessionStorage)
  .filter(key => key.startsWith("unleash_impression_"))
  .forEach(key => console.log(key, sessionStorage.getItem(key)));

// Вывод (если пользователь дошел до email):
// unleash_impression_soulmate-onboarding-image_v1 "true"
// unleash_impression_soulmate-trial-grid_grid "true"
```

---

## ✅ Итоговый ответ

### Когда отправляется `soulmate-onboarding-image`?

**🎯 Сразу при входе в воронку на первый экран "onboarding"**
- URL: `/soulmate/onboarding`
- Timing: ~420ms после загрузки страницы
- Экран: 1-й из ~20 экранов воронки

### Когда отправляется `soulmate-trial-grid`?

**🎯 Когда пользователь доходит до экрана "email" (почти в конце воронки)**
- URL: `/soulmate/email`
- Timing: ~120ms после перехода на экран
- Экран: 19-й из ~20 экранов воронки

### Код отправки (для обоих)

**Файл:** `src/components/funnel/FunnelRuntime.tsx`

**Строки:** 136-150

```typescript
useEffect(() => {
  if (currentScreenFlags.length === 0) return;
  
  currentScreenFlags.forEach((flag) => {
    const variant = activeVariants[flag];
    sendUnleashImpression(flag, variant); // ← ЗДЕСЬ
  });
}, [currentScreenFlags, activeVariants]);
```

**Функция:** `src/lib/funnel/unleash/sendImpression.ts`

```typescript
export function sendUnleashImpression(flag: string, variant: string | undefined) {
  // Проверки...
  
  window.gtag("event", "experiment_impression", {
    app_name: "witlab-funnel",
    feature: flag,
    treatment: variant,
  });
  
  sessionStorage.setItem(`unleash_impression_${flag}_${variant}`, "true");
}
```
