Тест: пауза магазина + ИИ-ответы в Telegram (локальный контейнер) #139

Open
opened 2026-08-07 14:03:27 +00:00 by NW · 6 comments
Owner

Задача

Остановить бота на продакшине и запустить локально в контейнере с теми же Telegram API, чтобы протестировать:

  1. Паузу магазина (sleep mode)
  2. Ответы ИИ в чате Telegram-бота

Статус

  • Продакшн-бот остановлен (Exited 137, конфликта polling нет)
  • Webhook не установлен — polling локально возможен
  • Интегрировать main-бот с /api/chat админки (chatbotService)
  • Настроить site_settings (chatbot_enabled, sleep_mode, provider, api_key)
  • Запустить локальный контейнер бота
  • Протестировать паузу магазина (/start → sleep message)
  • Протестировать ИИ-ответы (сообщение → ответ LLM)
  • Проверить Leads/ChatSessions в админке

Ключевой факт

main-бот (Node.js) НЕ имеет ИИ-интеграции — sleep mode и /api/chat живут только в Next.js админке (feat/nextjs-admin). Нужен мост: бот вызывает POST /api/chat админки (localhost:3100).

## Задача Остановить бота на продакшине и запустить локально в контейнере с теми же Telegram API, чтобы протестировать: 1. Паузу магазина (sleep mode) 2. Ответы ИИ в чате Telegram-бота ## Статус - [x] Продакшн-бот остановлен (Exited 137, конфликта polling нет) - [x] Webhook не установлен — polling локально возможен - [ ] Интегрировать main-бот с /api/chat админки (chatbotService) - [ ] Настроить site_settings (chatbot_enabled, sleep_mode, provider, api_key) - [ ] Запустить локальный контейнер бота - [ ] Протестировать паузу магазина (/start → sleep message) - [ ] Протестировать ИИ-ответы (сообщение → ответ LLM) - [ ] Проверить Leads/ChatSessions в админке ## Ключевой факт main-бот (Node.js) НЕ имеет ИИ-интеграции — sleep mode и /api/chat живут только в Next.js админке (feat/nextjs-admin). Нужен мост: бот вызывает POST /api/chat админки (localhost:3100).
Author
Owner

Прогресс: локальный контейнер запущен

Что сделано:

  1. Продакшн-бот остановлен — через Gitea Actions workflow (раннер orange-pi-arm64) выполнен docker stop telegram_shop_prod + docker update --restart=no. Контейнер на 192.168.2.74 остановлен, restart отключён.

  2. Локальный контейнер запущен (telegram-shop-local, host-сеть):

    • Бот инициализирован, polling работает, 0 ошибок 409
    • Админка на :3100, бот на :3001
    • Подключён к той же БД db/shop.db
  3. Мост бот → ИИ реализован:

    • src/services/chatbotService.js — вызов POST /api/chat админки
    • Sleep mode в handleStart (пауза магазина)
    • AI-ответы в message handler (необработанные сообщения → ИИ)
    • messageRouter.dispatch теперь возвращает признак обработки
  4. z-ai-web-dev-sdk удалён — только реальный Ollama Cloud API:

  5. Настройки в site_settings: chatbot_enabled=true, sleep_mode=false (тест), api_key=bbox, model=glm-5.2

Проверено:

  • Sleep mode: /api/chat отвечает 'Магазин временно на паузе...'
  • ИИ-ответы: 'Сколько стоит VPN на 90 дней?' → '4.99' с каталогом
  • Мост из контейнера: curl localhost:3100/api/chat работает
  • Лиды/сессии создаются (leadId 1-4)

Осталось: реальный тест в Telegram (отправить /start и сообщение боту).

## ✅ Прогресс: локальный контейнер запущен **Что сделано:** 1. **Продакшн-бот остановлен** — через Gitea Actions workflow (раннер orange-pi-arm64) выполнен `docker stop telegram_shop_prod` + `docker update --restart=no`. Контейнер на 192.168.2.74 остановлен, restart отключён. 2. **Локальный контейнер запущен** (`telegram-shop-local`, host-сеть): - Бот инициализирован, polling работает, 0 ошибок 409 - Админка на :3100, бот на :3001 - Подключён к той же БД `db/shop.db` 3. **Мост бот → ИИ реализован**: - `src/services/chatbotService.js` — вызов POST /api/chat админки - Sleep mode в `handleStart` (пауза магазина) - AI-ответы в message handler (необработанные сообщения → ИИ) - `messageRouter.dispatch` теперь возвращает признак обработки 4. **z-ai-web-dev-sdk удалён** — только реальный Ollama Cloud API: - Endpoint: https://ollama.com/v1/chat/completions - API key: bbox (b364c812...) - Модель: glm-5.2 (reasoning_effort: none) - `reasoning_effort: 'none'` добавлен в callOllama 5. **Настройки в site_settings**: chatbot_enabled=true, sleep_mode=false (тест), api_key=bbox, model=glm-5.2 **Проверено:** - ✅ Sleep mode: /api/chat отвечает 'Магазин временно на паузе...' - ✅ ИИ-ответы: 'Сколько стоит VPN на 90 дней?' → '4.99' с каталогом - ✅ Мост из контейнера: curl localhost:3100/api/chat работает - ✅ Лиды/сессии создаются (leadId 1-4) **Осталось:** реальный тест в Telegram (отправить /start и сообщение боту).
Author
Owner

Тестирование завершено

Пауза магазина (sleep mode):

  • Включён sleep_mode=true в site_settings
  • Мост из контейнера: 'Магазин временно на паузе. Мы пополняем ассортимент и скоро откроемся! Оставьте контакт — мы уведомим вас.'
  • handleStart показывает sleep-сообщение вместо каталога

ИИ-ответы:

  • 'Сколько стоит VPN на 90 дней?' → 'VPN Subscription 90d — $24.99' (с каталогом)
  • 'Есть ли премиум аккаунты?' → 'Premium Account 6 Months — $59.99, 1 Year — $99.99'
  • Модель glm-5.2 через Ollama Cloud (bbox API key), reasoning_effort: none

Инфраструктура:

  • Продакшн-бот остановлен (docker stop + restart=no через Gitea Actions)
  • Локальный бот: telegram-shop-local, polling активен (соединения к api.telegram.org)
  • Админка :3100, бот :3001, общая БД db/shop.db
  • z-ai-web-dev-sdk удалён, только реальный Ollama Cloud

Статус: ГОТОВО к тесту в Telegram. Отправьте /start и сообщение боту @dfhfghfghfghfghfgdhdfg_bot — получите sleep-сообщение (пауза) или ИИ-ответ (после выключения sleep).

## ✅ Тестирование завершено **Пауза магазина (sleep mode):** - ✅ Включён sleep_mode=true в site_settings - ✅ Мост из контейнера: 'Магазин временно на паузе. Мы пополняем ассортимент и скоро откроемся! Оставьте контакт — мы уведомим вас.' - ✅ handleStart показывает sleep-сообщение вместо каталога **ИИ-ответы:** - ✅ 'Сколько стоит VPN на 90 дней?' → 'VPN Subscription 90d — $24.99' (с каталогом) - ✅ 'Есть ли премиум аккаунты?' → 'Premium Account 6 Months — $59.99, 1 Year — $99.99' - ✅ Модель glm-5.2 через Ollama Cloud (bbox API key), reasoning_effort: none **Инфраструктура:** - ✅ Продакшн-бот остановлен (docker stop + restart=no через Gitea Actions) - ✅ Локальный бот: telegram-shop-local, polling активен (соединения к api.telegram.org) - ✅ Админка :3100, бот :3001, общая БД db/shop.db - ✅ z-ai-web-dev-sdk удалён, только реальный Ollama Cloud **Статус: ГОТОВО к тесту в Telegram.** Отправьте /start и сообщение боту @dfhfghfghfghfghfgdhdfg_bot — получите sleep-сообщение (пауза) или ИИ-ответ (после выключения sleep).
Author
Owner

🔧 Исправлены 3 бага

Баг 1: Заглушка сработала частично

Проблема: sleep mode давал жёсткое «Магазин на паузе» — клиент думал, что сервис мёртв.
Исправление: В /api/chat (route.ts) sleep mode теперь = мягкая инструкция: живой диалог, отвечает на вопросы о товарах и качестве, при попытке купить объясняет что резервы позже и предлагает оставить контакт. handleStart показывает ИИ-приветствие вместо заглушки.

Баг 2: Меню не убирались

Проблема: при нажатии «📦 Products» открывался каталог (страны/категории).
Исправление: в routes.js при sleep mode кнопка Магазин сразу переключает на ИИ-диалог + reply_markup: { remove_keyboard: true } — меню убирается, клиент остаётся в диалоге с ботом.

Баг 3: Полный JSON каталога в контекст

Проблема: в контекст ИИ шёл упрощённый список (name, price, category).
Исправление: в /api/chat теперь полный JSON каталога: id, name, description, price, quantityInStock, isMono, category, subcategory, location (страна/город/район). Добавлена инструкция: работает только общение, резервы позже, может расспросить по качеству.

Проверено:

  • 'Хочу купить VPN' → живой ответ с каталогом + 'магазин на паузе, оставьте контакт'
  • 'Какое качество у VPN?' → детальный ответ о качестве/стабильности + предложение оставить контакт
  • '📦 Products' → ИИ-ответ вместо каталога (remove_keyboard)

Статус:

  • Админка пересобрана (полный JSON каталога + мягкая пауза), :3100
  • Контейнер бота пересобран с фиксами, polling активен, 0 ошибок 409
  • Продакшн-бот остановлен (restart=no)

Готово к тесту в Telegram: @dfhfghfghfghfghfgdhdfg_bot (sleep_mode=true — тест паузы; выключить в #/chatbot для теста ИИ-продаж).

## 🔧 Исправлены 3 бага ### Баг 1: Заглушка сработала частично **Проблема:** sleep mode давал жёсткое «Магазин на паузе» — клиент думал, что сервис мёртв. **Исправление:** В /api/chat (route.ts) sleep mode теперь = мягкая инструкция: живой диалог, отвечает на вопросы о товарах и качестве, при попытке купить объясняет что резервы позже и предлагает оставить контакт. handleStart показывает ИИ-приветствие вместо заглушки. ### Баг 2: Меню не убирались **Проблема:** при нажатии «📦 Products» открывался каталог (страны/категории). **Исправление:** в routes.js при sleep mode кнопка Магазин сразу переключает на ИИ-диалог + reply_markup: { remove_keyboard: true } — меню убирается, клиент остаётся в диалоге с ботом. ### Баг 3: Полный JSON каталога в контекст **Проблема:** в контекст ИИ шёл упрощённый список (name, price, category). **Исправление:** в /api/chat теперь полный JSON каталога: id, name, description, price, quantityInStock, isMono, category, subcategory, location (страна/город/район). Добавлена инструкция: работает только общение, резервы позже, может расспросить по качеству. ### Проверено: - ✅ 'Хочу купить VPN' → живой ответ с каталогом + 'магазин на паузе, оставьте контакт' - ✅ 'Какое качество у VPN?' → детальный ответ о качестве/стабильности + предложение оставить контакт - ✅ '📦 Products' → ИИ-ответ вместо каталога (remove_keyboard) ### Статус: - Админка пересобрана (полный JSON каталога + мягкая пауза), :3100 - Контейнер бота пересобран с фиксами, polling активен, 0 ошибок 409 - Продакшн-бот остановлен (restart=no) **Готово к тесту в Telegram: @dfhfghfghfghfghfgdhdfg_bot** (sleep_mode=true — тест паузы; выключить в #/chatbot для теста ИИ-продаж).
Author
Owner

🔗 Объединение Users и Leads (расширенный профиль)

Исследование: users (финансы: баланс, покупки, кошельки, страна) и leads (коммуникации: переписки с ИИ, AI-профиль, статус) — одна сущность по telegram_id (пример: lead #5 = user #13 neroworm).

Реализовано объединение на уровне API + UI (без изменения схемы БД):

API

  • GET /api/leads/[id] → теперь возвращает { lead, user } — связанный пользователь (баланс, покупки, кошельки, страна)
  • GET /api/users/[id] → теперь возвращает { ...user, lead } — связанный лид (сессии, customerProfile, статус лида)
  • GET /api/leads/bulk → каждый лид обогащён полем user (баланс, статус, покупки)
  • GET /api/users/bulk → каждый пользователь обогащён полем lead (сессии, статус лида)

UI Лиды (#/leads)

  • Таблица: новая колонка «Покупатель» — баланс, количество покупок, бейдж бана
  • Детализация: блок «Покупатель» с KPI (баланс, покупки, кошельки), гео, последние покупки

UI Пользователи (#/users)

  • Таблица: новая колонка «Chats» — количество ИИ-сессий
  • Детализация: KPI «Chat Sessions», блок «Client Profile» с ИИ-профилем (intent/sentiment/summary), списком сессий с фингерпринтами (страна/устройство), телефоном/email/скором лида

Проверено (Playwright)

  • Users: колонка Chats (neroworm=1 сессия)
  • Leads: колонка Покупатель ($175 · 3 покупок у лида alice)
  • User detail 13: Client Profile + Chat Sessions + Lead status
  • Связка в обе стороны: lead#5 ↔ user#13

Теперь и в Пользователях, и в Лидах виден расширенный профиль с привязанными переписками и финансами.

## 🔗 Объединение Users и Leads (расширенный профиль) **Исследование:** users (финансы: баланс, покупки, кошельки, страна) и leads (коммуникации: переписки с ИИ, AI-профиль, статус) — одна сущность по telegram_id (пример: lead #5 = user #13 neroworm). **Реализовано объединение на уровне API + UI (без изменения схемы БД):** ### API - `GET /api/leads/[id]` → теперь возвращает `{ lead, user }` — связанный пользователь (баланс, покупки, кошельки, страна) - `GET /api/users/[id]` → теперь возвращает `{ ...user, lead }` — связанный лид (сессии, customerProfile, статус лида) - `GET /api/leads/bulk` → каждый лид обогащён полем `user` (баланс, статус, покупки) - `GET /api/users/bulk` → каждый пользователь обогащён полем `lead` (сессии, статус лида) ### UI Лиды (#/leads) - Таблица: новая колонка «Покупатель» — баланс, количество покупок, бейдж бана - Детализация: блок «Покупатель» с KPI (баланс, покупки, кошельки), гео, последние покупки ### UI Пользователи (#/users) - Таблица: новая колонка «Chats» — количество ИИ-сессий - Детализация: KPI «Chat Sessions», блок «Client Profile» с ИИ-профилем (intent/sentiment/summary), списком сессий с фингерпринтами (страна/устройство), телефоном/email/скором лида ### Проверено (Playwright) - ✅ Users: колонка Chats (neroworm=1 сессия) - ✅ Leads: колонка Покупатель ($175 · 3 покупок у лида alice) - ✅ User detail 13: Client Profile + Chat Sessions + Lead status - ✅ Связка в обе стороны: lead#5 ↔ user#13 Теперь и в Пользователях, и в Лидах виден расширенный профиль с привязанными переписками и финансами.
Author
Owner

4 правки по административному разделу

1. Очистка тестовых данных

  • Удалены тестовые пользователи (alice, bob, charlie... id 1-10) с их кошельками/покупками/транзакциями
  • Удалены тестовые лиды (1001, 9999, 7777...) и их сессии
  • Удалены тестовые audit_log
  • Остались только реальные: users 11-13 (UsaChicagoAll, Jehanson, neroworm), lead #5 (732563549)
  • Бэкап: db/shop.db.backup-*-cleanup

2. Просмотр переписок

  • Вкладка «Переписки» на странице лида: список сессий с количеством сообщений, временем, гео/устройством
  • Клик по сессии раскрывает полный транскрипт диалога с ИИ-агентом (пузыри: Клиент/ИИ-агент, время)

3. Лид → полная страница (вместо Sheet)

  • Убран боковой Sheet — клик по лиду ведёт на #/leads/{id}
  • Полная страница по аналогии с пользователем: KPI-карточки (баланс, покупки, сессии, AI-скор), профиль лида, блок покупателя, заметки, табы (Переписки/Активность/Покупки)

4. Тепловая карта активности

  • API /api/leads/[id]/activity — агрегация audit_log по telegram_id
  • Почасовая активность (0-23) — столбчатая диаграмма
  • Годовая карта GitHub-style — кубики по дням (53 недели), интенсивность цвета
  • Легенда Меньше/Больше, tooltip с датой и числом действий

Проверено (Playwright)

  • Таблица лидов: только реальный лид
  • #/leads/5: полная страница, 1 сессия, транскрипт раскрывается
  • Тепловая карта: 243 ячейки, 2 действия, почасовая + годовая
  • Консоль чистая (только ожидаемая 401 до логина)
## ✅ 4 правки по административному разделу ### 1. Очистка тестовых данных - Удалены тестовые пользователи (alice, bob, charlie... id 1-10) с их кошельками/покупками/транзакциями - Удалены тестовые лиды (1001, 9999, 7777...) и их сессии - Удалены тестовые audit_log - Остались только реальные: users 11-13 (UsaChicagoAll, Jehanson, neroworm), lead #5 (732563549) - Бэкап: db/shop.db.backup-*-cleanup ### 2. Просмотр переписок - Вкладка «Переписки» на странице лида: список сессий с количеством сообщений, временем, гео/устройством - Клик по сессии раскрывает полный транскрипт диалога с ИИ-агентом (пузыри: Клиент/ИИ-агент, время) ### 3. Лид → полная страница (вместо Sheet) - Убран боковой Sheet — клик по лиду ведёт на #/leads/{id} - Полная страница по аналогии с пользователем: KPI-карточки (баланс, покупки, сессии, AI-скор), профиль лида, блок покупателя, заметки, табы (Переписки/Активность/Покупки) ### 4. Тепловая карта активности - API /api/leads/[id]/activity — агрегация audit_log по telegram_id - Почасовая активность (0-23) — столбчатая диаграмма - Годовая карта GitHub-style — кубики по дням (53 недели), интенсивность цвета - Легенда Меньше/Больше, tooltip с датой и числом действий ### Проверено (Playwright) - ✅ Таблица лидов: только реальный лид - ✅ #/leads/5: полная страница, 1 сессия, транскрипт раскрывается - ✅ Тепловая карта: 243 ячейки, 2 действия, почасовая + годовая - ✅ Консоль чистая (только ожидаемая 401 до логина)
Author
Owner

🔧 Исправлены 2 бага в таблице лидов

Баг 1: Не отображались никнейм и Telegram ID

Причина: API возвращает поле telegram (@neroworm), а компонент читал устаревшее telegramUsername — которого в ответе нет. Колонки Telegram ID в таблице вообще не было.
Исправление: таблица теперь читает lead.telegram (никнейм) + добавлена колонка «Telegram ID» (lead.telegramId).

Баг 2: Откуда взялось имя «happy to answer»

Причина: ложное срабатывание regex в extractLeadData (api/chat/route.ts). Фраза ИИ-агента «I'm happy to answer...» матчилась паттерном (?:i am|i'm)\s+([A-Z][a-z]+...) и записывалась как имя лида. Причём функция анализировала ВСЕ сообщения (включая ответы ассистента), а не только клиента.
Исправление:

  • Анализируются только сообщения клиента (role === 'user')
  • Добавлен стоп-лист слов (happy, here, your, very...) — отбрасываются ложные имена
  • Очищено имя в БД: lead #5 name = NULL

Проверено (Playwright)

  • Таблица: @neroworm | 732563549 | Без имени (имя очищено)
  • Консоль чистая
## 🔧 Исправлены 2 бага в таблице лидов ### Баг 1: Не отображались никнейм и Telegram ID **Причина:** API возвращает поле `telegram` (@neroworm), а компонент читал устаревшее `telegramUsername` — которого в ответе нет. Колонки Telegram ID в таблице вообще не было. **Исправление:** таблица теперь читает `lead.telegram` (никнейм) + добавлена колонка «Telegram ID» (`lead.telegramId`). ### Баг 2: Откуда взялось имя «happy to answer» **Причина:** ложное срабатывание regex в `extractLeadData` (api/chat/route.ts). Фраза ИИ-агента «I'm happy to answer...» матчилась паттерном `(?:i am|i'm)\s+([A-Z][a-z]+...)` и записывалась как имя лида. Причём функция анализировала ВСЕ сообщения (включая ответы ассистента), а не только клиента. **Исправление:** - Анализируются только сообщения клиента (`role === 'user'`) - Добавлен стоп-лист слов (happy, here, your, very...) — отбрасываются ложные имена - Очищено имя в БД: lead #5 name = NULL ### Проверено (Playwright) - ✅ Таблица: @neroworm | 732563549 | Без имени (имя очищено) - ✅ Консоль чистая
Sign in to join this conversation.