fix
This commit is contained in:
parent
8a978cbf06
commit
58f96f652c
216
README-ADMIN.md
Normal file
216
README-ADMIN.md
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
# 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 готова к использованию! 🚀**
|
||||||
@ -9,7 +9,6 @@ interface GlobalMongoDB {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare global variable for better TypeScript support
|
|
||||||
declare global {
|
declare global {
|
||||||
var mongodb: GlobalMongoDB | undefined;
|
var mongodb: GlobalMongoDB | undefined;
|
||||||
}
|
}
|
||||||
@ -28,10 +27,9 @@ async function connectMongoDB(): Promise<Connection> {
|
|||||||
if (!cached!.mongoose.promise) {
|
if (!cached!.mongoose.promise) {
|
||||||
const opts = {
|
const opts = {
|
||||||
bufferCommands: false,
|
bufferCommands: false,
|
||||||
// Добавляем дополнительные опции для стабильности
|
maxPoolSize: 10,
|
||||||
maxPoolSize: 10, // Maintain up to 10 socket connections
|
serverSelectionTimeoutMS: 5000,
|
||||||
serverSelectionTimeoutMS: 5000, // Keep trying to send operations for 5 seconds
|
socketTimeoutMS: 45000,
|
||||||
socketTimeoutMS: 45000, // Close sockets after 45 seconds of inactivity
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cached!.mongoose.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
|
cached!.mongoose.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
|
||||||
@ -47,7 +45,6 @@ async function connectMongoDB(): Promise<Connection> {
|
|||||||
cached!.mongoose.conn = await cached!.mongoose.promise;
|
cached!.mongoose.conn = await cached!.mongoose.promise;
|
||||||
return cached!.mongoose.conn;
|
return cached!.mongoose.conn;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Reset the promise so next connection attempt can try again
|
|
||||||
cached!.mongoose.promise = null;
|
cached!.mongoose.promise = null;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user