# 01-BRD — ORCH-017: Прямые ссылки на BRD и Plane-таску в Telegram-уведомлении об апруве Work Item: **ORCH-017** Repo: `orchestrator` · Branch: `feature/ORCH-017-brd-plane-telegram` Тип: косметическая правка (UX уведомлений). Парная с ORCH-016. ## 1. Бизнес-контекст и проблема Когда оркестратор завершает стадию `analysis` и просит подтвердить BRD, в Telegram уходит отдельное «пингующее» уведомление (`notify_approve_requested` в `src/notifications.py`). Сейчас в этом сообщении **нет ссылок**: владелец (Слава) вынужден вручную зайти в Plane, найти нужную issue, открыть комментарий аналитика, оттуда перейти к BRD-документу. Это лишние ручные шаги на каждой задаче. Текущий текст уведомления: > 📋 {WI}: BRD/ТЗ/AC готовы. Переведите задачу в статус Approved в Plane для продолжения. ## 2. Цель В **этом же** уведомлении дать две прямые кликабельные ссылки, чтобы весь сценарий прохождения апрува выполнялся из Telegram, без ручной навигации в Plane: 1. **Ссылка на BRD** — открывает `01-brd.md` в Gitea (прочитать документ). 2. **Ссылка на Plane-issue** — открывает задачу в Plane (перевести в Approved / отклонить с комментом). ## 3. Целевой сценарий (Слава) Получил уведомление → кликнул «📄 BRD» → прочитал → кликнул «✅ Задача» → перевёл в Approved (или отклонил с комментарием). Всё из Telegram. ## 4. Объём (Scope) ### В объёме (выбранный по умолчанию минимальный вариант — см. §8 открытые вопросы) - Доработка **только** функции `notify_approve_requested(task_id)` в `src/notifications.py` (стадия `analysis`, запрос статуса Approved). - Формирование двух ссылок и встраивание их в текст того же отдельного уведомления. - Формат — HTML-ссылки в тексте (`label`), т.к. `send_telegram` уже шлёт `parse_mode="HTML"`. Альтернатива (inline-кнопки) — открытый вопрос §8. - Новая конфиг-настройка для внешнего web-URL Plane (см. §6, риск №1). - Обновление документации (`CLAUDE.md` env-карта при необходимости, `CHANGELOG.md`, `.env.example`) в том же PR. ### Вне объёма (НЕ трогать) - Логика апрува: `:approved:`-handler, `check_analysis_approved`, переходы стадий. - Живой Telegram-трекер (`update_task_tracker` / `render_task_tracker`, PR #21/#22) — его текст и поведение не меняем; новое уведомление остаётся ОТДЕЛЬНЫМ сообщением, дубли трекера не создаём. - Содержимое комментариев в Plane (это смежная задача ORCH-016). - Ссылки в других уведомлениях (deploy-failed, agent-failed, error) — вне объёма по умолчанию (см. открытый вопрос §8.2). ## 5. Заинтересованные стороны - **Owner / получатель уведомления:** Слава. - **Поставщик данных:** оркестратор (БД `tasks`: repo, branch, work_item_id, plane_issue_id). ## 6. Функциональные требования | # | Требование | |---|------------| | FR-1 | Уведомление об апруве BRD содержит кликабельную ссылку на документ `docs/work-items//01-brd.md` в Gitea. | | FR-2 | То же уведомление содержит кликабельную ссылку на соответствующую Plane-issue. | | FR-3 | Существующий текст-призыв («Переведите задачу в статус Approved …») сохраняется. | | FR-4 | Уведомление остаётся ОДНИМ отдельным пингующим сообщением (без дублей, без второго сообщения). | | FR-5 | Ссылка на BRD строится на внешнем `gitea_public_url` (фоллбэк `gitea_url`), формат branch-view: `{base}/{owner}/{repo}/src/branch/{branch}/docs/work-items/{WI}/01-brd.md`. Переиспользовать существующий паттерн из `src/usage.py`. | | FR-6 | Ссылка на Plane-issue строится на внешнем web-URL Plane + workspace + project + issue. | ## 7. Нефункциональные требования | # | Требование | |---|------------| | NFR-1 | **Никогда не ронять оркестратор** из-за уведомления: построение ссылок обёрнуто в защиту, при отсутствии данных (нет branch / нет plane_issue_id / не задан web-URL) — сообщение всё равно отправляется, просто без соответствующей ссылки (graceful degradation). | | NFR-2 | Не нарушать self-hosting: правка не требует рестарта прод-контейнера сверх обычного деплоя; не меняет реестр гейтов/стадий. | | NFR-3 | Сохранить `parse_mode="HTML"`; экранировать динамические подписи (`html.escape`), URL формировать из доверенных конфиг-значений. | ## 8. Открытые вопросы (требуют решения Owner; в документах принят безопасный дефолт) 1. **Формат ссылок.** Дефолт BRD: HTML-ссылки в тексте (минимальная правка). Альтернатива — inline-кнопки «📄 Открыть BRD» / «✅ К задаче в Plane», что требует доработки `send_telegram` (параметр `reply_markup`/`inline_keyboard`). → решение к стадии architecture. 2. **Охват.** Дефолт: только BRD-апрув (`notify_approve_requested`). Альтернатива — все точки, требующие решения Славы (напр. согласование макета ORCH-14). → если «все точки», объём расширяется, нужен отдельный перечень событий. 3. **Внешний web-URL Plane.** В конфиге сейчас только внутренний `plane_api_url` (`http://localhost:8091`) — он НЕ годится для браузерной ссылки. Дефолт: завести новую env-настройку `ORCH_PLANE_WEB_URL` (внешний адрес Plane) с фоллбэком на `plane_api_url`. Точное значение URL должен подтвердить Owner/INFRA. 4. **Формат Plane-ссылки.** `…/{workspace}/projects/{project_id}/issues/{issue_id}/` (надёжно, issue_id есть в `tasks.plane_issue_id`) vs короткий `…/{workspace}/browse//` (зависит от соответствия `work_item_id` ↔ Plane identifier, что не гарантировано из-за zero-padding ORCH-017 vs ORCH-17). → решение к стадии architecture. ## 9. Зависимости и связки - **PR #14** — `gitea_public_url`: переиспользуем для кликабельных ссылок на доки. - **PR #21/#22** — живой Telegram-трекер: новое сообщение остаётся отдельным, трекер не трогаем. - **ORCH-016** — единые коммент-артефакты в Plane (парная задача про навигацию к документам). ## 10. Критерий бизнес-успеха Слава из одного Telegram-уведомления одним кликом открывает BRD и одним кликом — задачу в Plane, не заходя в Plane вручную и не ища комментарий.