удалён вход Telegram, владелец записи стал обязателен в схеме

- убраны клиент бота, транспорт обновлений, отправитель сообщений, сборка
  входа при старте, секция настроек и зависимость go-telegram-bot-api; из
  конвейера ушла доставка ответа отправителю — исход виден опросом готовности.
  Колонки адресата и значение источника остались в схеме: применённые шаги не
  переписываются
- шаг 202608140003 запрещает пустого владельца у аудиозаписи и у файла;
  существующие строки он не проверяет, и это принято сознательно — искать их
  надо запросом до выкладки
- ревью нашло два пред-существующих дефекта, оба закрыты: пустой второй ответ
  распознавателя стирал сохранённую расшифровку, а пустая расшифровка перестала
  быть заметной вместе с убранной доставкой. Попутно поднят golang.org/x/image
  до v0.45.0 — красный шаг vulns, воспроизводился и на чистом master
This commit is contained in:
av
2026-08-15 07:24:35 +03:00
parent 97ceb7bb69
commit 8f7c3a057a
74 changed files with 2453 additions and 2733 deletions
+12 -14
View File
@@ -69,11 +69,10 @@ transcriber — **приложение, а не библиотека**: внеш
`contract.JobNotFoundError` (состояние и сообщение), `contract.NoopJobError`
(состояние), `contract.LostAcquisitionError` (идентификатор задачи).
`tg.EmptyBotTokenError` был ровно тем случаем, против которого написано правило —
тип без полей, — и снят задачей `local-run-without-telegram-token` 2026-08-13;
его место занял sentinel `telegram.ErrEmptyToken`. Рядом живёт
`contract.ErrDeliveryChannelDown` — тоже sentinel и по той же причине: заглушка
отправителя не знает ни задачи, ни чата, и нести ей нечего.
Правило это однажды нарушал `tg.EmptyBotTokenError` — тип без полей, — и был
снят задачей `local-run-without-telegram-token` 2026-08-13 в пользу sentinel'а.
Оба ушли из проекта 2026-08-14 вместе с входом Telegram; пример остаётся здесь
как случай, а не как живой код.
## Граница и трансляция: приватный и публичный канал
@@ -83,8 +82,8 @@ transcriber — **приложение, а не библиотека**: внеш
- **Приватный канал — логи** (владелец сервиса). Полная ошибка со всей цепочкой
`%w` и контекстом. Пишется один раз на доменной границе — см.
[logging.md](logging.md).
- **Публичный канал — пользовательские поверхности** (Telegram, веб-UI, HTTP
API). Сюда отдаём:
- **Публичный канал — пользовательские поверхности** (веб-UI, HTTP API). Сюда
отдаём:
- **человекочитаемое сообщение** по доменной ошибке — не сырой `err.Error()` и
не детали реализации (`database/sql`, пути на диске, имена внешних сервисов);
- **корреляционный ключ** для владельца — идентификатор задачи, чтобы по нему
@@ -118,8 +117,7 @@ transcriber — **приложение, а не библиотека**: внеш
У публичной границы две поверхности, и правило сырого текста для них разное.
- **Разовый ответ на действие** (тело HTTP-ответа, сообщение бота по результату
команды) — строго нейтральный: отображение выше, `err.Error()` наружу не идёт,
- **Разовый ответ на действие** (тело HTTP-ответа) — строго нейтральный: отображение выше, `err.Error()` наружу не идёт,
полная ошибка остаётся в логах по идентификатору задачи.
- **Сохранённая диагностика состояния** — колонка `error_text` задачи. Это
**поверхность владельца**, а не пользователя: сюда сырой текст ошибки допустим
@@ -131,9 +129,9 @@ transcriber — **приложение, а не библиотека**: внеш
- **внешнее значение в тексте усекается на границе, а его размер называется
числом рядом**: без этого непонятно, насколько сокращать.
*Расхождение:* `error_text` пишется целиком, без вычистки и без усечения, а
пользователь Telegram видит отдельный человекочитаемый текст — это часть
правила соблюдена.
*Расхождение:* `error_text` пишется целиком, без вычистки и без усечения.
Наружу он при этом не выходит: опрос готовности отдаёт признак остановки без
машинного текста — эту часть правила держит спека `intake`.
## panic
@@ -145,8 +143,8 @@ transcriber — **приложение, а не библиотека**: внеш
ронял процесс. В transcriber его вешает роутер хранилища сам
(`apis.panicRecover`, слой с идентификатором `DefaultPanicRecoverMiddlewareId`
на каждом роутере PocketBase): паникующий обработчик отдаёт `500`, процесс
живёт. Своего слоя мы не пишем. У воркеров и у бота такой границы **нет**:
паника в шаге конвейера роняет процесс целиком.
живёт. Своего слоя мы не пишем. У воркеров такой границы **нет**: паника в
шаге конвейера роняет процесс целиком.
## Несколько ошибок