Files
transcriber/tasks/items/json-api-for-spa.md
T
av b4b19db6e4 tasks: заведён урожай ревью remove-telegram-intake
- шесть записей по кластерам причин: журнал под внешним значением, нулевой
  код ответа в журнале, затирание вложения бедным ответом, открытый анониму
  адрес подтверждения почты, рубеж расшифровки без работы, пределы длительности
- находка про код 500 у отказа приёма дописана в json-api-for-spa: там живёт
  единая точка отображения доменной ошибки
- telegram-account-link и bot-api-only-through-bot-client оставлены с оговоркой,
  что предмета у них нет до возвращения входа
2026-08-15 07:46:16 +03:00

5.9 KiB
Raw Blame History

Свести приём и чтение записей к одному контракту для приложения

  • Тип: feature
  • Категория: Очередь — Единая точка трансляции доменной ошибки — база и для экранов, и для токенов; список своих записей заводится после владельца, а не до.
  • Зачем: Сегодняшний API отвечает 404 на любую ошибку чтения и 500 на любую ошибку приёма: строить на нём экраны нечем.

Экраны заводят задачу, видят её состояние и листают список — всё через один контракт.

Обработчик GET /api/status/:id сегодня отвечает 404 на любую ошибку чтения, включая сбой базы, а POST /api/audio500 на любую ошибку заведения, включая негодный файл. Экран, построенный на таком контракте, показывает «не найдено» при упавшей базе.

Отдельная ветка того же класса найдена ревью задачи remove-telegram-intake 2026-08-15, проход сверки требований: приём отвергает пустого владельца своей ошибкой, а транспорт переводит любую ошибку службы в 500. Спека приёма при этом держит эту проверку ради понятного отказа — «отвечает отправителю понятным отказом до того, как запись попадёт в память». Сегодня путь недостижим: слой предъявления отвергает такого вызывающего раньше. Он становится достижимым вместе с личными токенами и экранами приложения, то есть ровно здесь.

Затрагивает

  • POST /api/audio и GET /api/status/:id — коды ответа и форма ошибки;
  • новый эндпоинт списка своих записей с постраничным чтением;
  • единая точка отображения доменной ошибки в код ответа — её сегодня нет (conventions/errors.md);
  • internal/contract — доменные ошибки под отображение;
  • internal/controller/http целиком;
  • docs/architecture.md, раздел «Единые точки проекта».

Критерии приёмки

  • Код ответа отвечает причине отказа, а не месту, где он случился: сбой базы при чтении даёт 500, а не 404, негодный файл — 400 с человекочитаемым текстом, а не 500, а отказ приёма по пустому владельцу — 403, как и отказ слоя предъявления. Оракул — три теста: репозиторий, возвращающий ошибку драйвера; файл, который отвергает разбор метаданных; вызов приёма без учётной записи.
  • Тело ошибки одной формы на всех эндпоинтах, не содержит сырого err.Error() и опечатки transcibe. Оракул — тест на четырёх ветвях отказа (форма совпадает, текста внутренней ошибки в теле нет) плюс пустой grep -rn 'transcibe' internal/.
  • Список записей отдаётся страницами и упорядочен по времени создания. Оракул — тест на выборке больше страницы.
  • Отображение ошибки живёт в одной функции, и она названа в docs/architecture.md. Оракул — task gate, шаг docs.py check.
  • Ответ приёма отдаёт список заведённых записей и место под признак повторного файла, даже когда файл в запросе один. Оракул — тест приёма: тело ответа — список из одного элемента, у элемента есть поле признака повтора.

Рамки

Аутентификацию и владельца не заводим — это oidc-login и record-ownership; задача про форму контракта. Публичный контракт после мерджа обратной правкой не откатывается, и по решению владельца от 2026-08-12 форма ответа приёма согласуется здесь один раз — сразу списком и с местом под признак повтора, — чтобы dedup-by-content-hash, multi-file-upload и reject-oversized-recording её не переписывали, а экран загрузки не переделывался под вторую форму. Приём по-прежнему берёт из запроса один файл: меняется форма ответа, не число файлов. Сюда же приехала опечатка transcibe в тексте ошибки приёма (нашёл проход review-specs на ревью change 2026-08-11-fix-http-handler-tests): в одиночку текст ошибки менять нельзя, а здесь контракт переписывается целиком.