15 KiB
15 KiB
✅ AB Testing Integration - Полная реализация
🎯 Задача
Интегрировать Unleash feature flags в систему воронок для проведения AB тестирования:
- Возможность тестировать варианты экранов
- Возможность тестировать разные пути навигации
- UI в админке для настройки AB тестов
- Полная типизация TypeScript
✨ Что реализовано
1. 📦 Backend Infrastructure
Типы и интерфейсы (src/lib/funnel/types.ts)
// Расширен NavigationConditionDefinition
interface NavigationConditionDefinition {
conditionType?: "options" | "values" | "unleash"; // ← Новый тип
// Новые поля для Unleash
unleashFlag?: string; // Название флага
unleashVariants?: string[]; // Ожидаемые варианты
}
Поддерживаемые операторы:
includesAny- хотя бы один вариант совпадаетincludesAll- все варианты совпадаютincludesExactly- только указанные вариантыequals- точное совпадение
Логика проверки условий
src/lib/funnel/navigation.ts:
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:
export function resolveScreenVariant<T>(
screen: T,
answers: FunnelAnswers,
allScreens?: ScreenDefinition[],
unleashChecker?: UnleashChecker // ← Новый параметр
): T {
// Проверяет варианты с учетом Unleash условий
}
2. 🔌 Unleash SDK Integration
Provider (src/lib/funnel/unleash/UnleashProvider.tsx)
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 <FlagProvider config={config}>{children}</FlagProvider>;
}
Context (src/lib/funnel/unleash/UnleashContext.tsx)
export function UnleashContextProvider({
children,
activeVariants // { "flag-name": "v1", ... }
}) {
const checkVariant = (flag, expectedVariants, operator) => {
// Проверяет соответствие текущего варианта ожидаемым
};
return (
<UnleashContext.Provider value={{ activeVariants, checkVariant }}>
{children}
</UnleashContext.Provider>
);
}
Wrapper (src/components/funnel/FunnelUnleashWrapper.tsx)
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)
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)
export function ConditionTypeSelector({ condition, onChange }) {
return (
<select value={conditionType} onChange={...}>
<option value="options">Выбранные опции (list экраны)</option>
<option value="values">Значения (зодиак, возраст, email)</option>
<option value="unleash">AB тест (Unleash)</option>
</select>
);
}
Редактор Unleash условий (UnleashConditionEditor.tsx)
export function UnleashConditionEditor({ condition, onChange }) {
return (
<>
{/* Название флага */}
<Input
value={unleashFlag}
placeholder="trial-button-test"
onChange={handleFlagChange}
/>
{/* Оператор проверки */}
<select value={operator} onChange={handleOperatorChange}>
<option value="includesAny">Любой из вариантов (OR)</option>
<option value="equals">Равен (один вариант)</option>
</select>
{/* Ожидаемые варианты */}
<Input
value={unleashVariants.join(", ")}
placeholder="v1, v2, v3"
onChange={handleVariantsChange}
/>
</>
);
}
Интеграция в VariantConditionEditor
export function VariantConditionEditor({ condition, allScreens, onChange }) {
const conditionType = condition.conditionType ?? "options";
const isUnleashCondition = conditionType === "unleash";
return (
<>
<ConditionTypeSelector
condition={condition}
onChange={handleConditionTypeChange}
/>
{isUnleashCondition ? (
<UnleashConditionEditor condition={condition} onChange={onChange} />
) : (
// Существующая логика для 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)
🚀 Использование
В админке
- Откройте экран для редактирования
- Перейдите в "Вариативность" → Добавить вариант
- В условиях выберите "AB тест (Unleash)"
- Укажите флаг и варианты
- Настройте overrides
- Сохраните
В JSON
{
"variants": [
{
"conditions": [
{
"screenId": "payment",
"conditionType": "unleash",
"unleashFlag": "button-test",
"unleashVariants": ["v1"],
"operator": "equals"
}
],
"overrides": {
"bottomActionButton": {
"text": "New Button Text"
}
}
}
]
}
Environment Setup
# .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
✅ Проверка
Сборка
✓ npm run build
✓ No TypeScript errors
✓ No ESLint errors
✓ All pages compiled successfully
Тестирование
# 1. Запустите dev сервер
npm run dev
# 2. Откройте тестовую воронку
http://localhost:3000/ab-test-example/welcome
# 3. Проверьте разные варианты
# Откройте в нескольких вкладках - увидите разные версии
🎓 Примеры
Пример 1: Button Text AB Test
{
"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
{
"navigation": {
"defaultNextScreenId": "long-flow",
"rules": [{
"conditions": [{
"conditionType": "unleash",
"unleashFlag": "onboarding-length",
"unleashVariants": ["short"]
}],
"nextScreenId": "payment"
}]
}
}
Пример 3: Combined Conditions
{
"variants": [{
"conditions": [
{
"screenId": "gender",
"conditionType": "options",
"optionIds": ["female"]
},
{
"conditionType": "unleash",
"unleashFlag": "female-test",
"unleashVariants": ["v1"]
}
],
"overrides": {
"title": { "text": "Special for Women!" }
}
}]
}
🎯 Следующие шаги
- ✅ Настройте Unleash instance
- ✅ Создайте первые feature flags
- ✅ Добавьте AB тесты в существующие воронки
- ✅ Соберите метрики и выберите победителей
- ✅ Масштабируйте на все воронки
📞 Поддержка
- Документация: 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