# ADR-004: слоистая организация Telegram-бота **Статус:** Принято **Дата:** 2026-07-23 ## Контекст Telegram-бот принимает команды и callback-запросы, проверяет привязку пользователя, обращается к PostgreSQL и REST API Битрикс24, а затем формирует HTML-сообщения и inline-клавиатуры. ## Решение Бот организован по слоям: обработчики принимают события Telegram, middleware добавляет проверенную привязку в контекст, сервисы реализуют прикладные сценарии, `BitrixClient` отвечает за OAuth и HTTP, а классы представления формируют HTML-тексты и inline-клавиатуры. ![UML-диаграмма основных классов решения](assets/report/bot-class-diagram.png) *Рисунок ADR-004/1. UML-диаграмма основных классов решения* Классы `Binding`, `OAuthCredentials`, `ClientInfo`, `DealStageFilter` и `DealPage` являются dataclass-моделями передачи данных. Они отделяют словари REST-ответов и строки БД от интерфейсов сервисов. `DealPage` дополнительно вычисляет признак `has_next`, который используется при построении кнопок пагинации. Основные команды и callback-действия Telegram-бота приведены в таблице. | Ввод | Обработчик | Результат | |-----------------------------------------|---------------------------------|--------------------------------------------| | /start, /help | StartBotHandlers.start | Справка или состояние привязки | | /start bind_<token> | StartBotHandlers.bind | Погашение одноразовой ссылки в личном чате | | /deals, /leads | DealBotHandlers.deals | Первая страница сделок начальной стадии | | /deal ID, /lead ID | DealBotHandlers.deal_by_command | Карточка сделки по идентификатору | | deals:page:<stage>:<page> | deals_page | Фильтрация по стадии и пагинация | | deal:view:<id> | deal_by_button | Карточка выбранной сделки | | deal:assign:<id>:<expected> | assign_responsible | Назначение текущего Битрикс-пользователя | | deal:remind:<id> | remind_to_call | Создание дела на звонок через час | | deal:history:<id> | show_history | Пять последних переходов по стадиям | *Таблица ADR-004/1. Пользовательские команды и callback-действия* Навигация по страницам списка, переход к карточке и возврат выполняются кнопками клавиатуры с редактированием исходного сообщения бота. Список сделок также поддерживает фильтрацию, которая задаётся дополнительными кнопками на странице просмотра списка. Перед выполнением CRM-команд `BindingRequiredMiddleware` ищет привязку по Telegram user id. При успешной проверке объект `Binding` помещается в словарь `data` и передаётся именованным параметром обработчика. Если привязки нет, цепочка прерывается до REST-запроса, а пользователь получает инструкцию открыть приложение в Битрикс24. ## Последствия Конструкторы принимают зависимости явно, поэтому сервисы можно тестировать с имитационными репозиториями и REST-клиентами. Проверка middleware ограждает пользователя от ошибочного поведения и гарантирует наличие привязки перед обращением к CRM.