# 02-ТЗ — ORCH-017: Прямые ссылки в Telegram-уведомлении об апруве BRD Work Item: **ORCH-017** · Repo: `orchestrator` Опирается на 01-brd.md. Уточняет конкретные изменения кода/конфигурации. > Примечание по канону: ТЗ фиксирует ТРЕБОВАНИЯ к изменениям, а не готовое > архитектурное решение. Выбор формата (текст vs inline-кнопки) и точного формата > Plane-URL — за стадией architecture (см. открытые вопросы 01-brd.md §8). Если по > ходу разработки ТЗ окажется неполным/неверным — возврат на стадию Анализ, без > правок ТЗ задним числом. ## 1. Задействованные модули `src/` | Модуль | Роль в задаче | |--------|---------------| | `src/notifications.py` | **Основной.** Функция `notify_approve_requested(task_id)` (≈ строки 547–566) — единственная точка отправки пингующего уведомления об апруве BRD. Сюда добавляются ссылки. | | `src/config.py` | Класс `Settings`. Добавить настройку внешнего web-URL Plane (`plane_web_url`, env `ORCH_PLANE_WEB_URL`) с дефолтом-фоллбэком. | | `src/projects.py` | (Чтение) `get_project_by_repo(repo)` → `plane_project_id` для построения Plane-URL. | | `src/usage.py` | (Референс, не править) Эталонный паттерн branch-view ссылки на доки (`{base}/{owner}/{repo}/src/branch/{branch}/`), строки ≈483–503 — переиспользовать тот же формат. | | `src/db.py` | (Чтение) Таблица `tasks`: поля `work_item_id`, `repo`, `branch`, `plane_issue_id`. Источник данных для ссылок. | ## 2. Источники данных (из `tasks` по `task_id`) - `work_item_id` — путь к BRD-документу и (опц.) идентификатор issue. - `repo`, `branch` — построение Gitea branch-view URL. - `plane_issue_id` — uuid issue в Plane для прямой ссылки. - `project_id` — через `projects.get_project_by_repo(repo).plane_project_id`. `notify_approve_requested` сейчас принимает только `task_id` и тянет лишь `work_item_id` через `_get_work_item_id`. Требуется дополнительно прочитать `repo`, `branch`, `plane_issue_id` из `tasks` (один SELECT, в защищённом try/except). ## 3. Требуемые изменения ### 3.1 `src/notifications.py` - Построить **BRD-ссылку** (FR-1/FR-5): `{base}/{owner}/{repo}/src/branch/{branch}/docs/work-items/{work_item_id}/01-brd.md`, где `base = (settings.gitea_public_url or settings.gitea_url).rstrip('/')`, `owner = settings.gitea_owner`. Если нет `base`/`repo`/`branch`/`work_item_id` — ссылку опустить (NFR-1). - Построить **Plane-ссылку** (FR-2/FR-6): `{plane_web_base}/{workspace_slug}/projects/{project_id}/issues/{plane_issue_id}/` (точный формат — решение architecture, см. 01-brd §8.4). Если нет данных — опустить. - Встроить обе ссылки в текст того же сообщения (FR-3/FR-4), формат HTML-`` по умолчанию. Сохранить существующий призыв «Переведите задачу в статус Approved …». - Сохранить вызов как **одно** `send_telegram(msg)` (пингующее, не silent). Порядок существующих действий не менять: старт BRD-часов (`mark_brd_review_started`) → `update_task_tracker(task_id)` → `send_telegram(msg)`. - Динамические подписи экранировать `html.escape` (NFR-3). ### 3.2 `src/config.py` - Добавить в `Settings` поле `plane_web_url: str = ""` (env `ORCH_PLANE_WEB_URL`). - Семантика фоллбэка: `plane_web_base = (settings.plane_web_url or settings.plane_api_url).rstrip('/')`. ### 3.3 Опционально (если выбран вариант inline-кнопок — открытый вопрос 01-brd §8.1) - Расширить `send_telegram(text, disable_notification=False, reply_markup=None)`: при наличии `reply_markup` прокидывать его в payload `sendMessage`. Обратная совместимость — обязательна (текущие вызовы без аргумента работают как раньше). - ⚠️ Это РАСШИРЯЕТ объём; включается только по явному решению Owner на стадии architecture. ## 4. Изменения API Нет. Публичные HTTP-эндпоинты (`/webhook/*`, `/status`, `/queue`, `/health`) не затрагиваются. ## 5. Изменения схемы БД Нет. Все нужные поля (`repo`, `branch`, `work_item_id`, `plane_issue_id`) уже существуют в `tasks`. ## 6. Изменения конфигурации / окружения - Новая env-переменная `ORCH_PLANE_WEB_URL` (внешний web-адрес Plane). Прописать в `.env.example` (канон секретов/настроек), описать в env-карте (`CLAUDE.md` / `docs/operations/INFRA.md`). Реальное значение задаётся в `.env`/`.env.staging` на хосте. - Существующие `ORCH_GITEA_PUBLIC_URL`, `ORCH_GITEA_OWNER`, `ORCH_PLANE_WORKSPACE_SLUG` переиспользуются как есть. ## 7. Требования к новым QG checks Нет. Реестр `QG_CHECKS`, стадии и машинные вердикты не меняются (правка — отображение, не управление конвейером). ## 8. Артефакты pipeline, которые должны быть обновлены в ЭТОМ PR - `CHANGELOG.md` — запись о фиче. - `.env.example` — новая `ORCH_PLANE_WEB_URL`. - При добавлении настройки — env-карта в `CLAUDE.md` / `docs/operations/INFRA.md`. - ADR (стадия architecture): `docs/work-items/ORCH-017/06-adr/ADR-001-*.md` — фиксирует выбор формата (текст vs кнопки) и формат Plane-URL. ## 9. Ограничения - Не трогать `:approved:`-handler и `check_analysis_approved` (только текст/формат уведомления). - Не плодить сообщения: одно отдельное пингующее сообщение; живой трекер (PR #21/#22) не дублировать. - Соблюдать self-hosting: не ронять/не рестартить прод сверх штатного деплоя; обязательная страховка `deploy-staging` (8501) перед прод-деплоем орка.