Files
telegram-shop/docs/API.md
NW d7680357af chore: repo cleanup + docs for admin API and DB schema (v1.2.8)
- remove stale docs/admin-frontend-spec.md (old Express/EJS admin), unused templates/ (SmartAdmin copy), dead scripts/sync-agents.cjs, committed dev.pid
- add docs/API.md (admin REST API reference) and docs/DATABASE.md (DB schema)
- refresh .env.example: drop stale ADMIN_PORT/SHOP_CONTAINER, add ADMIN_URL, HEALTH_PORT, DEFAULT_LANGUAGE, CHATBOT_API_*
- add npm run lint so Gitea workflows pass
- rebrand web-testing suite from APAW to telegram-shop
2026-08-09 00:22:22 +01:00

13 KiB
Raw Permalink Blame History

Telegram Shop — Admin API Reference

Актуальная документация по REST API админ-панели (admin-next/, Next.js 16 + Prisma).

  • Базовый URL: http://<host>:3000
  • Формат: JSON (Content-Type: application/json)
  • Аутентификация: cookie admin_token (httpOnly, 24ч), устанавливается через POST /api/auth/login

Аутентификация

Метод Путь Описание
POST /api/auth/login Вход по токену. Body: { "token": "..." }. Rate-limit: 5 попыток / 15 мин на IP (429). Устанавливает cookie admin_token
GET /api/auth/session Проверка сессии. Ответ: { "role": "admin" | "super_admin" } (401 если нет/просрочен)
POST /api/auth/logout Выход, удаляет cookie

Роли

  • admin — обычный администратор
  • super_admin — доступ к seed-фразам, экспорту, импорту, очистке БД

Роль определяется при входе: если SUPER_ADMIN_SECRET не задан или равен ADMIN_SECRET — все админы получают super_admin. Иначе роль super_admin даёт только вход по SUPER_ADMIN_SECRET.

Все эндпоинты ниже требуют cookie admin_token (иначе 401). Эндпоинты с пометкой 🔒 требуют роль super_admin (иначе 403).

Дашборд и статистика

GET /api/stats/dashboard

Сводная статистика для дашборда:

  • counts: totalUsers, totalProducts, totalPurchases, totalSubcategories, bannedUsers, activeWallets
  • статусы покупок: completedPurchases, pendingPurchases, cancelledPurchases
  • метрики: totalRevenue (сумма completed), aov, conversionRate
  • временные ряды: revenueByDay, purchasesByDay, newUsersByDay (последние 30 дней)
  • topProducts, recentPurchases, recentUsers

Каталог

GET /api/catalog/tree

Полное дерево каталога: локации, категории, подкатегории с _count (вложенные сущности).

Локации

Метод Путь Описание
GET /api/locations/bulk Список локаций (с _count категорий/товаров)
POST /api/locations/bulk Создать. Body: { country, city, district }
PUT /api/locations/[id] Обновить. Body: { country?, city?, district? }
PATCH /api/locations/[id] Переключить is_active (0/1)
DELETE /api/locations/[id] Удалить (409 если есть связанные сущности)

Категории

Метод Путь Описание
GET /api/categories/bulk Список категорий (с локацией и _count)
POST /api/categories/bulk Создать. Body: { name, locationId }
PUT /api/categories/[id] Обновить. Body: { name?, locationId? } (409 при дубликате в локации)
PATCH /api/categories/[id] Переключить is_active
DELETE /api/categories/[id] Удалить (409 если есть связанные сущности)

Подкатегории

Метод Путь Описание
GET /api/subcategories/bulk Список подкатегорий
POST /api/subcategories/bulk Создать. Body: { name, categoryId }
PUT /api/subcategories/[id] Обновить. Body: { name?, categoryId? }
PATCH /api/subcategories/[id] Переключить is_active
DELETE /api/subcategories/[id] Удалить

Товары

Метод Путь Описание
GET /api/products/bulk Список. Query: loc, cat, sub, search, page, limit (≤100). Ответ: { data, total, page, limit }
POST /api/products/add Создать. Body: { locationId, categoryId, subcategoryId?, name, description?, privateData?, price, quantityInStock?, photoUrl?, hiddenPhotoUrl?, hiddenCoordinates?, hiddenDescription?, isMono? }. Обязательны: locationId, categoryId, name, price. isMono=1quantityInStock=999999
GET /api/products/[id] Детали товара (с category, subcategory, location)
PUT /api/products/[id] Обновить (частично)
DELETE /api/products/[id] Удалить
POST /api/products/[id]/clone Клонировать (имя получает суффикс (Copy))

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

Метод Путь Описание
GET /api/users/bulk Список. Query: search (username/telegramId), status (0/2), page, limit (≤100). Ответ: { data, total, page, limit }
GET /api/users/[id] Детали: пользователь + кошельки + последние 20 покупок + связанный лид
POST /api/users/[id] Обновить (username, country, city, district, notes и т.д.)
PATCH /api/users/[id] Переключить status (0=active, 2=blocked)
POST /api/users/[id]/adjust-balance Изменить баланс. Body: { amount: number, currency: "total_balance" | "bonus_balance" }. Пишет audit-запись
POST /api/users/batch-status Массово сменить статус. Body: { userIds: number[], newStatus: 0 | 2 }

Кошельки

Метод Путь Описание
GET /api/wallets/bulk Пользователи, у которых есть кошельки. Query: search. Ответ: { users, totalWallets, totalBalance }
GET /api/wallets/[userId] Кошельки конкретного пользователя
GET /api/wallets/overview Сводка: суммы и количество по типам (BTC/LTC/ETH/USDT/USDC), последние 20 комиссионных выплат
GET /api/wallets/seeds 🔒 Seed-фразы всех кошельков (пишет audit seed_phrase_viewed)
GET /api/wallets/export-seeds 🔒 Экспорт seed-фраз в CSV (Content-Disposition: attachment)
POST /api/wallets/record-payment Записать комиссионную выплату. Body: { paidAmount: number, note? }

Покупки

Метод Путь Описание
GET /api/purchases/bulk Список. Query: status (pending/completed/cancelled), from, to (YYYY-MM-DD), page, limit (≤100). Ответ: { data, total, page, limit }
PATCH /api/purchases/[id] Сменить статус. Body: { status: "completed" | "cancelled" }. Только для pending
POST /api/purchases/batch-status Массово. Body: { purchaseIds: number[], status: "completed" | "cancelled" } (обновляет только pending)

Транзакции

Метод Путь Описание
GET /api/transactions/bulk Список. Query: userId, page, limit (≤100, по умолчанию 20). Ответ: { data, total, page, limit }

Лиды и чат

Лиды

Метод Путь Описание
GET /api/leads/bulk Список. Query: search (name/phone/email/telegram/telegramId), status, page, limit (≤100). Ответ: { data, total, page, limit }
GET /api/leads/[id] Детали лида + связанный пользователь (баланс, покупки, кошельки)
PUT /api/leads/[id] Обновить (name, phone, email, telegram, status, notes, customFields и т.д.)
GET /api/leads/[id]/activity Активность: { hourly: number[24], yearly: { "YYYY-MM-DD": count }, total } (по audit_log)
GET /api/leads/[id]/sessions Чат-сессии лида с распарсенными сообщениями

Чат (публичный виджет)

Метод Путь Описание
POST /api/chat Отправить сообщение в чат-виджет. Body: { sessionId?, message, language?, device?, ip?, country? }. Создаёт/обновляет ChatSession, извлекает данные лида (имя/телефон/email/telegram), вызывает ИИ-провайдера, при chatbot_sleep_mode отвечает sleep-сообщением

Оператор

Метод Путь Описание
POST /api/operator Подключение/отключение оператора. Body: { sessionId, action: "connect" | "disconnect", operatorName }. Пишет audit operator_connect

Чатбот (настройки)

Метод Путь Описание
GET /api/admin/chatbot Настройки чатбота из site_settings (ключи chatbot_*), API-ключ маскируется
PUT /api/admin/chatbot Обновить настройки. Валидация: chatbot_temperature 02, chatbot_max_tokens 504000, chatbot_max_history 150
GET /api/chatbot/models?endpoint=&apiKey= Список моделей провайдера через OpenAI-совместимый /models. Без query — берёт сохранённые настройки. Поддерживает OpenAI (data[]) и Ollama (models[])

Ключи настроек чатбота (defaults): chatbot_enabled, chatbot_sleep_mode, chatbot_sleep_message, chatbot_system_prompt, chatbot_temperature (0.7), chatbot_max_tokens (1024), chatbot_max_history (20), chatbot_knowledge_base, chatbot_provider (ollama), chatbot_api_endpoint, chatbot_api_key, chatbot_model.

Аудит

Метод Путь Описание
GET /api/audit/bulk Журнал аудита. Query: page, limit (≤200, по умолчанию 100), userId, from, to, search, action. Ответ: { data, total, page, limit }

Локализация (i18n)

Метод Путь Описание
GET /api/locales Все переводы: { en: {...}, es: {...}, de: {...} }
PUT /api/locales Обновить ключ. Body: { lang, key, value }

Настройки

Метод Путь Описание
GET /api/settings Список настроек (секреты маскированы, список в _masked)
PUT /api/settings Обновить. Body: { key, value }. Ответ: «Settings saved. Restart required.»
GET /api/settings/export Полный экспорт БД в JSON (users, wallets, purchases, categories, subcategories, locations, products, auditLogs, commissionPayments, userStates)
POST /api/settings/import 🔒 Импорт (заглушка: «Import not yet implemented»)

Seed / Demo

Метод Путь Описание
GET /api/seed/data Проверка: { seeded: boolean } (есть ли пользователи)
POST /api/seed/demo Заполнить демо-данными. Body: { reauthToken } (повторный ввод секрета)
POST /api/seed/clear 🔒 Очистить все данные. Body: { reauthToken }. Пишет audit clear_all

Корневой

Метод Путь Описание
GET /api Служебный ответ (health API)

Коды ошибок

Код Значение
400 Невалидный запрос / отсутствуют обязательные поля
401 Нет cookie admin_token или токен невалиден/просрочен
403 Недостаточно прав (нужен super_admin)
404 Сущность не найдена
409 Конфликт (дубликат, есть связанные записи)
429 Слишком много попыток входа
500 Внутренняя ошибка

Соглашения

  • Пагинация: page (с 1), limit (кап зависит от эндпоинта: 50/100/200)
  • Даты: from/to в формате YYYY-MM-DD (to инклюзивно до конца дня)
  • is_active/status пользователей: 0 = активно, 2 = заблокировано
  • Статусы покупок: pending / completed / cancelled
  • Статусы лидов: new / contacted / qualified / lost / spam