# 🧪 AB Testing с Unleash в Воронках Полное руководство по интеграции AB тестов через Unleash feature flags в систему воронок. ## 📋 Содержание - [Настройка](#настройка) - [Примеры использования](#примеры-использования) - [API Reference](#api-reference) - [Архитектура](#архитектура) ## 🔧 Настройка ### 1. Environment Variables Добавьте в `.env.local`: ```bash NEXT_PUBLIC_UNLEASH_URL=https://your-unleash-instance.com/api/frontend NEXT_PUBLIC_UNLEASH_CLIENT_KEY=your-client-key ``` **Важно:** Если переменные не установлены, AB тесты будут отключены автоматически. ### 2. Настройка Unleash Dashboard 1. Создайте feature flag в Unleash (например, `trial-button-test`) 2. Добавьте варианты (v0, v1, v2, etc.) 3. Настройте stickiness на `sessionId` для консистентности 4. Добавьте gradual rollout strategy ## 💡 Примеры использования ### Пример 1: AB тест текста кнопки **Сценарий:** Тестируем разные тексты кнопки оплаты ```json { "id": "payment-screen", "template": "trialPayment", "bottomActionButton": { "text": "Continue" }, "variants": [ { "conditions": [ { "screenId": "payment-screen", "conditionType": "unleash", "unleashFlag": "trial-button-test", "unleashVariants": ["v1"], "operator": "includesAny" } ], "overrides": { "bottomActionButton": { "text": "Start 3-Day Trial" } } }, { "conditions": [ { "screenId": "payment-screen", "conditionType": "unleash", "unleashFlag": "trial-button-test", "unleashVariants": ["v2"], "operator": "includesAny" } ], "overrides": { "bottomActionButton": { "text": "Get My Reading Now" } } } ] } ``` **Результат:** - v0 (контроль): "Continue" - v1: "Start 3-Day Trial" - v2: "Get My Reading Now" ### Пример 2: AB тест навигации **Сценарий:** Тестируем короткий vs длинный onboarding ```json { "id": "gender-select", "template": "list", "navigation": { "defaultNextScreenId": "birthdate", "rules": [ { "conditions": [ { "screenId": "gender-select", "conditionType": "unleash", "unleashFlag": "onboarding-flow-test", "unleashVariants": ["short"], "operator": "equals" } ], "nextScreenId": "payment" }, { "conditions": [ { "screenId": "gender-select", "conditionType": "unleash", "unleashFlag": "onboarding-flow-test", "unleashVariants": ["long"], "operator": "equals" } ], "nextScreenId": "relationship-status" } ] } } ``` **Результат:** - v0/default: gender → birthdate - short: gender → payment (пропускаем шаги) - long: gender → relationship-status → ... → payment ### Пример 3: Комбинированные условия **Сценарий:** AB тест только для женской аудитории ```json { "variants": [ { "conditions": [ { "screenId": "gender", "conditionType": "options", "optionIds": ["female"], "operator": "includesAny" }, { "screenId": "payment", "conditionType": "unleash", "unleashFlag": "female-specific-test", "unleashVariants": ["v1"], "operator": "equals" } ], "overrides": { "title": { "text": "Special offer for you! ✨" } } } ] } ``` ## 📚 API Reference ### NavigationConditionDefinition ```typescript interface NavigationConditionDefinition { screenId: string; conditionType?: "options" | "values" | "unleash"; operator?: "includesAny" | "includesAll" | "includesExactly" | "equals"; // Для Unleash AB тестов unleashFlag?: string; unleashVariants?: string[]; // Для других типов optionIds?: string[]; values?: string[]; } ``` ### Операторы | Оператор | Описание | Пример | |----------|----------|--------| | `includesAny` | Хотя бы один вариант совпадает | `["v1", "v2"]` → true если v1 ИЛИ v2 | | `includesAll` | Все варианты совпадают | `["v1"]` → true если v1 (для одного = includesAny) | | `includesExactly` | Только указанные варианты | Редко используется | | `equals` | Точное совпадение | `["v1"]` → true только если v1 | ### Типы условий | Тип | Использование | Пример | |-----|---------------|--------| | `options` | List экраны | `{ conditionType: "options", optionIds: ["male"] }` | | `values` | Зодиак, возраст | `{ conditionType: "values", values: ["aries", "leo"] }` | | `unleash` | AB тесты | `{ conditionType: "unleash", unleashFlag: "test-1" }` | ## 🏗 Архитектура ### Компоненты ``` UnleashProvider (от @unleash/proxy-client-react) └── FunnelUnleashWrapper (собирает все флаги из воронки) └── UnleashContextProvider (предоставляет активные варианты) └── FunnelRuntime (использует варианты для navigation/variants) ``` ### Поток данных 1. **FunnelUnleashWrapper** сканирует все экраны воронки 2. Находит все `unleashFlag` в conditions 3. Получает варианты для всех флагов через `useVariant` 4. Передает `{ flagName: variant }` в **UnleashContextProvider** 5. **FunnelRuntime** использует `unleashChecker` для проверки условий 6. **navigation.ts** и **variants.ts** вызывают `unleashChecker` при проверке ### Файловая структура ``` src/ ├── lib/funnel/ │ ├── unleash/ │ │ ├── UnleashProvider.tsx # Wrapper для Unleash SDK │ │ ├── UnleashContext.tsx # Context с активными вариантами │ │ ├── useUnleash.ts # Hook для получения вариантов │ │ └── index.ts │ ├── navigation.ts # Поддержка unleash в условиях │ ├── variants.ts # Поддержка unleash в вариантах │ └── types.ts # Расширенные типы ├── components/ │ ├── funnel/ │ │ ├── FunnelUnleashWrapper.tsx # Сборщик флагов │ │ └── FunnelRuntime.tsx # Интеграция unleashChecker │ └── admin/builder/forms/ │ ├── UnleashConditionEditor.tsx # UI для настройки │ ├── ConditionTypeSelector.tsx # Выбор типа │ └── variants/ │ └── VariantConditionEditor.tsx # Интеграция в существующий UI ``` ## 🎯 Best Practices ### 1. Naming Convention ```bash # Формат: [page]-[element]-[description] trial-button-text onboarding-flow-length payment-copy-variant ``` ### 2. Variants Naming ```bash # Всегда используйте v0 как контроль v0 - контрольная группа (baseline) v1 - вариант 1 v2 - вариант 2 ``` ### 3. Stickiness **Всегда используйте `sessionId` для stickiness** в Unleash: - Обеспечивает консистентность для анонимных пользователей - Пользователь видит одинаковый вариант на всех экранах - Не требует авторизации ### 4. Rollout Strategy ```bash # Начните с малого Week 1: 10% traffic → v1 Week 2: 50% traffic → v1 Week 3: 100% traffic → v1 (если winner) ``` ## 🔍 Debugging ### Development Mode В development режиме в консоли будут логи: ```bash [Unleash] Flag "trial-button-test" = v1 [Unleash] Active variants: { "trial-button-test": "v1", "onboarding-flow": "short" } ``` ### Query Parameters (только dev) ```bash # Переопределить вариант флага ?trial-button-test=v2 # Комбинировать несколько ?trial-button-test=v1&onboarding-flow=short ``` ### Admin Preview В админке конструктора: 1. Экраны с AB тестами помечены значком 🧪 2. В превью можно переключать варианты 3. Validation показывает некорректные флаги ## ⚠️ Troubleshooting ### Флаг не работает **Проверьте:** 1. ✅ Environment variables установлены 2. ✅ Флаг создан в Unleash Dashboard 3. ✅ Флаг включен (enabled) 4. ✅ Правильно указано `unleashFlag` в JSON 5. ✅ Варианты существуют в Unleash ### Всегда показывается контроль **Причины:** - Rollout = 0% (увеличьте в Unleash) - Неправильный stickiness (используйте sessionId) - Constraints блокируют пользователя ### Ошибка в консоли ```bash Cannot find module '@/lib/funnel/unleash' ``` **Решение:** Проект не собран. Выполните `npm run dev` ## 📊 Analytics Integration Unleash автоматически отправляет impression events: ```typescript window.gtag?.("event", "experiment_impression", { app_name: "witlab-funnel", feature: "trial-button-test", treatment: "v1" }); ``` Интегрируется с: - ✅ Google Analytics - ✅ Google Tag Manager - ✅ Yandex Metrika (через funnel meta) ## 🚀 Deployment ### Перед выкаткой ```bash # 1. Проверьте сборку npm run build # 2. Проверьте все флаги в Unleash # 3. Убедитесь что rollout = 0% для новых тестов # 4. Deploy ``` ### После выкатки ```bash # 1. Проверьте метрики через 1 час # 2. Постепенно увеличивайте rollout # 3. Анализируйте результаты через 1-2 недели # 4. Выберите winner и удалите проигравшие варианты ``` ## 📞 Support **Вопросы?** Проверьте: 1. Эту документацию 2. Примеры в `/public/funnels/` 3. Код в `/src/lib/funnel/unleash/` **Нашли баг?** Создайте issue с: - Название флага - JSON конфигурация - Ожидаемое vs фактическое поведение