4.3 KiB
ADR-006: изменение сделки с проверкой актуального состояния
Статус: Принято
Дата: 2026-07-23
Контекст
Состояние сделки может измениться в Битрикс24 после формирования карточки в
Telegram, но до нажатия callback-кнопки. Используемый метод crm.deal.update не
предоставляет условный UPDATE, поэтому перед изменением требуется проверить,
что показанное пользователю состояние остаётся актуальным.
Решение
Назначение ответственного и изменение стадии
Callback-кнопка назначения содержит не только id сделки, но и ASSIGNED_BY_ID,
который был показан пользователю:
deal:assign:<deal_id>:<expected_responsible_id>. Перед изменением сервис
повторно загружает сделку и сравнивает фактического ответственного с ожидаемым.
Если карточка устарела, REST-обновление не выполняется.
Внутри одного процесса операции по паре (member_id, deal_id) последовательно
выполняются под asyncio.Lock. После crm.deal.update сервис повторно читает
сделку и убеждается, что ответственным стал bitrix_user_id привязанного
пользователя.
Рисунок ADR-006/1. Диаграмма последовательности взятия сделки в работу
При обновлении одновременно передаются ASSIGNED_BY_ID связанного пользователя,
рабочая STAGE_ID и параметр REGISTER_HISTORY_EVENT=Y. После REST-запроса
выполняется контрольное чтение сделки.
Планирование звонка и просмотр истории
Действие «Позвонить позже» создаёт в Битрикс24 дело типа todo с крайним сроком
через один час. Владельцем является сделка (ownerTypeId=2), а ответственным —
связанный пользователь Битрикс24. Массив pingOffsets=[0] включает напоминание
в момент наступления срока.
История загружается методом crm.stagehistory.list с фильтром OWNER_ID и
сортировкой по убыванию идентификатора. В интерфейс выводятся первые пять
событий. Для каждого события идентификатор стадии преобразуется в название с
учётом CATEGORY_ID, после чего DealFormatter формирует защищённый HTML-текст
и клавиатуру возврата к карточке или списку.
Рисунок ADR-006/2. Диаграмма последовательности планирования звонка и просмотра истории
Последствия
Локальный asyncio.Lock защищает только один процесс bot. При горизонтальном
масштабировании на несколько контейнеров потребуется распределённая блокировка
либо серверная условная операция. Повторная проверка REST-результата сохраняет
защиту от внешних изменений, но не делает два удалённых вызова одной транзакцией
Битрикс24.

