# ⚡ Быстрая справка: AB-тесты Soulmate

## 🧪 Два AB-теста

### 1️⃣ `soulmate-onboarding-image`

```
┌──────────────────────────────────────────┐
│ Экран:  onboarding (1-й экран)           │
│ URL:    /soulmate/onboarding             │
│ Когда:  Сразу при входе в воронку        │
│ Timing: ~420ms после загрузки            │
│                                          │
│ Тестирует:                               │
│ • v0 = дефолтное изображение             │
│ • v1 = альтернативное изображение (PNG)  │
│ • v2 = видео (MP4)                       │
│                                          │
│ JSON: variants блок                      │
└──────────────────────────────────────────┘
           │
           ▼ GA impression событие
           
window.gtag("event", "experiment_impression", {
  feature: "soulmate-onboarding-image",
  treatment: "v1"
});
```

### 2️⃣ `soulmate-trial-grid`

```
┌──────────────────────────────────────────┐
│ Экран:  email (19-й экран)               │
│ URL:    /soulmate/email                  │
│ Когда:  При достижении email экрана      │
│ Timing: ~120ms после перехода            │
│                                          │
│ Тестирует:                               │
│ • coupon = переход на экран с купоном    │
│ • grid   = переход на выбор тарифов      │
│                                          │
│ JSON: navigation.rules блок              │
└──────────────────────────────────────────┘
           │
           ▼ GA impression событие
           
window.gtag("event", "experiment_impression", {
  feature: "soulmate-trial-grid",
  treatment: "grid"
});
```

---

## 📍 Где в коде

```typescript
// src/components/funnel/FunnelRuntime.tsx (строки 103-150)

// Определяем флаги текущего экрана
const currentScreenFlags = useMemo(() => {
  const flags = new Set<string>();
  
  // Из variants
  currentScreen.variants?.forEach((variant) => {
    if (condition.unleashFlag) flags.add(condition.unleashFlag);
  });
  
  // Из navigation.rules
  currentScreen.navigation?.rules?.forEach((rule) => {
    if (condition.unleashFlag) flags.add(condition.unleashFlag);
  });
  
  return Array.from(flags);
}, [currentScreen]);

// Отправляем impression когда экран виден
useEffect(() => {
  currentScreenFlags.forEach((flag) => {
    const variant = activeVariants[flag];
    sendUnleashImpression(flag, variant); // ← ОТПРАВКА
  });
}, [currentScreenFlags, activeVariants]);
```

---

## ⏱️ Timeline полной воронки

```
┌─────────────────────────────────────────────────────────┐
│ T+0      Открытие /soulmate/onboarding                  │
├─────────────────────────────────────────────────────────┤
│ T+420ms  ✅ IMPRESSION #1                               │
│          feature: soulmate-onboarding-image             │
│          treatment: v1                                  │
└─────────────────────────────────────────────────────────┘
                        │
                        │ Пользователь проходит 18 экранов
                        ▼
┌─────────────────────────────────────────────────────────┐
│ T+5min   Достижение /soulmate/email                     │
├─────────────────────────────────────────────────────────┤
│ T+5m     ✅ IMPRESSION #2                               │
│ +120ms   feature: soulmate-trial-grid                   │
│          treatment: grid                                │
└─────────────────────────────────────────────────────────┘
```

---

## 🔍 Быстрая проверка

### Console (Development mode)

```javascript
// При загрузке onboarding экрана:
[Unleash Impression] ✅ Sent successfully:
{ feature: "soulmate-onboarding-image", variant: "v1" }

// При достижении email экрана:
[Unleash Impression] ✅ Sent successfully:
{ feature: "soulmate-trial-grid", variant: "grid" }
```

### Network Tab

```
POST /g/collect?...
  &en=experiment_impression
  &ep.feature=soulmate-onboarding-image
  &ep.treatment=v1

POST /g/collect?...
  &en=experiment_impression
  &ep.feature=soulmate-trial-grid
  &ep.treatment=grid
```

### Session Storage

```javascript
sessionStorage = {
  "unleash_impression_soulmate-onboarding-image_v1": "true",
  "unleash_impression_soulmate-trial-grid_grid": "true"
}
```

---

## 📊 Сравнение

|  | Test #1 | Test #2 |
|--|---------|---------|
| **Флаг** | `soulmate-onboarding-image` | `soulmate-trial-grid` |
| **Экран** | `onboarding` (1-й) | `email` (19-й) |
| **URL** | `/soulmate/onboarding` | `/soulmate/email` |
| **В JSON** | `variants` | `navigation.rules` |
| **Тестирует** | Медиа-контент | Навигацию |
| **Когда** | При входе в воронку | Почти в конце воронки |

---

## ✅ Главное

1. **Оба флага загружаются сразу** (preload) для быстрых переходов
2. **Impression отправляются последовательно** - только когда пользователь видит экран
3. **Защита от дубликатов** через sessionStorage работает автоматически
4. **Один и тот же код** отправляет события для обоих тестов

---

## 📚 Детальная документация

- `SOULMATE_AB_TESTS_TIMELINE.md` - полный анализ с диаграммами
- `GA_AB_TEST_ANALYSIS.md` - техническая документация
- `GA_AB_TEST_EXAMPLES.md` - примеры и сценарии
