From c7d6f049b040eb30f851e43636625ac49ca2e4c8 Mon Sep 17 00:00:00 2001 From: "dev.daminik00" Date: Thu, 23 Oct 2025 02:03:31 +0200 Subject: [PATCH] trial choice --- TRIAL_CHOICE_PAYMENT_INTEGRATION.md | 0 .../PAYMENT_TEMPLATE_VARIABLES.md | 0 docs/TRIAL_CHOICE_PAYMENT_INTEGRATION.md | 160 ------------------ 3 files changed, 160 deletions(-) delete mode 100644 TRIAL_CHOICE_PAYMENT_INTEGRATION.md rename PAYMENT_TEMPLATE_VARIABLES.md => docs/PAYMENT_TEMPLATE_VARIABLES.md (100%) diff --git a/TRIAL_CHOICE_PAYMENT_INTEGRATION.md b/TRIAL_CHOICE_PAYMENT_INTEGRATION.md deleted file mode 100644 index e69de29..0000000 diff --git a/PAYMENT_TEMPLATE_VARIABLES.md b/docs/PAYMENT_TEMPLATE_VARIABLES.md similarity index 100% rename from PAYMENT_TEMPLATE_VARIABLES.md rename to docs/PAYMENT_TEMPLATE_VARIABLES.md diff --git a/docs/TRIAL_CHOICE_PAYMENT_INTEGRATION.md b/docs/TRIAL_CHOICE_PAYMENT_INTEGRATION.md index 2cd37fb..e69de29 100644 --- a/docs/TRIAL_CHOICE_PAYMENT_INTEGRATION.md +++ b/docs/TRIAL_CHOICE_PAYMENT_INTEGRATION.md @@ -1,160 +0,0 @@ -# Trial Choice & Payment Integration - -## Проблемы которые решены - -### 1. Связь выбора Trial Choice → Payment -**Проблема**: Пользователь выбирает вариант триала на экране TrialChoice, но на экране Payment всегда отображался первый вариант. - -**Решение**: -- Создан `TrialVariantSelectionContext` для хранения выбранного `variantId` -- `TrialChoiceTemplate` сохраняет выбор пользователя в контекст -- `TrialPaymentTemplate` читает выбранный вариант из контекста и использует его вместо первого - -### 2. Общая логика загрузки и кеширование -**Проблема**: -- Каждый экран (TrialChoice, Payment) делал отдельный запрос к API -- TrialChoice показывал неправильные данные до завершения загрузки -- Payment уже имел loader, но TrialChoice — нет - -**Решение**: -- Создан `PaymentPlacementProvider` для кеширования загруженных placement данных -- `usePaymentPlacement` hook теперь использует кеш из контекста -- Повторные запросы к API не выполняются если данные уже загружены -- `TrialChoiceTemplate` показывает loader (как Payment) до загрузки данных - -## Архитектура - -### Контексты - -#### PaymentPlacementProvider -- **Путь**: `src/entities/session/payment/PaymentPlacementProvider.tsx` -- **Назначение**: Кеширует результаты `loadFunnelPaymentById` чтобы избежать повторных запросов -- **Ключ кеша**: `${funnelKey}:${paymentId}` -- **Состояние**: `{ placement, isLoading, error }` - -#### TrialVariantSelectionProvider -- **Путь**: `src/entities/session/payment/TrialVariantSelectionContext.tsx` -- **Назначение**: Хранит выбранный пользователем `variantId` для передачи между экранами -- **Состояние**: `{ selectedVariantId, setSelectedVariantId }` - -### Обновленные компоненты - -#### TrialChoiceTemplate -- **Изменения**: - - Добавлен loader (Spinner) до загрузки placement - - Сохраняет выбор в `TrialVariantSelectionContext` - - Использует `usePaymentPlacement` с кешированием - - Инициализирует локальный `selectedId` из `selectedVariantId` контекста - -#### TrialPaymentTemplate -- **Изменения**: - - Читает `selectedVariantId` из `TrialVariantSelectionContext` - - Использует выбранный вариант, если доступен: `placement?.variants?.find((v) => v.id === selectedVariantId)` - - Fallback на первый вариант если выбор отсутствует - - Использует `usePaymentPlacement` с кешированием - -#### SpecialOfferTemplate -- **Изменения**: Нет (специально) -- **Поведение**: Продолжает использовать первый вариант `placement?.variants?.[0]` -- **Причина**: Использует другой `paymentId` (`"main_secret_discount"`) и не должен зависеть от выбора Trial - -### usePaymentPlacement Hook -- **Изменения**: - - Теперь использует `PaymentPlacementContext` для получения/загрузки данных - - Упрощена логика: нет локального state, все в контексте - - Автоматически триггерит загрузку если данных нет - -### Layout Integration -- **Файл**: `src/app/[funnelId]/layout.tsx` -- **Изменения**: Обернут в два новых провайдера: - ```tsx - - - {children} - - - ``` - -## Потоки данных - -### Поток 1: Воронка С экраном Trial Choice -``` -1. User открывает Trial Choice - → PaymentPlacementProvider загружает "main" placement (если еще нет в кеше) - → TrialChoiceTemplate показывает loader - → После загрузки отображаются варианты - -2. User выбирает вариант (например, id="plan-123") - → setSelectedVariantId("plan-123") в TrialVariantSelectionContext - -3. User переходит на Payment - → PaymentPlacementProvider возвращает "main" placement из кеша (без запроса) - → TrialPaymentTemplate читает selectedVariantId="plan-123" - → Использует вариант с id="plan-123" вместо первого -``` - -### Поток 2: Воронка БЕЗ экрана Trial Choice -``` -1. User сразу открывает Payment - → PaymentPlacementProvider загружает "main" placement - → TrialPaymentTemplate показывает loader - → selectedVariantId === null - → Использует первый вариант (дефолт) -``` - -### Поток 3: Special Offer -``` -1. User открывает Special Offer - → PaymentPlacementProvider загружает "main_secret_discount" placement - → SpecialOfferTemplate показывает loader - → Всегда использует первый вариант (не зависит от Trial Choice) -``` - -## Тестирование - -### Сценарий 1: Trial Choice → Payment -1. Открыть воронку с Trial Choice -2. Дождаться загрузки вариантов -3. Выбрать второй вариант (не первый) -4. Нажать Continue -5. **Ожидается**: На Payment отображается выбранный (второй) вариант - -### Сценарий 2: Прямой переход на Payment -1. Открыть воронку без Trial Choice или перейти прямо на Payment -2. **Ожидается**: На Payment отображается первый вариант (дефолт) - -### Сценарий 3: Кеширование -1. Открыть Trial Choice → загрузка placement -2. Перейти на Payment -3. **Ожидается**: Payment загружается мгновенно (из кеша), без повторного API запроса - -### Сценарий 4: Special Offer -1. Открыть Special Offer -2. **Ожидается**: Всегда показывается первый вариант, независимо от выбора в Trial Choice - -## API изменения (Backend) - -### session.controller.ts -- **Изменения**: Добавлены `title` и `accent` поля в варианты -- **Поведение**: Возвращает все планы (не ограничивает до 4) -- **Дефолты**: `title` использует `["Basic", "Standard", "Popular", "Premium"]` с fallback `"Premium"` - -## Файлы созданы/изменены - -### Новые файлы -- `src/entities/session/payment/PaymentPlacementProvider.tsx` -- `src/entities/session/payment/TrialVariantSelectionContext.tsx` -- `src/entities/session/payment/index.ts` - -### Измененные файлы -- `src/hooks/payment/usePaymentPlacement.ts` - использует контекст вместо локального state -- `src/components/funnel/templates/TrialChoiceTemplate/TrialChoiceTemplate.tsx` - loader + сохранение выбора -- `src/components/funnel/templates/TrialPaymentTemplate/TrialPaymentTemplate.tsx` - использует выбранный вариант -- `src/app/[funnelId]/layout.tsx` - обернут в провайдеры - -## Будущие улучшения - -1. **Персистентность**: Сохранять выбор в localStorage/sessionStorage для сохранения при перезагрузке -2. **Аналитика**: Трекинг выбора вариантов для A/B тестирования -3. **Валидация**: Проверять что выбранный variant все еще существует в placement -4. **Типизация**: Усилить типы для garantie что только валидные paymentId используются