# ✅ AB Testing Integration - Полная реализация ## 🎯 Задача Интегрировать Unleash feature flags в систему воронок для проведения AB тестирования: - Возможность тестировать варианты экранов - Возможность тестировать разные пути навигации - UI в админке для настройки AB тестов - Полная типизация TypeScript ## ✨ Что реализовано ### 1. 📦 Backend Infrastructure #### Типы и интерфейсы (`src/lib/funnel/types.ts`) ```typescript // Расширен NavigationConditionDefinition interface NavigationConditionDefinition { conditionType?: "options" | "values" | "unleash"; // ← Новый тип // Новые поля для Unleash unleashFlag?: string; // Название флага unleashVariants?: string[]; // Ожидаемые варианты } ``` **Поддерживаемые операторы:** - `includesAny` - хотя бы один вариант совпадает - `includesAll` - все варианты совпадают - `includesExactly` - только указанные варианты - `equals` - точное совпадение #### Логика проверки условий **`src/lib/funnel/navigation.ts`:** ```typescript export type UnleashChecker = ( flag: string, expectedVariants: string[], operator?: "includesAny" | "includesAll" | "includesExactly" | "equals" ) => boolean; function satisfiesCondition( condition: NavigationConditionDefinition, answers: FunnelAnswers, allScreens?: ScreenDefinition[], unleashChecker?: UnleashChecker // ← Новый параметр ): boolean { if (conditionType === "unleash") { return unleashChecker( condition.unleashFlag, condition.unleashVariants, operator ); } // ... остальная логика } ``` **`src/lib/funnel/variants.ts`:** ```typescript export function resolveScreenVariant( screen: T, answers: FunnelAnswers, allScreens?: ScreenDefinition[], unleashChecker?: UnleashChecker // ← Новый параметр ): T { // Проверяет варианты с учетом Unleash условий } ``` ### 2. 🔌 Unleash SDK Integration #### Provider (`src/lib/funnel/unleash/UnleashProvider.tsx`) ```typescript export function UnleashProvider({ children, userId, sessionId }) { // Инициализирует Unleash клиент // Если env переменные не заданы - graceful fallback const config = { url: process.env.NEXT_PUBLIC_UNLEASH_URL, clientKey: process.env.NEXT_PUBLIC_UNLEASH_CLIENT_KEY, context: { userId, sessionId: sessionId || userId || "anonymous", } }; return {children}; } ``` #### Context (`src/lib/funnel/unleash/UnleashContext.tsx`) ```typescript export function UnleashContextProvider({ children, activeVariants // { "flag-name": "v1", ... } }) { const checkVariant = (flag, expectedVariants, operator) => { // Проверяет соответствие текущего варианта ожидаемым }; return ( {children} ); } ``` #### Wrapper (`src/components/funnel/FunnelUnleashWrapper.tsx`) ```typescript export function FunnelUnleashWrapper({ funnel, children }) { // 1. Сканирует все экраны воронки // 2. Находит все unleashFlag в conditions (variants + navigation) // 3. Получает варианты для всех флагов через useVariant // 4. Передает activeVariants в UnleashContextProvider const allFlags = useMemo(() => { // Собирает unique флаги из всех условий }, [funnel.screens]); const activeVariants = useMemo(() => { // Получает текущие варианты для всех флагов }, [flagsReady, flagVariants]); } ``` #### Runtime Integration (`src/components/funnel/FunnelRuntime.tsx`) ```typescript export function FunnelRuntime({ funnel, initialScreenId }) { const { checkVariant } = useUnleashContext(); // Создаем unleashChecker для передачи в navigation/variants const unleashChecker: UnleashChecker = useCallback( (flag, expectedVariants, operator) => { return checkVariant(flag, expectedVariants, operator); }, [checkVariant] ); // Передаем во все функции проверки resolveScreenVariant(baseScreen, answers, funnel.screens, unleashChecker); resolveNextScreenId(currentScreen, answers, funnel.screens, unleashChecker); estimatePathLength(funnel, answers, unleashChecker); } ``` ### 3. 🎨 Admin UI Components #### Селектор типа условия (`ConditionTypeSelector.tsx`) ```typescript export function ConditionTypeSelector({ condition, onChange }) { return ( ); } ``` #### Редактор Unleash условий (`UnleashConditionEditor.tsx`) ```typescript export function UnleashConditionEditor({ condition, onChange }) { return ( <> {/* Название флага */} {/* Оператор проверки */} {/* Ожидаемые варианты */} ); } ``` #### Интеграция в VariantConditionEditor ```typescript export function VariantConditionEditor({ condition, allScreens, onChange }) { const conditionType = condition.conditionType ?? "options"; const isUnleashCondition = conditionType === "unleash"; return ( <> {isUnleashCondition ? ( ) : ( // Существующая логика для options/values )} ); } ``` ### 4. 📚 Документация - **AB_TESTING_GUIDE.md** - Полное руководство (200+ строк) - Настройка environment - Примеры использования - API Reference - Best Practices - Troubleshooting - **UNLEASH_SETUP.md** - Quick Start - Быстрый старт за 4 шага - Структура файлов - Примеры - Требования - **ab-test-example.json** - Тестовая воронка - 6 экранов с разными типами AB тестов - Button text testing - Content variant testing - Navigation testing - Combined conditions (gender + AB test) ## 🚀 Использование ### В админке 1. Откройте экран для редактирования 2. Перейдите в "Вариативность" → Добавить вариант 3. В условиях выберите "AB тест (Unleash)" 4. Укажите флаг и варианты 5. Настройте overrides 6. Сохраните ### В JSON ```json { "variants": [ { "conditions": [ { "screenId": "payment", "conditionType": "unleash", "unleashFlag": "button-test", "unleashVariants": ["v1"], "operator": "equals" } ], "overrides": { "bottomActionButton": { "text": "New Button Text" } } } ] } ``` ### Environment Setup ```bash # .env.local NEXT_PUBLIC_UNLEASH_URL=https://unleash.example.com/api/frontend NEXT_PUBLIC_UNLEASH_CLIENT_KEY=your-key ``` ## 📊 Возможности ### Что можно тестировать ✅ **Варианты экранов:** - Тексты (заголовки, подзаголовки, кнопки) - Контент (описания, иконки, блоки) - Любые поля через variants overrides ✅ **Навигация:** - Разные пути через воронку - Длинный vs короткий onboarding - A/B тест целых flow ✅ **Комбинированные условия:** - AB тест + пол пользователя - AB тест + возраст - AB тест + ответы на вопросы ### Архитектура ``` ┌─────────────────────────────────────┐ │ Unleash Dashboard │ │ (Feature Flags Config) │ └─────────────────┬───────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ UnleashProvider │ │ (@unleash/proxy-client-react) │ └─────────────────┬───────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ FunnelUnleashWrapper │ │ - Сканирует воронку │ │ - Собирает все флаги │ │ - Получает варианты │ └─────────────────┬───────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ UnleashContextProvider │ │ activeVariants: { │ │ "flag-1": "v1", │ │ "flag-2": "v2" │ │ } │ └─────────────────┬───────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ FunnelRuntime │ │ - unleashChecker: UnleashChecker │ │ - resolveScreenVariant(...) │ │ - resolveNextScreenId(...) │ └─────────────────┬───────────────────┘ │ ┌────────┴────────┐ ▼ ▼ ┌─────────┐ ┌─────────┐ │variants │ │navigation│ │.ts │ │.ts │ └─────────┘ └─────────┘ ``` ## 📁 Файлы ### Новые файлы (14) ``` src/lib/funnel/unleash/ ├── UnleashProvider.tsx ✨ Unleash SDK wrapper ├── UnleashContext.tsx ✨ React Context для вариантов ├── useUnleash.ts ✨ Hooks для работы с флагами └── index.ts ✨ Экспорты src/components/funnel/ └── FunnelUnleashWrapper.tsx ✨ Сборщик флагов из воронки src/components/admin/builder/forms/ ├── UnleashConditionEditor.tsx ✨ UI редактор AB тестов └── ConditionTypeSelector.tsx ✨ Селектор типа условия docs/ ├── AB_TESTING_GUIDE.md ✨ Полное руководство ├── UNLEASH_SETUP.md ✨ Quick start └── AB_TESTING_IMPLEMENTATION.md ✨ Этот файл public/funnels/ └── ab-test-example.json ✨ Тестовая воронка package.json ✏️ +@unleash/proxy-client-react ``` ### Модифицированные файлы (6) ``` src/lib/funnel/ ├── types.ts ✏️ +unleash поля в NavigationConditionDefinition ├── navigation.ts ✏️ +UnleashChecker support └── variants.ts ✏️ +UnleashChecker support src/components/ ├── funnel/FunnelRuntime.tsx ✏️ +unleashChecker integration └── admin/builder/forms/variants/ └── VariantConditionEditor.tsx ✏️ +Unleash UI src/app/[funnelId]/[screenId]/ └── page.tsx ✏️ +UnleashProvider wrapper ``` ## ✅ Проверка ### Сборка ```bash ✓ npm run build ✓ No TypeScript errors ✓ No ESLint errors ✓ All pages compiled successfully ``` ### Тестирование ```bash # 1. Запустите dev сервер npm run dev # 2. Откройте тестовую воронку http://localhost:3000/ab-test-example/welcome # 3. Проверьте разные варианты # Откройте в нескольких вкладках - увидите разные версии ``` ## 🎓 Примеры ### Пример 1: Button Text AB Test ```json { "id": "payment", "bottomActionButton": { "text": "Continue" }, "variants": [ { "conditions": [{ "conditionType": "unleash", "unleashFlag": "payment-button-test", "unleashVariants": ["variant-a"] }], "overrides": { "bottomActionButton": { "text": "Start Trial" } } } ] } ``` ### Пример 2: Navigation AB Test ```json { "navigation": { "defaultNextScreenId": "long-flow", "rules": [{ "conditions": [{ "conditionType": "unleash", "unleashFlag": "onboarding-length", "unleashVariants": ["short"] }], "nextScreenId": "payment" }] } } ``` ### Пример 3: Combined Conditions ```json { "variants": [{ "conditions": [ { "screenId": "gender", "conditionType": "options", "optionIds": ["female"] }, { "conditionType": "unleash", "unleashFlag": "female-test", "unleashVariants": ["v1"] } ], "overrides": { "title": { "text": "Special for Women!" } } }] } ``` ## 🎯 Следующие шаги 1. ✅ Настройте Unleash instance 2. ✅ Создайте первые feature flags 3. ✅ Добавьте AB тесты в существующие воронки 4. ✅ Соберите метрики и выберите победителей 5. ✅ Масштабируйте на все воронки ## 📞 Поддержка - **Документация:** AB_TESTING_GUIDE.md - **Quick Start:** UNLEASH_SETUP.md - **Примеры:** /public/funnels/ab-test-example.json - **Unleash Docs:** https://docs.getunleash.io/ --- **Статус:** ✅ Готово к production **Версия:** 1.0.0 **Дата:** 2025-01-20