Files
orchestrator/docs/work-items/ORCH-042/02-trz.md
claude-bot 66100855f6
All checks were successful
CI / test (push) Successful in 15s
analyst(ET): auto-commit from analyst run_id=167
2026-06-06 09:49:58 +00:00

9.7 KiB
Raw Blame History

02 — ТЗ: Telegram live-tracker, режим bump + русификация

Work Item: ORCH-042 · См. 01-brd.md, 03-acceptance-criteria.md.

1. Задействованные модули src/

Файл Что меняется
src/config.py Новое поле Settings.tracker_mode (env ORCH_TRACKER_MODE).
src/notifications.py Новый helper delete_telegram(message_id); ветвление update_task_tracker по режиму; текстовые правки в _BRD_LABEL, _TRACKER_STAGES, BRD-строке render_task_tracker, _done_link.

БД — без изменений (используется существующая колонка tasks.tracker_message_id и хелперы get_tracker_message_id / set_tracker_message_id в src/db.py). API HTTP-эндпоинты оркестратора — без изменений. Новые QG checks — не требуются.

2. Изменения конфигурации (src/config.py)

Добавить в класс Settings (рядом с блоком «Telegram notifications»):

# ORCH-042: режим live-трекера задачи.
#   edit -> карточка редактируется на месте (editMessageText), ДЕФОЛТ (как было).
#   bump -> при обновлении старое сообщение удаляется и карточка отправляется
#           заново вниз чата (deleteMessage + sendMessage + repoint message_id),
#           тихо (disable_notification). Одна карточка на задачу в обоих режимах.
# Неизвестное/пустое значение трактуется как edit (см. notifications).
tracker_mode: str = "edit"
  • env_prefix = "ORCH_" уже задан → переменная окружения ORCH_TRACKER_MODE.
  • Резолюция режима — в notifications: всё, что не равно (case-insensitive, trimmed) "bump", считается edit. Не падать на любом значении.

3. Изменения нотификаций (src/notifications.py)

3.1. Новый low-level helper delete_telegram

Рядом с send_telegram / edit_telegram. Контракт «never raises».

def delete_telegram(message_id: int) -> bool:
    """Delete a Telegram message. Never raises.

    Returns True if the message is gone after the call (deleted now, OR Telegram
    says it's already not there / can't be deleted -> treat as "no longer our
    problem", caller proceeds to send a fresh card). Returns False only on a
    transient failure (network / timeout / 5xx / unknown error) where the old
    message may still be alive.
    """

Требования к реализации:

  • Эндпоинт https://api.telegram.org/bot{token}/deleteMessage, тело {chat_id, message_id}, timeout=5.
  • Нет токена/chat_id → вернуть False (как и прочие helpers при отсутствии кредов — ничего не отправлено, ничего не удалено).
  • ok:trueTrue.
  • ok:false с описанием «уже нет / нельзя удалить» (маркеры: "message to delete not found", "message can't be deleted", "message_id_invalid") → True (сообщение и так недоступно; не транзиент).
  • Прочие ok:false (неизвестный 400 / 5xx) и исключения (сеть/таймаут) → False + logger.warning.
  • Вынести маркеры в модульную константу (по аналогии с _GONE_MARKERS), например _DELETE_GONE_MARKERS.

3.2. Ветвление update_task_tracker по режиму

Сохранить существующий путь edit без изменений поведения. Добавить путь bump.

Псевдокод целевой логики:

def update_task_tracker(task_id: int):
    try:
        from .db import get_tracker_message_id, set_tracker_message_id
        text = render_task_tracker(task_id)
        mode = (_get_settings().tracker_mode or "edit").strip().lower()
        mid = get_tracker_message_id(task_id)

        if mode == "bump":
            # bump: одна карточка, но всегда внизу.
            if mid is not None:
                delete_telegram(mid)   # best-effort; fallback -> всё равно шлём новое
            new_mid = send_telegram(text, disable_notification=True)
            if new_mid is not None:
                set_tracker_message_id(task_id, new_mid)
            # send вернул None (нет кредов / транзиент) -> mid не трогаем,
            # дубля в пределах вызова нет; перерисуется на следующем переходе.
            return

        # mode == "edit" (ДЕФОЛТ): существующая логика без изменений.
        ...  # текущий код edit/EDIT_GONE-fallback as is
    except Exception as e:
        logger.warning(f"update_task_tracker({task_id}) failed: {e}")

Инварианты bump-ветки:

  • В пределах ОДНОГО вызова отправляется максимум одно новое сообщение → дублей нет (BR-7).
  • set_tracker_message_id вызывается ТОЛЬКО при успешном send (new_mid is not None). При сбое send id остаётся прежним; на следующем переходе старый будет удалён (или уже мёртв) и отправлен новый — без накопления карточек.
  • delete_telegram — best-effort: его результат НЕ блокирует отправку новой карточки (BR-6: delete-fail → всё равно шлём новое).
  • Bump всегда тихий: disable_notification=True (BR-4).

3.3. Текстовые правки (общие для обоих режимов)

BR Где Было Стало
BR-9 _BRD_LABEL (модульная константа) "Ревью БРД" "Подтверждение BRD"
BR-10 render_task_tracker, ветка BRD-строки при review_seconds is not None префикс ⏸️ (⏸️) (). Ветка ожидания (review_seconds is None, с ) — НЕ менять.
BR-11 _TRACKER_STAGES (метки) Analysis / Architecture / Development / Review / Testing / Deploy Анализ / Архитектура / Разработка / Код ревью / Тестирование / Внедрение
BR-12 _done_link "\U0001f4e6 deployed" "\U0001f4e6 Внедрено"

Примечания:

  • В _TRACKER_STAGES меняется ТОЛЬКО display-label (2-й элемент кортежа). Ключи стадий (analysis,…) и имена агентов (analyst,…) НЕ трогать — они завязаны на _STAGE_ACTIVE_AGENT, last_done, БД.
  • Выравнивание {label:<13} и {_BRD_LABEL:<13} оставить как есть (все новые русские метки ≤13 символов; «Подтверждение BRD» длиннее — формат просто не паддит, косметика, поведение не ломает).
  • Метки используются и в « …»-строках завершённых стадий, и в «🔄 … идёт»-строке активной стадии — обе автоматически станут русскими (правка в одном месте).

4. Совместимость и риски

  • Дефолт edit гарантирует нулевую регрессию без явного включения bump (BR-8). Подробно — 10-tech-risks.md (заводит архитектор/девелопер при необходимости).
  • Самохостинг: изменения только в коде нотификаций, миграций БД нет, перезапуск self — по стандартной страховке deploy-staging (8501) перед prod (см. CLAUDE.md).

5. Артефакты pipeline, которые ДОЛЖНЫ быть обновлены в этом же PR

  • CHANGELOG.md → запись в [Unreleased] / Added (режим bump) + Changed (русификация текста).
  • docs/architecture/internals.md — секция про live-tracker: режимы edit/bump, ORCH_TRACKER_MODE, контракт delete_telegram.
  • .env.exampleORCH_TRACKER_MODE=edit с комментарием.
  • Тесты — см. 04-test-plan.yaml. Существующие тесты в tests/test_telegram_tracker.py, проверяющие англоязычные метки ("✅ Analysis", "🔄 Deploy", "Review") и метку "Ревью БРД", ОБЯЗАТЕЛЬНО обновить под новые русские строки — иначе регрессия в CI. Это правка существующих ассертов, не изменение контракта.

6. Замечания по реализации (без расширения scope)

  • Не вводить новых зависимостей; httpx уже используется.
  • Не менять сигнатуры send_telegram / edit_telegram / update_task_tracker (внешние вызовы из launcher/stage_engine не трогаются).
  • Не менять состав отдельных пингов (approve-gate / error / deploy-fail / agent-fail).