Files
telegram-shop/docs/admin-nextjs-guide.md
Z User de6f82bd00 feat: add Docker deployment (Dockerfile, docker-compose, .dockerignore) and update docs
- Multi-stage Dockerfile (node:22-slim, bun build, standalone output, non-root)
- docker-compose.yml with DB volume, healthcheck, memory limits
- .dockerignore to exclude dev artifacts from build context
- docs: full deployment guide with docker compose, manual docker, env vars,
  reverse proxy configs (Caddy/Nginx), update instructions, server requirements
- docs: comparison table old (Node.js bot) vs new (Next.js admin)
2026-08-05 23:27:35 +00:00

19 KiB
Executable File
Raw Blame History

Next.js Админ-Панель — Руководство

Обзор

Новая админ-панель на Next.js 16 (App Router) + TypeScript + shadcn/ui + Prisma (SQLite) + Recharts. Полная замена EJS/SmartAdmin шаблонизатора.

Стек

Слой Технология
Фреймворк Next.js 16 (App Router, Turbopack)
Язык TypeScript 5
Стилизация Tailwind CSS 4 + shadcn/ui (New York)
БД Prisma ORM + SQLite
Графики Recharts
Состояние Zustand
ИИ/LLM z-ai-web-dev-sdk (chat, vision)
Тема next-themes (dark/light)
Уведомления Sonner (toast)
Иконки Lucide React

Авторизация

  • Пароль: значение ADMIN_SECRET из .env (по умолчанию changeme)
  • Если задан SUPER_ADMIN_SECRET (и ≠ ADMIN_SECRET) — вход с ним даёт роль super_admin
  • Если не задан — все админы = super_admin
  • Кука admin_token (httpOnly, sameSite=lax, 24ч, secure в production)
  • Rate-limit: 5 попыток / 15 мин с IP
  • HMAC-SHA256 подпись токена

Экраны (15)

Основные

  1. Dashboard — 4 KPI-карточки, 8 графиков (recharts), лента активности, авто-обновление
  2. Catalog — дерево локаций → категории → подкатегории → товары, CRUD, clone, экспорт
  3. Users — таблица + детальная страница, batch ban/unban, заметки, поиск, статус-вкладки
  4. Wallets — 4 вкладки (All/Owner/Transactions/Seeds), запись платежей, экспорт seed-фраз
  5. Purchases — таблица с batch approve/cancel, фильтры по статусу/дате, модаль деталей
  6. Audit Log — журнал действий, фильтры по действию/дате/поиску, копирование записей
  7. Categories — CRUD с просмотром товаров, подсчёт подкатегорий и продуктов
  8. Locations — CRUD (страна/город/район)
  9. Settings — редактирование параметров, экспорт/импорт данных (super_admin)
  10. Locales — inline-редактор EN/ES/DE переводов
  11. Danger Zone — Seed / Clear с reauth (super_admin)

ИИ-ассистент и Лиды

  1. AI Chatbot (#/chatbot) — полная конфигурация ИИ-бота:

    • Включение/выключение бота
    • Спящий режим — при включении /start показывает ИИ-чат вместо каталога
    • Системный промпт и приветственное сообщение
    • Температура, max tokens, глубина истории
    • База знаний — словарный лексикон (товары, цены, FAQ)
    • Провайдер: OpenAI / DeepSeek / OpenRouter / Ollama / Custom
    • API endpoint и ключ (маскированный при отображении)
  2. Leads (#/leads) — управление лидами и переписками:

    • Таблица лидов с поиском, фильтрами по статусу
    • AI-профиль клиента (intent, interests, sentiment, readiness)
    • Просмотр переписок в виде чат-пузырей
    • Вход оператора — переключение бота на ручной режим
    • Статусы: Новый / Контакт / Квалифицированный / Потерянный / Спам
    • Заметки и quick-статус

Спящий режим магазина

Когда спящий режим включён в настройках AI Chatbot:

  • Пользователь через /start получает ИИ-чат вместо каталога
  • Бот сообщает что магазин пополняется
  • Можно собрать контакты для уведомления при открытии
  • Все сессии сохраняются в таблице chat_sessions
  • Из переписок автоматически извлекаются лиды

API маршруты (48+)

Основные

Метод Маршрут Описание
POST /api/auth/login Вход, установка куки
GET /api/auth/session Проверка сессии
POST /api/auth/logout Выход
GET /api/stats/dashboard Статистика дашборда
GET/PUT /api/settings Настройки
GET /api/settings/export Полный экспорт БД (JSON)
POST /api/settings/import Импорт (в разработке)

Товары и каталог

Метод Маршрут Описание
GET /api/products/bulk Список товаров
POST /api/products/add Создание товара
GET/PUT/DELETE /api/products/[id] CRUD товара
POST /api/products/[id]/clone Дублирование товара
GET /api/catalog/tree Дерево каталога
GET/POST /api/categories/bulk Список/создание категорий
GET/PUT/DELETE /api/categories/[id] CRUD категории
GET/POST /api/subcategories/bulk Список/создание подкатегорий
GET/PUT/DELETE /api/subcategories/[id] CRUD подкатегории
GET/POST /api/locations/bulk Список/создание локаций
GET/PUT/DELETE /api/locations/[id] CRUD локации

Пользователи и кошельки

Метод Маршрут Описание
GET /api/users/bulk Список пользователей
GET/PUT /api/users/[id] Профиль пользователя
POST /api/users/[id]/adjust-balance Корректировка баланса
POST /api/users/batch-status Batch ban/unban
GET /api/wallets/bulk Список кошельков
GET /api/wallets/overview Обзор кошельков
GET /api/wallets/[userId] Кошельки пользователя
POST /api/wallets/record-payment Запись платежа
GET /api/wallets/seeds Seed-фразы (super_admin)
GET /api/wallets/export-seeds Экспорт seed-фраз CSV

Покупки и транзакции

Метод Маршрут Описание
GET /api/purchases/bulk Список покупок
GET/PUT /api/purchases/[id] Детали/статус покупки
POST /api/purchases/batch-status Batch approve/cancel
GET /api/transactions/bulk Список транзакций

Аудит и локали

Метод Маршрут Описание
GET /api/audit/bulk Журнал аудита
GET /api/locales Локализации (EN/ES/DE)
POST /api/seed/demo Генерация тестовых данных
POST /api/seed/clear Очистка БД

ИИ-чатбот и лиды

Метод Маршрут Описание
GET/PUT /api/admin/chatbot Настройки ИИ-бота
POST /api/chat Точка входа чата (для TG-бота)
GET /api/leads/bulk Список лидов
GET/PUT /api/leads/[id] Профиль лида
GET /api/leads/[id]/sessions Чат-сессии лида
POST /api/operator Подключение/отключение оператора

Модель данных (Prisma)

Всего 15 моделей:

Модель Описание
TgUser Пользователи Telegram
CryptoWallet Криптокошельки
Transaction Транзакции
Location Локации (страна/город/район)
Category Категории товаров
Subcategory Подкатегории
Product Товары
Purchase Покупки
CommissionPayment Комиссионные платежи
AuditLog Журнал аудита
UserState Состояния пользователей ( FSM )
ChatSession Чат-сессии с ИИ-ботом
Lead Лиды (авто-экстракция из чата)
SiteSetting Ключ-значение настройки

ChatSession

model ChatSession {
  id                Int       @id @default(autoincrement())
  sessionId         String    @unique
  telegramId        String?
  leadId            Int?
  messages          String    // JSON: [{role, content, timestamp}]
  customerProfile   String?   // AI-профиль клиента (JSON)
  isActive          Boolean   @default(true)
  operatorName      String?   // Подключённый оператор
  autoReplyDisabled Boolean   @default(false) // Ручной режим
  operatorConnectedAt DateTime?
  device / ip / country
  createdAt / updatedAt
}

Lead

model Lead {
  id              Int      @id @default(autoincrement())
  telegramId      String?  @unique
  name / phone / email / telegram
  status          String   @default("new")
  aiLeadScore     Float?   // 0-1 скор от ИИ
  customFields    String   // JSON
  chatSessions    ChatSession[]
}

Архитектура ИИ-бота

Конфигурация (SiteSetting)

Все настройки бота хранятся в таблице site_settings как ключ-значение. Кэшируются 5 минут.

Ключ Тип По умолчанию
chatbot_enabled bool true
chatbot_sleep_mode bool false
chatbot_sleep_message text "Магазин пополняется..."
chatbot_system_prompt text "Ты — AI-ассистент..."
chatbot_welcome_message text "Здравствуйте!..."
chatbot_temperature float 0.7
chatbot_max_tokens int 500
chatbot_max_history int 20
chatbot_knowledge_base text ""
chatbot_provider enum openai
chatbot_api_endpoint url https://api.openai.com/v1
chatbot_api_key string ""

Поток чата

  1. TG-бот отправляет POST /api/chat с {sessionId, message, telegramId}
  2. Сервер находит/создаёт ChatSession
  3. Загружает конфигурацию бота (из кэша/БД)
  4. Формирует системный промпт: system_prompt + knowledge_base + customer_profile + catalog_context
  5. Если sleep_mode — добавляет информацию о режиме пополнения
  6. Отправляет в LLM (через z-ai-web-dev-sdk)
  7. Сохраняет сообщения в ChatSession
  8. Извлекает данные лида (имя, телефон, email, telegram) из текста
  9. Генерирует/обновляет AI-профиль клиента (intent, interests, sentiment, readiness)
  10. Автоматически создаёт/обновляет запись Lead
  11. Возвращает {reply, sessionId, leadId?, profile?}

Профилирование клиента

Из каждой переписки ИИ автоматически генерирует профиль:

{
  "intent": "покупка|информация|поддержка|пробный период",
  "interests": ["VPN-коды", "аналитика"],
  "sentiment": "positive|neutral|negative",
  "budgetHint": "бюджетный|высокий",
  "readiness": "exploring|considering|ready",
  "summary": "Цель: покупка. Интересуется VPN."
}

Оператор

  • Оператор может подключиться к любой сессии (POST /api/operator)
  • При подключении: autoReplyDisabled=true, бот перестаёт отвечать
  • Оператор видит всю историю переписки
  • При отключении — бот снова отвечает

Развертывание (Docker)

Сравнение со старой версией

Старая (Node.js бот) Новая (Next.js админка)
Dockerfile FROM node:22, npm install, CMD node src/index.js Multi-stage build, standalone output, non-root user
docker-compose 1 сервис, BOT_TOKEN + ADMIN_IDS 1 сервис, ADMIN_SECRET + CHATBOT_API_KEY
БД ./db/shop.db (sqlite3 напрямую) ./db/custom.db (через Prisma ORM)
Порт Нет (только TG webhook) 3000 (веб-интерфейс + API)
RAM ~64 MB ~256512 MB

Быстрый старт (docker compose)

# 1. Клонировать ветку
GIT_LFS_SKIP_SMUDGE=1 git clone -b feat/nextjs-admin https://git.softuniq.eu/Telegram-Market/telegram-shop.git
CD telegram-shop

# 2. Создать .env файл
cat > .env << 'EOF'
ADMIN_SECRET=your_admin_password
SUPER_ADMIN_SECRET=your_super_admin_password
CHATBOT_API_KEY=sk-your-openai-key   # опционально, для ИИ-бота
CHATBOT_API_ENDPOINT=https://api.openai.com/v1  # или другой провайдер
EOF

# 3. Создать папку для БД
mkdir -p db

# 4. Собрать и запустить
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose up -d --build

# 5. Дождаться запуска (15-30 сек)
docker compose logs -f

После запуска админка доступна на http://<IP>:3000.

Ручной Docker (без compose)

# Сборка
docker build -t tg-shop-admin .

# Запуск
docker run -d \
  --name tg_shop_admin \
  --restart always \
  -p 3000:3000 \
  -v $(pwd)/db:/app/db \
  -e ADMIN_SECRET=your_admin_password \
  -e SUPER_ADMIN_SECRET=your_super_admin_password \
  -e CHATBOT_API_KEY=sk-xxx \
  -m 512m \
  tg-shop-admin

Переменные окружения

Переменная Обязательна По умолчанию Описание
DATABASE_URL Нет file:/app/db/custom.db Путь к SQLite БД внутри контейнера
ADMIN_SECRET Да changeme Пароль для роли admin
SUPER_ADMIN_SECRET Нет Пароль для роли super_admin
CHATBOT_API_KEY Нет API-ключ для ИИ-бота (OpenAI/DeepSeek/etc)
CHATBOT_API_ENDPOINT Нет https://api.openai.com/v1 Endpoint LLM-провайдера

Запуск без Docker (разработка)

# Установить зависимости
bun install

# Инициализация БД
bun run db:push

# Создать .env
echo 'DATABASE_URL=file:./db/custom.db' > .env
echo 'ADMIN_SECRET=admin123' >> .env
echo 'SUPER_ADMIN_SECRET=superadmin456' >> .env

# Генерация тестовых данных (опционально)
curl -X POST http://localhost:3000/api/seed/demo \
  -H 'Cookie: admin_token=<your_token>'

# Dev-сервер
bun run dev        # http://localhost:3000

# Production
bun run build      # сборка standalone
bun run start      # запуск production

Первоначальная настройка после деплоя

  1. Открыть http://<IP>:3000
  2. Войти с паролем из ADMIN_SECRET
  3. Перейти в Settings (#/settings) — настроить параметры магазина
  4. Перейти в AI Chatbot (#/chatbot) — настроить ИИ-бота:
    • Ввести API-ключ и выбрать провайдера
    • Настроить системный промпт
    • Добавить базу знаний (словарный лексикон)
  5. Перейти в Danger ZoneSeed Demo Data для заполнения тестовыми данными
  6. Очистить тестовые данные через Clear Database перед продакшеном

Обновление

# docker compose
git pull
docker compose up -d --build

# ручной
git pull
docker build -t tg-shop-admin .
docker stop tg_shop_admin && docker rm tg_shop_admin
# повторить docker run ...

Важно: БД хранится в volume ./db, она сохраняется при пересборке.

Требования к серверу

Ресурс Минимум Рекомендуется
CPU 1 ядро 2 ядра
RAM 256 MB 512 MB
Диск 500 MB (образ) + БД 1 GB
Архитектура x86_64, ARM64

Reverse Proxy (Caddy / Nginx)

Caddy (авто HTTPS):

admin.yourdomain.com {
    reverse_proxy localhost:3000
}

Nginx:

server {
    listen 443 ssl;
    server_name admin.yourdomain.com;
    # ... ssl certs ...

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Seed-данные

POST /api/seed/demo создаёт данные:

  • 3 локации, 5 категорий, 11 подкатегорий
  • 10 пользователей (alicejack)
  • 10 товаров, 2530 покупок
  • 10 криптокошельков, 2 комиссионных платежа, 12 audit записей

Общие компоненты

  • Pagination — числовая пагинация с многоточиями
  • ErrorBoundary — обработка ошибок рендеринга
  • ExportButton — экспорт CSV + JSON
  • SortableHeader — сортируемые заголовки таблиц
  • useDebounce — хук debounce (300ms)
  • useMobile — хук определения мобильного устройства
  • useKeyboardShortcuts — хук горячих клавиш (19)

Навигация

Хеш-роутинг (window.location.hash). Горячие клавиши: 1 Dashboard, 2 Catalog, 3 Users, 4 Wallets, 5 Purchases, 6 Audit, 7 Categories, 8 Locations, 9 Settings Ctrl+K — палитра команд

Визуальные эффекты

  • Matrix Rain — CSS-анимация падающих символов на странице логина (низкая непрозрачность)
  • Glass-card — стеклянный эффект карточек (backdrop-blur)
  • KPI shimmer — мерцание при наведении на KPI-карточки
  • Page-enter — fade-in анимация страниц
  • Gradient borders — градиентные рамки хедера/футера
  • Alternating rows — чередующиеся строки таблиц
  • Sticky table headers — закреплённые заголовки таблиц