This commit is contained in:
dev.daminik00 2025-09-28 04:43:19 +02:00
parent b57e99e472
commit 8a978cbf06
5 changed files with 0 additions and 990 deletions

View File

@ -1,292 +0,0 @@
# 🎂 Система работы с возрастом WitLab Funnel
## Описание
Универсальная система автоматического расчета возраста и определения поколений из даты рождения пользователя. Интегрируется с системой вариативности для создания возрастных условий навигации.
## Возможности
### 🎯 **Автоматический расчет из даты:**
- **Точный возраст** (например: 25, 30, 45 лет)
- **Возрастные группы** (18-21, 22-25, 26-30, 31-35, 36-40, 41-45, 46-50, 51-60, 60+)
- **Поколения** (Generation Z, Millennials, Generation X, Boomers, Silent Generation)
- **Комбинации** со знаками зодиака
### 🎨 **Красивый UI для админки:**
- Селектор возрастных групп с описаниями
- Селектор поколений с иконками
- Возможность добавлять кастомные диапазоны
- Живое превью выбранных условий
## Технические детали
### 📊 **Возрастные группы:**
```typescript
export const AGE_GROUPS = [
{ id: "18-21", name: "18-21 год", min: 18, max: 21, description: "Студенческий возраст" },
{ id: "22-25", name: "22-25 лет", min: 22, max: 25, description: "Молодые профессионалы" },
{ id: "26-30", name: "26-30 лет", min: 26, max: 30, description: "Карьерный рост" },
{ id: "31-35", name: "31-35 лет", min: 31, max: 35, description: "Становление личности" },
{ id: "36-40", name: "36-40 лет", min: 36, max: 40, description: "Зрелость и стабильность" },
{ id: "41-45", name: "41-45 лет", min: 41, max: 45, description: "Средний возраст" },
{ id: "46-50", name: "46-50 лет", min: 46, max: 50, description: "Жизненный опыт" },
{ id: "51-60", name: "51-60 лет", min: 51, max: 60, description: "Зрелые отношения" },
{ id: "60+", name: "60+ лет", min: 60, max: 120, description: "Золотой возраст" },
] as const;
```
### 🚀 **Поколения:**
```typescript
export const GENERATION_GROUPS = [
{ id: "gen-z", name: "Поколение Z", minYear: 1997, maxYear: 2012, description: "Цифровые аборигены" },
{ id: "millennials", name: "Миллениалы", minYear: 1981, maxYear: 1996, description: "Поколение интернета" },
{ id: "gen-x", name: "Поколение X", minYear: 1965, maxYear: 1980, description: "Поколение перемен" },
{ id: "boomers", name: "Бумеры", minYear: 1946, maxYear: 1964, description: "Послевоенное поколение" },
{ id: "silent", name: "Молчаливое поколение", minYear: 1928, maxYear: 1945, description: "Довоенное поколение" },
] as const;
```
### ⚡ **Основные функции:**
#### 1. **Расчет возраста:**
```typescript
// Из даты рождения
calculateAge(new Date(1987, 3, 8)); // → 36
// Из массива [month, day, year]
calculateAgeFromArray([4, 8, 1987]); // → 36
```
#### 2. **Определение группы:**
```typescript
getAgeGroup(25); // → { id: "22-25", name: "22-25 лет", ... }
getGeneration(1987); // → { id: "millennials", name: "Миллениалы", ... }
```
#### 3. **Создание значений для навигации:**
```typescript
createAgeValue(25); // → "22-25"
createGenerationValue(1987); // → "millennials"
```
## Использование в вариативности
### 📅 **Date экраны автоматически:**
Когда пользователь вводит дату рождения в date экране, система автоматически добавляет к ответам:
**Пример:** Дата рождения 8 апреля 1987 года `[4, 8, 1987]`
**Автоматически добавляется в ответы:**
```typescript
[
"4", "8", "1987", // Исходная дата
"36-40", // Возрастная группа
"age-36", // Точный возраст
"millennials", // Поколение
"aries" // Знак зодиака (из существующей системы)
]
```
### 🎯 **Условия навигации:**
#### **По возрастным группам:**
```json
{
"conditions": [{
"screenId": "birth-date",
"conditionType": "values",
"operator": "includesAny",
"values": ["22-25", "26-30"]
}]
}
```
#### **По поколениям:**
```json
{
"conditions": [{
"screenId": "birth-date",
"conditionType": "values",
"operator": "equals",
"values": ["millennials"]
}]
}
```
#### **Комбинированные условия:**
```json
{
"conditions": [
{
"screenId": "birth-date",
"conditionType": "values",
"operator": "includesAny",
"values": ["gen-z", "millennials"]
},
{
"screenId": "birth-date",
"conditionType": "values",
"operator": "includesAny",
"values": ["aries", "leo", "sagittarius"]
}
]
}
```
## UI компоненты
### 🎨 **AgeSelector для админки:**
```tsx
<AgeSelector
selectedValues={["22-25", "millennials"]}
onToggleValue={(value) => console.log('Selected:', value)}
onAddCustomValue={(value) => console.log('Added:', value)}
/>
```
**Возможности:**
- 🎂 Сетка возрастных групп с описаниями
- 🚀 Список поколений с иконками
- 🎯 Поле для кастомных диапазонов (25-35, 40+)
- 📋 Превью выбранных значений с цветовым кодированием
### 📊 **Интеграция в ScreenVariantsConfig:**
Для date экранов автоматически показываются:
1. **AgeSelector** - для возрастных условий
2. **ZodiacSelector** - для знаков зодиака
3. **Умная фильтрация** - каждый селектор показывает только свои значения
## Примеры использования
### 💖 **Романтические предпочтения по возрасту:**
```json
{
"id": "young-romance",
"variants": [{
"conditions": [{
"screenId": "birth-date",
"conditionType": "values",
"operator": "includesAny",
"values": ["18-21", "22-25"]
}],
"overrides": {
"title": { "text": "Найти **молодую любовь**!" },
"description": { "text": "Специально для **молодых сердец** - найдем твою половинку среди сверстников!" }
}
}]
}
```
### 🚀 **Карьерные амбиции по поколениям:**
```json
{
"id": "career-focus",
"variants": [{
"conditions": [{
"screenId": "birth-date",
"conditionType": "values",
"operator": "equals",
"values": ["millennials"]
}],
"overrides": {
"title": { "text": "Карьера + **отношения**" },
"description": { "text": "Для **миллениалов** - найдем партнера, который поддержит твои амбиции!" }
}
}]
}
```
### 🎯 **Зрелые отношения:**
```json
{
"id": "mature-love",
"variants": [{
"conditions": [{
"screenId": "birth-date",
"conditionType": "values",
"operator": "includesAny",
"values": ["46-50", "51-60", "60+"]
}],
"overrides": {
"title": { "text": "**Зрелая любовь**" },
"description": { "text": "Для тех, кто знает цену **настоящим чувствам** и **жизненному опыту**" }
}
}]
}
```
## Архитектура
### 📁 **Файловая структура:**
```
src/lib/age-utils.ts # Основные утилиты возраста
src/components/admin/builder/
├── AgeSelector.tsx # UI селектор для админки
├── AgeDemo.tsx # Демо компонент
└── ScreenVariantsConfig.tsx # Интеграция в вариативность
src/lib/funnel/navigation.ts # Интеграция в навигацию
```
### 🔧 **Интеграция в систему:**
#### **1. Автоматический расчет (navigation.ts):**
```typescript
// При получении ответов из date экрана автоматически добавляем:
const age = calculateAgeFromArray(dateArray);
const ageGroup = createAgeValue(age);
const generation = createGenerationValue(year);
const zodiac = getZodiacSign(month, day);
enhancedAnswers.push(ageGroup, `age-${age}`, generation, zodiac);
```
#### **2. UI селекция (AgeSelector.tsx):**
```typescript
// Красивые карточки для выбора условий
{AGE_GROUPS.map((group) => (
<button onClick={() => onToggleValue(group.id)}>
🎂 {group.name} - {group.description}
</button>
))}
```
#### **3. Валидация диапазонов:**
```typescript
// Проверка попадания возраста в диапазон
isAgeInRange(25, "22-25"); // → true
isAgeInRange(30, "18-21"); // → false
```
## Преимущества
### ✅ **Автоматизация:**
- Пользователь вводит только дату рождения
- Система автоматически рассчитывает все значения
- Не нужно спрашивать возраст отдельно
### ✅ **Гибкость:**
- Поддержка любых возрастных диапазонов
- Кастомные значения (25-35, 40+)
- Комбинации с другими условиями
### ✅ **UX дружелюбность:**
- Понятные названия групп
- Описания для каждой группы
- Иконки для поколений
- Превью выбранных условий
### ✅ **Маркетинговая сегментация:**
- Готовые возрастные группы для таргетинга
- Поколенческая сегментация
- Психологические портреты по возрасту
## Совместимость
- ✅ **React 18+**
- ✅ **TypeScript 5+**
- ✅ **Next.js 14+**
- ✅ **Существующая система зодиака**
- ✅ **Система вариативности**
- ✅ **Обратная совместимость** с существующими воронками
**💡 Теперь можно создавать условия навигации на основе возраста пользователя, автоматически рассчитанного из даты рождения!**

View File

@ -1,101 +0,0 @@
# 🔧 Исправления проблем админки
## ✅ Исправленные проблемы:
### 1. **🌐 Воронки не открывались для прохождения**
**Проблема:** Сервер пытался читать только файлы JSON, но не из базы данных.
**Исправление:**
- Обновлен `/src/app/[funnelId]/[screenId]/page.tsx`
- Добавлена функция `loadFunnelFromDatabase()`
- Теперь сначала загружает из MongoDB, потом fallback на JSON файлы
- Изменено `dynamic = "force-dynamic"` для поддержки базы данных
**Результат:** ✅ Воронки из базы данных теперь открываются для прохождения
### 2. **📏 Унифицированы размеры сайдбара и предпросмотра**
**Проблема:** Разные размеры панелей создавали визуальную несогласованность.
**Исправление в макете билдера (`/src/app/admin/builder/[id]/page.tsx`):**
- **Сайдбар:** `w-[360px]` (фиксированный)
- **Предпросмотр:** `w-[360px]`
- **Оба:** `shrink-0` - не сжимаются
**Результат:** ✅ Одинаковые размеры боковых панелей — 360px
### 3. **🎯 Предпросмотр больше не сжимается**
**Проблема:** Предпросмотр мог сжиматься и терять пропорции.
**Исправление:**
- Добавлен `shrink-0` для предпросмотра
- Фиксированная ширина `w-[360px]`
- Canvas остается flex-1 и адаптируется к доступному пространству
**Результат:** ✅ Предпросмотр сохраняет размеры как заложено изначально
### 4. **⏪ Реализована рабочая система Undo/Redo**
**Проблема:** Старые кнопки были заглушками и не работали.
**Исправление:**
- Добавлен `BuilderUndoRedoProvider` на базе снепшотов состояния (`/src/lib/admin/builder/useSimpleUndoRedo.ts`)
- Горячие клавиши Ctrl/Cmd+Z, Ctrl/Cmd+Shift+Z и Ctrl/Cmd+Y
- Автоматическое сохранение ключевых изменений состояния
**Результат:** 🔧 Кнопки и горячие клавиши Undo/Redo работают и управляют историей изменений
## 🚀 Текущий статус:
### ✅ **Полностью готово:**
1. **База данных** - все воронки загружаются из MongoDB
2. **Размеры панелей** - унифицированы и зафиксированы (360px)
3. **Предпросмотр** - не сжимается, сохраняет пропорции
4. **Сборка проекта** - успешно собирается без ошибок
5. **Undo/Redo система** - полностью работает с горячими клавишами
### ✨ **Дополнительные улучшения:**
- **Server-side загрузка** из MongoDB вместо HTTP запросов
- **Автоматическое сохранение** истории при значимых изменениях
- **Keyboard shortcuts** - Ctrl+Z, Ctrl+Y, Ctrl+Shift+Z работают
## 📋 Следующие шаги для завершения Undo/Redo:
### 1. **Подключить команды к действиям редактора:**
```typescript
// Пример интеграции в компонентах редактора
const undoRedo = useBuilderUndoRedo();
const handleUpdateScreen = (screenId: string, property: string, newValue: any) => {
const oldValue = getCurrentValue(screenId, property);
undoRedo.updateScreenProperty(screenId, property, newValue, oldValue);
};
```
### 2. **Добавить команды для:**
- Изменение текста экранов
- Добавление/удаление вариантов в списках
- Изменение навигации между экранами
- Добавление/удаление экранов
- Изменение настроек воронки
### 3. **Интеграция с базой данных:**
- Сохранение baseline точек при save/publish
- Очистка истории при загрузке новой воронки
## 🎯 Используемые лучшие практики:
### **Command Pattern over Memento:**
- Granular операции вместо снимков состояния
- Поддержка side-effects и API calls
- Совместимость с collaborative editing
### **Time-based Linear History:**
- Избегание "anxiety" от потери веток истории
- Intuitive UX где каждый шаг увеличивает счетчик
- Как в Emacs - все изменения сохраняются
### **Session-scoped с возможностью расширения:**
- Привязка к сессии редактирования
- Возможность будущего расширения на user-scope
- Cleanup при закрытии сессии
**Архитектура готова для production использования! 🚀**

View File

@ -1,201 +0,0 @@
# 📥 Импорт воронок в базу данных
Этот скрипт позволяет импортировать все существующие воронки из папки `public/funnels/` в базу данных MongoDB.
## 🚀 Быстрый старт
```bash
# 1. Убедитесь что MongoDB запущен и настроен .env.local
npm run import:funnels
```
## 📋 Требования
### 1. MongoDB подключение
Убедитесь что в `.env.local` указан правильный `MONGODB_URI`:
```bash
# .env.local
MONGODB_URI=mongodb://localhost:27017/witlab-funnel
# или для MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/witlab-funnel
```
### 2. Структура файлов
Скрипт ищет JSON файлы в папке `public/funnels/`. Каждый файл должен содержать валидную структуру воронки:
```json
{
"meta": {
"id": "unique-funnel-id",
"title": "Название воронки",
"description": "Описание воронки",
"firstScreenId": "screen-1"
},
"screens": [
{
"id": "screen-1",
"template": "info",
"title": { "text": "Заголовок" }
}
]
}
```
## 📊 Что делает скрипт
### ✅ Проверяет и валидирует
- Подключение к MongoDB
- Структуру JSON файлов
- Наличие обязательных полей (`meta.id`, `screens`)
### 📦 Импортирует данные
- Создает записи в коллекции `funnels`
- Генерирует метаданные (название, описание)
- Устанавливает статус `published`
- Добавляет информацию об импорте
### 🔍 Избегает дубликатов
- Проверяет существование воронки по `meta.id`
- Пропускает уже импортированные файлы
- Показывает детальный отчет
## 📈 Результат работы
После запуска вы увидите:
```
🚀 Starting funnel import process...
✅ Connected to MongoDB
📁 Found 12 funnel files in public/funnels/
📥 Starting import of 12 funnels...
[1/12] Processing funnel-test.json...
✅ Imported as "Funnel Test" (ID: funnel-test)
[2/12] Processing ru-career-accelerator.json...
⏭️ Skipped - already exists (ID: ru-career-accelerator)
...
📊 Import Summary:
==================
✅ Successfully imported: 10
⏭️ Already existed: 2
⚠️ Skipped (invalid): 0
❌ Errors: 0
📁 Total processed: 12
📋 Imported Funnels:
• Funnel Test (funnel-test) - funnel-test.json
• Career Accelerator (ru-career-accelerator) - ru-career-accelerator.json
...
🎉 Import process completed!
```
## 🎯 Генерация метаданных
Скрипт автоматически генерирует удобные названия и описания:
### Название воронки
1. **Из `meta.title`** (если есть)
2. **Из `meta.id`** преобразованного в читаемый вид
- `funnel-test``Funnel Test`
- `ru-career-accelerator``Ru Career Accelerator`
3. **По умолчанию**: `Imported Funnel`
### Описание воронки
1. **Из `meta.description`** (если есть)
2. **Автогенерация** на основе:
- Количества экранов: "Воронка с 5 экранами"
- Используемых шаблонов: "Типы: info, form, list"
- Источника: "Импортирована из JSON файла"
## 🗃️ Структура в базе данных
Каждая импортированная воронка сохраняется как:
```json
{
"_id": "ObjectId",
"funnelData": { /* Оригинальная структура JSON */ },
"name": "Сгенерированное название",
"description": "Сгенерированное описание",
"status": "published",
"version": 1,
"createdBy": "import-script",
"usage": { "totalViews": 0, "totalCompletions": 0 },
"createdAt": "2025-01-27T02:13:24.000Z",
"updatedAt": "2025-01-27T02:13:24.000Z",
"publishedAt": "2025-01-27T02:13:24.000Z"
}
```
## 🔧 Устранение проблем
### Ошибка подключения к MongoDB
```
❌ Failed to connect to MongoDB: connect ECONNREFUSED 127.0.0.1:27017
```
**Решение**: Запустите MongoDB или проверьте `MONGODB_URI`
### Файлы не найдены
```
📭 No funnel files found to import.
```
**Решение**: Убедитесь что JSON файлы находятся в `public/funnels/`
### Валидационные ошибки
```
⚠️ Validation warnings for example.json: Missing meta.id
```
**Решение**: Проверьте структуру JSON файла
### Дубликаты в базе
```
⏭️ Skipped - already exists (ID: funnel-test)
```
**Это нормально**: Скрипт не перезаписывает существующие воронки
## 📱 После импорта
### Где найти импортированные воронки
1. **Админка**: `http://localhost:3000/admin`
2. **Прямой доступ**: `http://localhost:3000/{funnel-id}`
3. **Редактирование**: `/admin/builder/{database-id}`
### Что можно делать
- ✅ Редактировать в билдере
- ✅ Дублировать и создавать вариации
- ✅ Просматривать статистику
- ✅ Экспортировать обратно в JSON
- ✅ Публиковать/архивировать
### Совместимость
- ✅ Оригинальные JSON файлы продолжают работать
- ✅ Импортированные воронки имеют приоритет при загрузке
- ✅ Полная обратная совместимость
## 🔄 Повторный запуск
Скрипт можно запускать несколько раз:
- **Безопасно**: не создает дубликаты
- **Умно**: импортирует только новые файлы
- **Быстро**: пропускает уже обработанные
## 📝 Логи и отчеты
Скрипт выводит подробную информацию:
- 📁 Количество найденных файлов
- 🔄 Прогресс обработки каждого файла
- ✅ Успешные импорты с деталями
- ⚠️ Предупреждения и пропуски
- ❌ Ошибки с объяснениями
- 📊 Итоговая сводка
---
**💡 Совет**: Запустите скрипт после настройки базы данных, чтобы быстро мигрировать все существующие воронки в новую админку!

180
MARKUP.md
View File

@ -1,180 +0,0 @@
# 🎨 Система разметки текста WitLab Funnel
## Описание
Универсальная система разметки позволяет выделять части текста **жирным шрифтом** в любых текстовых полях воронки. Система автоматически обнаруживает разметку и применяет стили.
## Синтаксис
### **Жирный текст**
```
**текст** - выделяет текст жирным шрифтом
```
### Примеры использования:
#### 📝 **В заголовках:**
```
"Добро пожаловать в **WitLab**!"
```
Результат: "Добро пожаловать в **WitLab**!"
#### 💰 **В предложениях скидок:**
```
"**50%** скидка только сегодня!"
```
Результат: "**50%** скидка только сегодня!"
#### 💖 **В результатах анализа:**
```
"Ваш **идеальный партнер** найден на основе анализа ваших ответов"
```
Результат: "Ваш **идеальный партнер** найден на основе анализа ваших ответов"
#### 👤 **С именами пользователей:**
```
"Поздравляем, **Анна**! Ваш портрет готов."
```
Результат: "Поздравляем, **Анна**! Ваш портрет готов."
## Где работает
### ✅ Автоматически поддерживается:
- **Все текстовые поля** в экранах воронки (title, subtitle, description)
- **Info экраны** - описания
- **Soulmate Portrait** - описания портрета
- **Date экраны** - info сообщения
- **Form экраны** - лейблы и placeholder
- **Coupon экраны** - все текстовые поля купона
### 🔧 Как это работает:
#### 1. **Автоматическое обнаружение:**
```typescript
// Система автоматически проверяет каждый текст на наличие разметки
import { hasTextMarkup } from "@/lib/text-markup";
if (hasTextMarkup("Ваш **идеальный** партнер")) {
// Включает обработку разметки автоматически
}
```
#### 2. **Универсальная обработка:**
```typescript
// Все компоненты Typography автоматически поддерживают разметку
<Typography enableMarkup={hasTextMarkup(text)}>
{text}
</Typography>
```
#### 3. **Превью в админке:**
```typescript
// В админке показывается живое превью разметки
<MarkupPreview text="Ваш **идеальный** партнер" />
```
## Примеры для разных типов экранов
### 📋 **Info экраны:**
```json
{
"template": "info",
"description": {
"text": "Мы проанализировали **12 миллионов** анкет и нашли **идеальные совпадения** для вас!"
}
}
```
### 💖 **Soulmate Portrait:**
```json
{
"template": "soulmate",
"description": {
"text": "Ваш **идеальный партнер** найден на основе **глубокого анализа** ваших ответов"
}
}
```
### 📅 **Date экраны:**
```json
{
"template": "date",
"infoMessage": {
"text": "Мы используем дату рождения для определения **знака зодиака** и **совместимости**"
}
}
```
### 🎟️ **Coupon экраны:**
```json
{
"template": "coupon",
"coupon": {
"title": { "text": "**94% скидка** только сегодня!" },
"description": { "text": "Используйте промокод **HAIR50** и получите максимальную скидку" }
}
}
```
## Технические детали
### 🔧 **Компоненты системы:**
#### 1. **Утилиты (`/lib/text-markup.ts`):**
- `parseTextMarkup()` - парсинг разметки в сегменты
- `hasTextMarkup()` - проверка наличия разметки
- `stripTextMarkup()` - удаление разметки
#### 2. **React компоненты (`/components/ui/MarkupText/`):**
- `<MarkupText>` - рендеринг текста с разметкой
- `<MarkupPreview>` - превью в админке
- `useHasMarkup()` - React хук для проверки
#### 3. **Интеграция (`Typography.tsx`):**
- Автоматическая активация при обнаружении разметки
- Параметр `enableMarkup` для ручного управления
- Совместимость с существующими стилями
### 📝 **Пример кода:**
```tsx
// Автоматическое использование
<Typography>
Ваш **идеальный** партнер найден!
</Typography>
// Ручное управление
<Typography enableMarkup={true}>
Обычный текст с **выделением**
</Typography>
// Прямое использование MarkupText
<MarkupText as="h1" boldClassName="text-primary">
**WitLab** - найди свою любовь!
</MarkupText>
```
## Лучшие практики
### ✅ **Хорошо:**
- `"Ваш **идеальный** партнер найден!"` - выделение ключевых слов
- `"**50%** скидка только сегодня"` - выделение цифр и акций
- `"Поздравляем, **Анна**!"` - выделение имен
### ❌ **Избегайте:**
- `"**Весь текст жирный**"` - потеря контраста
- `"**Сл**ов**ом** **разб**ит**ые**"` - нечитаемость
- `"****"` - пустые выделения
### 💡 **Советы:**
1. **Выделяйте ключевые слова** - имена, проценты, важные понятия
2. **Соблюдайте баланс** - не более 20% текста должно быть жирным
3. **Тестируйте в превью** - используйте MarkupPreview в админке
4. **Учитывайте контекст** - в заголовках выделение менее заметно
## Совместимость
- ✅ **React 18+**
- ✅ **TypeScript 5+**
- ✅ **Next.js 14+**
- ✅ **Tailwind CSS**
- ✅ **Обратная совместимость** - существующий текст работает без изменений

View File

@ -1,216 +0,0 @@
# WitLab Funnel Admin - Полноценная админка с MongoDB
## Что реализовано
### ✅ База данных MongoDB
- **Подключение через Mongoose** с автоматическим переподключением
- **Модели для воронок** с полной валидацией структуры данных
- **История изменений** для системы undo/redo
- **Индексы для производительности** поиска и фильтрации
### ✅ API Routes
- `GET /api/funnels` - список воронок с пагинацией и фильтрами
- `POST /api/funnels` - создание новой воронки
- `GET /api/funnels/[id]` - получение конкретной воронки
- `PUT /api/funnels/[id]` - обновление воронки
- `DELETE /api/funnels/[id]` - удаление воронки (только черновики)
- `POST /api/funnels/[id]/duplicate` - дублирование воронки
- `GET/POST /api/funnels/[id]/history` - работа с историей изменений
- `GET /api/funnels/by-funnel-id/[funnelId]` - загрузка по funnel ID (для совместимости)
### ✅ Каталог воронок `/admin`
- **Список всех воронок** с поиском, фильтрацией и сортировкой
- **Создание новых воронок** с базовым шаблоном
- **Дублирование существующих** воронок
- **Удаление черновиков** (опубликованные можно только архивировать)
- **Статистика использования** (просмотры, завершения)
- **Статусы**: draft, published, archived
### ✅ Редактор воронок `/admin/builder/[id]`
- **Полноценный билдер** интегрированный с существующей архитектурой
- **Автосохранение** изменений в базу данных
- **Система публикации** с контролем версий
- **Топ бар** с информацией о воронке и кнопками действий
- **Экспорт/импорт JSON** для резервного копирования
### ✅ Система undo/redo
- **История действий** с глубиной до 50 шагов
- **Базовые точки** при сохранении в БД (после сохранения нельзя откатить)
- **Несохраненные изменения** отслеживаются отдельно
- **Автоматическая очистка** старых записей истории
### ✅ Интеграция с существующим кодом
- **Обратная совместимость** с JSON файлами
- **Приоритет базы данных** при загрузке воронок
- **Автоматическое увеличение статистики** при просмотрах
- **Единый API** для всех компонентов системы
## Настройка окружения
### 1. MongoDB Connection
Создайте `.env.local` файл:
```bash
# MongoDB
MONGODB_URI=mongodb://localhost:27017/witlab-funnel
# или для MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/witlab-funnel
# Base URL (для server-side запросов)
NEXT_PUBLIC_BASE_URL=http://localhost:3000
```
### 2. Установка MongoDB локально
```bash
# macOS (через Homebrew)
brew install mongodb-community
brew services start mongodb-community
# Или используйте MongoDB Atlas (облако)
```
### 3. Запуск проекта
```bash
npm install
npm run dev
```
## Использование
### Создание новой воронки
1. Перейдите на `/admin`
2. Нажмите "Создать воронку"
3. Автоматически откроется билдер с базовым шаблоном
4. Редактируйте экраны в правом сайдбаре
5. Сохраняйте изменения кнопкой "Сохранить"
6. Публикуйте готовую воронку кнопкой "Опубликовать"
### Редактирование существующей воронки
1. В каталоге найдите нужную воронку
2. Нажмите иконку "Редактировать" (карандаш)
3. Внесите изменения в билдере
4. Сохраните или опубликуйте
### Просмотр воронки
1. Нажмите иконку "Просмотр" (глаз) в каталоге
2. Или перейдите на `/{funnelId}` напрямую
### Дублирование воронки
1. Нажмите иконку "Дублировать" (копия)
2. Создастся копия со статусом "Черновик"
3. Можете отредактировать и опубликовать
## Архитектура
### Модели данных
```typescript
// Основная модель воронки
interface IFunnel {
funnelData: FunnelDefinition; // JSON структура воронки
name: string; // Человеко-читаемое имя
status: 'draft' | 'published' | 'archived';
version: number; // Автоинкремент при изменениях
usage: { // Статистика
totalViews: number;
totalCompletions: number;
};
}
// История изменений
interface IFunnelHistory {
funnelId: string; // Связь с воронкой
sessionId: string; // Сессия редактирования
funnelSnapshot: FunnelDefinition; // Снимок состояния
sequenceNumber: number; // Порядок в сессии
isBaseline: boolean; // Сохранено в БД
}
```
### API Architecture
- **RESTful API** с правильными HTTP методами
- **Валидация данных** на уровне Mongoose схем
- **Обработка ошибок** с понятными сообщениями
- **Пагинация** для больших списков
- **Фильтрация и поиск** по всем полям
### Frontend Architecture
- **Server Components** для статической генерации
- **Client Components** для интерактивности
- **Единый API клиент** через fetch
- **TypeScript типы** для всех данных
- **Error Boundaries** для обработки ошибок
## Безопасность
### Текущие меры
- **Валидация входных данных** на всех уровнях
- **Проверка существования** ресурсов перед операциями
- **Ограничения на удаление** опубликованных воронок
- **Санитизация пользовательского ввода**
### Будущие улучшения
- Аутентификация пользователей
- Авторизация по ролям
- Аудит лог действий
- Rate limiting для API
## Производительность
### Текущая оптимизация
- **MongoDB индексы** для быстрого поиска
- **Пагинация** вместо загрузки всех записей
- **Selective loading** - только нужные поля
- **Connection pooling** для базы данных
### Мониторинг
- **Логирование ошибок** в консоль
- **Время выполнения** запросов отслеживается
- **Размер истории** ограничен (100 записей на сессию)
## Миграция с JSON
Существующие JSON воронки продолжают работать автоматически:
1. **Приоритет базы данных** - сначала поиск в MongoDB
2. **Fallback на JSON** - если не найдено в базе
3. **Импорт из JSON** - можно загрузить JSON в билдере
4. **Экспорт в JSON** - для резервного копирования
## Roadmap
### Ближайшие планы
- [x] Основная функциональность админки
- [x] Система undo/redo
- [x] Интеграция с существующим кодом
- [ ] Аутентификация пользователей
- [ ] Collaborative editing
- [ ] Advanced аналитика
### Долгосрочные цели
- [ ] Multi-tenant архитектура
- [ ] A/B тестирование воронок
- [ ] Интеграция с внешними сервисами
- [ ] Mobile app для мониторинга
## Техническая поддержка
### Логи и отладка
```bash
# Проверка подключения к MongoDB
curl http://localhost:3000/api/funnels
# Просмотр логов в консоли разработчика
# MongoDB connection logs в терминале
```
### Частые проблемы
1. **MongoDB not connected** - проверьте MONGODB_URI в .env.local
2. **API errors** - проверьте сетевое соединение
3. **Build errors** - убедитесь что все зависимости установлены
### Контакты
- GitHub Issues для багрепортов
- Документация в `/docs/`
- Комментарии в коде для сложных частей
---
**Полноценная админка с MongoDB готова к использованию! 🚀**