9.7 KiB
9.7 KiB
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:true→True.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.example—ORCH_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).