- шесть записей по кластерам причин: журнал под внешним значением, нулевой код ответа в журнале, затирание вложения бедным ответом, открытый анониму адрес подтверждения почты, рубеж расшифровки без работы, пределы длительности - находка про код 500 у отказа приёма дописана в json-api-for-spa: там живёт единая точка отображения доменной ошибки - telegram-account-link и bot-api-only-through-bot-client оставлены с оговоркой, что предмета у них нет до возвращения входа
58 lines
4.7 KiB
Markdown
58 lines
4.7 KiB
Markdown
# 🧹 Запретить обращаться к Bot API мимо клиента бота
|
||
|
||
- **Тип:** chore
|
||
- **Категория:** Очередь — Правило границы клиента ставится на тот же транспорт, мелочи которого разбирает строка выше: своя обёртка, заведённая раньше правила, вернёт утечку токена молча.
|
||
- **Зачем:** Чистка отказа от адреса с токеном живёт в клиенте; свой http.Client в транспорте вернёт утечку молча — правило noctx такую подмену не ловит, а класс уже стоил одного дефекта.
|
||
|
||
Токен бота стоит в пути каждого обращения к Bot API, а `http.Client` кладёт
|
||
адрес запроса в `*url.Error` целиком. Поэтому 2026-08-13 чистка перенесена на
|
||
границу клиента: `internal/adapter/telegram`, `NewBot` — свой `Do` разворачивает
|
||
отказ в первопричину, а подменённый логгер вычищает токен из строк самой
|
||
библиотеки. Случай записан в журнал дефектов
|
||
[review.md](../../docs/review.md), 2026-08-13.
|
||
|
||
Держится это на двух стыках, и оба обходятся одной строкой: скачивание записи
|
||
берёт клиента у бота (`c.bot.Client.Do`), а не общий, и бот заводится единой
|
||
точкой, а не `tgbotapi.NewBotAPI`. Проверки на оба стыка есть
|
||
(`internal/controller/tg/download_test.go`,
|
||
`internal/adapter/telegram/bot_test.go`), но они судят **сегодняшние** места:
|
||
новый файл в транспорте, заведший свой клиент, они не увидят.
|
||
|
||
Ступень по лестнице механизации — четвёртая: свойство о структуре, а не о
|
||
вызове, и выражается тест-сканером в `internal/archrules`.
|
||
|
||
|
||
**Предмета у задачи сейчас нет.** Клиент бота удалён вместе со входом задачей
|
||
`remove-telegram-intake` 2026-08-15 — временно, решение записано
|
||
[ADR-2026-08-15-telegram-intake-removed-temporarily](../../docs/adr/ADR-2026-08-15-telegram-intake-removed-temporarily.md).
|
||
Запись остаётся гигиеной **возврата**: класс стоил проекту одного дефекта, и
|
||
запрет надо ставить вместе с новым клиентом, а не после него.
|
||
|
||
## Затрагивает
|
||
|
||
- `internal/archrules` — новое правило-сканер и его перечень предметов;
|
||
- `internal/controller/tg` — как поднадзорный пакет;
|
||
- `internal/adapter/telegram` — как единственное законное место, где клиент
|
||
заводится;
|
||
- [go-linters.md](../../docs/conventions/go-linters.md) — строка в перечне
|
||
механизированного и снятие соответствующей прозы.
|
||
|
||
## Критерии приёмки
|
||
|
||
- Свой `http.Client`, `http.DefaultClient` или `tgbotapi.NewBotAPI` в
|
||
`internal/controller/tg` роняет проверку и называет файл. Оракул — мутация:
|
||
внести каждую из трёх форм по очереди, все три краснеют.
|
||
- Законное употребление в `internal/adapter/telegram` проверку не роняет.
|
||
Оракул — тот же прогон на нетронутом дереве, зелёный.
|
||
- Правило не молчит, потеряв предмет: переименованный или исчезнувший пакет
|
||
роняет проверку, а не проходит обходом по пустому перечню. Оракул — мутация с
|
||
переименованием каталога.
|
||
- Правило записано строкой в `go-linters.md`, и проза, которую оно заменило,
|
||
оттуда снята. Оракул — чтение записи.
|
||
|
||
## Рамки
|
||
|
||
Боевым токеном не запускаться: сканер читает исходники, живого бота ему не
|
||
нужно. Внутренний логгер библиотеки правилом не выражается — его сторожит
|
||
проверка `TestLibraryLoggerIsActuallyInstalled`, и это остаётся так.
|