v1.8.0: YandexGPT-only NLP, unknown questions system, callback dedup, consent flow fixes, DELETE cascade, UTC+3, auto-detect sidebar menu, tel:/mailto: links

This commit is contained in:
2026-06-01 18:07:13 +03:00
parent aa1269e013
commit cc87bcf72c
20 changed files with 1453 additions and 301 deletions
+152 -107
View File
@@ -3819,115 +3819,160 @@ RoleMenuPermission модель + API + PermissionsMiddleware
Проанализируй шаги на 100% реализацию! Если что-то не соответствует подготовь план на ПЕРЕПИСАТЬ часть кода -
Сопоставь проработанные этапы 1-4. Все верно и соответствует друг другу? Что необходимо откорректировать для 100% работоспособности этапов 1-4?
Сопоставь проработанные этапы 1-5. Все верно и соответствует друг другу? Что необходимо откорректировать для 100% работоспособности этапов 1-5?
Сопоставь проработанные этапы 1-4 с сервисным порталом? Есть ли функционал в портале не реализованный для правильной работы бота по пройденым этапам 1-4? Что необходимо откорректировать для 100% работоспособности этапов 1-4?
Сопоставь проработанные этапы 1-5 с сервисным порталом? Есть ли функционал в портале не реализованный для правильной работы бота по пройденым этапам 1-4? Что необходимо откорректировать для 100% работоспособности этапов 1-5?
risk_score.py - 57 вопросов анкеты. Вынеси в сервисный портал для добавления или редактирования вопросов в раздел Чат-бот Max под названием "Вопросы для риск-инжиниринга"
Категории (автоматически заполню)
Название Описание Сортировка
Аудит безопасности Независимая оценка систем видеонаблюдения, СКУД, ОПС 1
Сервисное обслуживание / SLA Абонентское обслуживание по SLA-контракту 2
Реагирование на инциденты Срочное реагирование при нештатных ситуациях 3
Технический надзор Контроль качества при монтаже и пусконаладке 4
Проектная документация Разработка и согласование проектной документации 5
Риск-инжиниринг Оценка рисков, BCP, DRP, стратегия безопасности 6
Общий вопрос Консультация или вопрос вне указанных категорий 7
База знаний (автоматически заполню из FAQ сайта)
С планируемым наполнением (~15-20 записей):
max_bot/ — полная копия проекта (47 файлов)
max_bot/
├── .env.example
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI: webhook + 19 API endpoints
│ ├── config.py
│ ├── database.py
│ ├── bot_engine.py # Диспетчер сообщений
│ ├── conversation.py # CRUD диалогов
│ ├── fsm.py # 20 состояний + транзиции
│ ├── max_api.py # MAX Messenger API клиент
│ ├── max_notifications.py # NEW: уведомления оператору/Level2/клиенту
│ ├── settings_cache.py
│ ├── text_renderer.py
│ ├── file_storage.py
│ ├── handlers/
│ │ ├── __init__.py
│ │ ├── greeting.py
│ │ ├── consent.py
│ │ ├── contact.py
│ │ ├── inquiry.py
│ │ ├── handoff.py
│ │ ├── out_of_hours.py
│ │ ├── main_menu.py
│ │ └── features/
│ │ ├── __init__.py
│ │ ├── risk_score.py # UPD: 7 вопросов анкеты
│ │ ├── sla_status.py
│ │ ├── photo_report.py
│ │ ├── appointment.py # UPD: выбор слотов
│ │ ├── quality_rate.py
│ │ ├── commercial.py # UPD: multi-step сбор
│ │ ├── my_objects.py
│ │ ├── sla_ticket.py # UPD: notify_level2
│ │ ├── notifications.py # NEW: подписка
│ │ └── broadcasts.py # NEW: рассылка
│ ├── integrations/
│ │ ├── __init__.py
│ │ ├── _1c_unf.py
│ │ ├── portal_db.py
│ │ └── yandex_gpt.py
│ ├── keyboards/
│ │ ├── __init__.py
│ │ └── inline.py
│ ├── models/
│ │ ├── __init__.py
│ │ └── models.py # 18 моделей (11 bot_* + 5 stub + 2 new)
│ └── utils/
│ ├── __init__.py
│ ├── emotion_detector.py # NEW
│ └── categorizer.py # NEW
├── sql/
│ ├── bot_schema.sql
│ └── migrations/
│ ├── v1.5.1_broadcast_recipient_ids.sql
│ └── v1.5.2_role_menu_permissions.sql
├── nginx/
│ └── max-aegisone.conf
├── max_bot_deploy.sh
└── tests/
├── __init__.py
├── conftest.py
├── test_fsm.py
├── test_handlers.py
├── test_max_api.py
└── test_webhook.py
py_service/ — только изменённые файлы (8 файлов)
py_service/
├── app/
│ └── routers/
│ └── service_pages.py # UPD: +5 роутов (handoffs, notifications)
└── app/templates/
├── page.html # UPD: сайдбар +2 ссылки
├── dashboard.html # UPD: сайдбар +2 ссылки
└── pages/
├── bot_handoffs.html # NEW: Handoff-диалоги
├── bot_notifications.html # NEW: Уведомления
├── role_settings.html # UPD: +2 permission
└── users.html # UPD: колонка MAX ID + поле в форме
SQL миграция (выполнить перед деплоем)
-- Создать в общей БД aegisone:
Вопрос Ответ
Какие услуги вы предоставляете? Мы — независимый инженерный центр... (перечень 6 услуг)
Сколько стоят услуги? Стоимость зависит от объёма... от 15 000 ₽/мес по SLA
Где вы находитесь? Краснодар, ул. Московская, 81/1, офис 25
Работаете ли вы в других регионах? Да, работаем по всей РФ...
Какое у вас рабочее время? Пн-Пт с 9:00 до 18:00
Что входит в аудит безопасности? ...
Что такое "Таинственный покупатель"? ...
Нужно ли останавливать работу при аудите? Нет, аудит проводится без остановки...
Какие SLA-тарифы есть? Базовый (15 000), Оптимальный (30 000), Максимальный (60 000)
Что входит в обслуживание по SLA? ...
Как быстро вы реагируете на инциденты? От 4 до 24 часов в зависимости от тарифа
Продаёте ли вы оборудование? Нет, мы не продаём оборудование, только экспертизу
Работаете ли вы с НДС? ...
Как заключить договор? ...
Есть ли у вас лицензии? ...
CREATE TABLE IF NOT EXISTS bot_notifications (
id SERIAL PRIMARY KEY,
type VARCHAR(50) NOT NULL,
recipient_type VARCHAR(20) NOT NULL CHECK (recipient_type IN ('operator','level2','client')),
recipient_max_user_id BIGINT,
title VARCHAR(255) DEFAULT '',
body TEXT DEFAULT '',
related_type VARCHAR(50) DEFAULT '',
related_id INTEGER,
is_read BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS bot_notification_subscriptions (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES bot_users(id) ON DELETE CASCADE,
notify_on_status_change BOOLEAN NOT NULL DEFAULT FALSE,
notify_on_reply BOOLEAN NOT NULL DEFAULT FALSE,
notify_on_broadcast BOOLEAN NOT NULL DEFAULT FALSE
);
A. Проведи ПОЛНЫЙ ГЛУБОКИЙ анализ кода на 100% реализацию в соответствии с шагами 1-5! Если что-то не соответствует подготовь план на ПЕРЕПИСАТЬ часть кода -
Этап 1 — Инфраструктура проекта
Шаг 1.1 — Создать структуру max_bot/
Папки: app/, app/handlers/, app/handlers/features/, app/integrations/, app/keyboards/, app/models/, app/utils/, sql/, nginx/
Файлы: Dockerfile, docker-compose.yml, requirements.txt, .env.example
Шаг 1.2 — Создать SQL-схему (bot_schema.sql)
Таблицы: bot_users, bot_conversations, bot_messages, bot_consent_logs, bot_1c_sync_log, bot_knowledge_base, bot_categories, bot_settings, bot_features, bot_response_templates, bot_broadcasts
Seed data: bot_settings (имя София, телефоны, email, часы работы), bot_features (11 фич, все disabled)
Шаг 1.3 — Создать Nginx-конфиг max-aegisone.conf
Прокси: /webhook → localhost:8002, /api/ → localhost:8002, /health → localhost:8002
SSL-сертификат Let's Encrypt для max.aegisone.ru
Шаг 1.4 — Создать deploy-скрипты
max_bot_deploy.sh — копирование на сервер, SQL миграция, docker compose up
Дополнить main deploy.sh секцией для max_bot
Этап 2 — Ядро бота
Шаг 2.1 — config.py (Pydantic Settings)
DB_URL, MAX_TOKEN (берётся из БД), WEBHOOK_SECRET, WEBHOOK_PATH
Шаг 2.2 — database.py (AsyncSession)
Подключение к общей БД aegisone (shared с py_service)
Шаг 2.3 — models.py (SQLAlchemy ORM)
Все bot_* модели (BotUser, BotConversation, BotMessage, BotConsentLog, Bot1CSyncLog, BotKnowledgeBase, BotCategory, BotSetting, BotFeature, BotResponseTemplate, BotBroadcast)
Шаг 2.4 — settings_cache.py
Загрузка настроек из bot_settings в кэш с TTL 5 минут
Методы: get_bot_token(), get_assistant_name(), get_phones(), get_email(), is_feature_enabled(), get_template()
Шаг 2.5 — max_api.py (Max API клиент)
Методы: get_me(), send_message(), send_message_with_keyboard(), send_file(), get_file_url(), subscribe_webhook(), send_contact_request()
Шаг 2.6 — fsm.py (конечный автомат)
Состояния: IDLE, MAIN_MENU, NAME_REQUEST, CONSENT_REQUEST, CONTACT_REQUEST, INQUIRY_REQUEST, CATEGORY_SELECT, CONFIRMATION, HANDOFF_REQUEST, HANDOFF_CONFIRMATION, OUT_OF_HOURS, FEATURE_RISK_SCORE, FEATURE_SLA_STATUS, FEATURE_PHOTO_REPORT, FEATURE_APPOINTMENT, FEATURE_QUALITY_RATE, FEATURE_COMMERCIAL, FEATURE_MY_OBJECTS, SLA_TICKET_CREATE
Словарь переходов STATE_TRANSITIONS
Шаг 2.7 — bot_engine.py
Функция handle_update(): приём webhook → определение события (message_created, bot_started, callback) → загрузка состояния из БД → вызов соответствующего handler → возврат ответа
Шаг 2.8 — conversation.py (управление диалогами)
CRUD для bot_conversations, bot_messages
Обновление last_active_at у BotUser
Шаг 2.9 — text_renderer.py
Рендер шаблонов с подстановкой {name}, {id}, {phone_1}, {phone_2}, {email}, {work_hours}, {policy_url}
Шаг 2.10 — main.py (FastAPI приложение)
lifespan: инициализация MaxAPIClient, SettingsCache
POST /webhook — приём событий от Max, проверка заголовка X-Max-Bot-Api-Secret, вызов handle_update()
GET /health — health check
Этап 3 — Базовый секретарь (не отключаемый)
Шаг 3.1 — handlers/greeting.py
Обработка /start и любого первого сообщения
Проверка истории клиента (есть ли открытые диалоги)
Отправка приветствия + главное меню (Оставить заявку, Задать вопрос, Связаться с оператором, активные фичи)
Шаг 3.2 — handlers/consent.py
Запрос согласия на обработку ПД (ФЗ-152)
Кнопка "✅ Даю согласие" + ссылка на политику
Логирование в bot_consent_logs
При отказе: показать телефоны (tel:) и email (mailto:) — кликабельные
При согласии: переход к сбору контакта
Шаг 3.3 — handlers/contact.py
Кнопка "📱 Поделиться контактом" (request_contact)
Или ручной ввод телефона/email с валидацией
Шаг 3.4 — handlers/inquiry.py
Приём текста обращения, фото, документов (PDF, DOCX, XLSX, TXT)
Сохранение вложений локально + создание записи в file_sync_queue
Авто-категоризация: YandexGPT (если ключ есть) → ключевые слова
Показ inline-кнопок с категориями для подтверждения
Шаг 3.5 — handlers/handoff.py
Проверка рабочего времени (Пн-Пт 9:00-18:00 МСК, настраиваемое)
Передача диалога оператору
Шаг 3.6 — handlers/out_of_hours.py
Уведомление: "Сейчас мы не работаем. Рабочее время: ..."
Тот же сбор данных (имя → согласие → контакт → обращение)
В подтверждении: уточнение что нерабочее время
Шаг 3.7 — handlers/main_menu.py
Динамическое меню: базовые кнопки + активные фичи из bot_features
Обработка выбора пункта меню
Этап 4 — Фичи (toggle on/off через портал)
Шаг 4.1 — handlers/features/risk_score.py
5-7 вопросов по объекту → расчёт Risk Score
Шаг 4.2 — handlers/features/sla_status.py
Поиск объекта → статус SLA, последний визит, открытые задачи
Шаг 4.3 — handlers/features/photo_report.py
Приём фото → создание инцидента
Шаг 4.4 — handlers/features/appointment.py
Выбор слота → запись на визит
Шаг 4.5 — handlers/features/quality_rate.py
Оценка 1-5 после закрытия обращения
Шаг 4.6 — handlers/features/commercial.py
Сбор параметров → генерация КП
Шаг 4.7 — handlers/features/my_objects.py
Сводка по объектам клиента
Шаг 4.8 — handlers/features/sla_ticket.py
Проверка активного SLA → создание заявки о неисправности
Приоритет: start→low, business→normal, enterprise→high
Уведомление инженера через MAX (Level 2, max_user_id)
Шаг 4.9 — handlers/features/notifications.py
Авто-уведомления при изменении статуса
Шаг 4.10 — handlers/features/broadcasts.py
Отправка сообщений всем согласным пользователям
Шаг 4.11 — integrations/yandex_gpt.py
YandexGPT API клиент для категоризации и анализа эмоций
Fallback на ключевые слова, если ключ пуст
Шаг 4.12 — utils/emotion_detector.py
Анализ эмоций: YandexGPT → ключевые слова-маркеры
Негатив → эскалация оператору
Шаг 4.13 — utils/categorizer.py
Авто-категоризация: YandexGPT → ключевые слова
Этап 5 — Интеграции
Шаг 5.1 — integrations/1c_unf.py
POST webhook в 1С:УНФ с данными клиента
GET /api/1c/response — приём ответов от 1С
Шаг 5.2 — integrations/portal_db.py
Чтение данных клиентов/объектов/SLA из общей БД
Шаг 5.3 — yandex_disk.py (в py_service)
YandexDiskClient: upload, download, list, search, publish, delete, create_folder
Шаг 5.4 — file_storage.py (в max_bot)
Сохранение файлов локально → создание записи в file_sync_queue
Шаг 5.5 — file_sync.py (в py_service)
Фоновый процесс: каждые 60 сек проверка file_sync_queue → загрузка на Яндекс.Диск → удаление локального файла
Шаг 5.6 — max_notifications.py (в py_service)
Отправка уведомлений инженерам через MAX API (Level 2 — по max_user_id)
B. Проведи ПОЛНЫЙ ГЛУБОКИЙ анализ и сопоставь проработанные этапы 1-5. Все верно и соответствует друг другу? Что необходимо откорректировать для 100% работоспособности этапов 1-5?
C. Проведи ПОЛНЫЙ ГЛУБОКИЙ анализ и сопоставь проработанные этапы 1-5 с сервисным порталом? Есть ли функционал в портале не реализованный для правильной работы бота по пройденым этапам 1-5? Что необходимо откорректировать для 100% работоспособности этапов 1-5? Текущие настройки для бота берутся из "Чат-бот Max — Настройки"