Files
orchestrator/docs/work-items/ORCH-080/06-adr/ADR-001-disable-telegram-link-preview.md

5.3 KiB
Raw Blame History

ADR-001: Подавление Telegram link-preview в низкоуровневых примитивах нотификаций

Статус

Accepted

Контекст

С ORCH-067 карточка трекера и notify-сообщения несут кликабельный номер задачи <a href="https://plane.mva154.duckdns.org/.../issues/<id>/">ORCH-NNN</a>. Telegram Bot API по умолчанию (при отсутствии ключа disable_web_page_preview) разворачивает web-page-preview для первой ссылки в сообщении — под каждым сообщением трекера раскрывается баннер «Plane — Modern project management». В дефолтном режиме bump (ORCH-067) карточка пересоздаётся на каждом переходе, поэтому баннер дублируется на каждой задаче и каждом обновлении, засоряя ленту (жалоба Owner, 08.06).

Код-аудит (src/notifications.py) подтвердил причину: JSON-payload обоих низкоуровневых примитивов — send_telegram() (POST /sendMessage, стр. 55-60) и edit_telegram() (POST /editMessageText, стр. 168-173) — не содержит ключ disable_web_page_preview. Все вышестоящие нотификации (update_task_tracker в обоих режимах, notify_approve_requested, notify_error, alert'ы стадий из launcher/stage_engine) проходят через эти два примитива.

Решение

Добавить "disable_web_page_preview": True в JSON-payload httpx.post обоих примитивов: send_telegram() и edit_telegram(). Изменение — на уровне низкоуровневого примитива, а не на уровне каждого вызова, потому что:

  1. Единая точка — все исходящие сообщения трекера/нотификаций идут через эти две функции; правка двух строк гасит баннер у ВСЕХ потребителей (карточка bump/edit, notify-хелперы, alert'ы) без изменения их кода.
  2. Безусловно, без флага — превью Plane не нужно никому (это не данные, а навигация по ссылке, которая остаётся кликабельной). Kill-switch не вводится: риск регрессии нулевой, правка обратима одной строкой. Это согласуется с принципом «минимум зависимостей/конфигурации».
  3. Top-level флаг, а не link_preview_options.is_disabled — top-level disable_web_page_preview остаётся валиден и обратносовместим в Bot API; это минимальная правка без введения вложенной структуры.

parse_mode: "HTML" сохраняется в обоих payload (иначе <a href> перестанет рендериться — ссылка должна остаться кликабельной). disable_notification, bump/edit-логика, repoint tracker_message_id, delete-семантика, контракты возврата (send_telegram → message_id|None, edit_telegram → EDIT_*) — не затрагиваются.

Последствия

Плюсы:

  • Баннер link-preview исчезает под карточкой трекера (оба режима) и под всеми notify/alert-сообщениями — одна правда в двух примитивах.
  • Ссылка на задачу остаётся кликабельной (HTML сохранён).
  • Нулевой риск: ключ аддитивный, контракты примитивов и инвариант «одна карточка на задачу» не меняются; never-raise (try/except) сохранён.

Минусы / ограничения:

  • Поведение безусловное — нет конфигурации «вернуть превью». Сознательный выбор: превью трекера не имеет ценности, флаг был бы лишней поверхностью.

Не затрагивается: STAGE_TRANSITIONS, реестр QG_CHECKS, схема БД, parse_mode, disable_notification, транспортные хелперы delete_telegram/repoint-логика. Глобальный ADR не требуется — решение локально для src/notifications.py, не сквозное.

Self-hosting

Изменение не требует немедленного рестарта прод-контейнера и не меняет топологию. Деплой — штатный через staging (8501) → Confirm Deploy (ORCH-059). По ORCH-026 (сериализация merge одного репо) задача мержится после освобождения конвейера orchestrator (координация с ORCH-074 — см. BRD §7).