Files
transcriber/tasks/items/audiorecord-actions.md
T
av 79ff12548f tasks: спроектирован контракт приложения и переставлена голова очереди
- json-api-for-spa: адреса приложения уехали в своё пространство /app/,
  приём стал POST /app/audiorecords, опрос /api/status/:id убран, заведены
  список, карточка, текст, /app/me и /app/config; имя файла отправителя
  легло своей колонкой рядом с заголовком
- три действия над записью — правка заголовка, возврат в работу и журнал
  событий — собраны задачей audiorecord-actions
- голова очереди: контракт, каркас, экран загрузки, список, действия
- в прежних задачах поправлены адреса, рубежи конвейера и остатки Telegram
2026-08-15 09:06:11 +03:00

8.1 KiB

Дать владельцу править запись, возвращать её в работу и видеть её путь

  • Тип: feature
  • Категория: Очередь — Три действия живут на экране одной записи, а заводит его список
  • Зачем: С записью нельзя сделать ничего: заголовок ставит одна языковая модель, остановленную возвращает в работу только владелец сервиса в панели, а журнал событий пишется и не читается никем, кроме него же

Экран одной записи перестаёт быть окном просмотра: с него запись переименовывают, возвращают в работу после отказа и смотрят её путь по рубежам.

Три действия собраны одной задачей, потому что живут на одном экране и стоят на одном контракте: порознь каждое несло бы свой адрес и свою правку того же экрана. Собраны они после решения владельца 2026-08-15, которым разведены колонки заголовка и имени файла и назначено пространство адресов /app/.

Переименование. Колонка заголовка объявлена местом для «пользовательского или сгенерированного» названия, а поставить его человеку нечем: заполняет её один llm-insights-adapter. Отсюда же второй вопрос, который решается здесь: что происходит с заголовком, поставленным человеком, когда модель посчитает свой.

Возврат в работу. Паспорт описывает сценарий «отказ на середине» и кончает его тем, что владелец записи узнаёт о неудаче. Дальше пусто: разовый сбой ffmpeg оставляет запись остановленной, пока владелец сервиса не откроет панель. Само снятие остановки написано — entity.Resume чистит все три сторожа и ставит время входа в рубеж заново. Цена названа прямо: повтор запускает платное распознавание, и запускает его теперь пользователь, а не владелец сервиса — значит у возвратов нужен предел, и его величину выбирает эта задача.

Путь записи. Журнал событий заполняется на смену рубежа, остановку и снятие остановки, а читается только в панели: architecture.md говорит про него прямо, что «экрана у него пока нет». Владельцу записи он нужен там, где карточка отвечает «остановлена»: без пути «встала сразу» неотличимо от «висела два часа».

Затрагивает

  • PATCH /app/audiorecords/{id} — правка заголовка, и только его;
  • POST /app/audiorecords/{id}/resume — возврат остановленной записи в работу;
  • GET /app/audiorecords/{id}/events — события своей записи по времени;
  • предел числа возвратов и место, где он считается: колонка записи либо журнал событий;
  • ответ карточки записи — признак того, можно ли вернуть запись в работу сейчас;
  • шаг конвейера, кладущий посчитанный заголовок: признак того, что заголовок поставлен человеком;
  • экран одной записи из records-list-screen: три действия и показ пути;
  • перевод рубежей и причин остановки в текст для человека — тот же словарь, что на карточке;
  • спека pipeline — возврат в работу нормирован там со стороны панели; спека storage — журнал событий описан там как канал владельца сервиса; правка записи её владельцем не нормирована нигде.

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

  • Заголовок правится владельцем и переживает перезагрузку экрана, посчитанный его не затирает, а пустой возвращает показ по имени файла отправителя. Оракул — три теста: правка и чтение карточки; шаг расчёта заголовка по записи с правленым заголовком; правка пустым значением и чтение списка.
  • Заголовок ограничен длиной и очищен от управляющих знаков — теми же правилами, какими приём чистит имя файла. Оракул — тест на строке сверх предела и со знаками управления.
  • Остановленная запись возвращается в работу с сохранённого рубежа с очищенными сторожами, неостановленная отвечает отказом, а возвраты сверх предела — тоже, и запись остаётся остановленной. Оракул — три теста: возврат записи с накопленными отказами и признаком прежнего захвата, затем захват с того же рубежа; возврат записи в работе; возвраты сверх предела.
  • Владелец видит события своей записи по времени, и машинного текста отказа в них нет: событие несёт причину остановки, а не сообщение зависимости. Оракул — два теста: запись, прошедшая два рубежа и остановку; остановленная запись с текстом ошибки в колонке.
  • Чужая запись на всех трёх адресах отвечает тем же, чем несуществующая, — и кодом, и телом. Оракул — тест на двух учётных записях, по разу на каждый адрес.

Рамки

Правку прочих полей записи не заводим: меняется один заголовок. Краткое описание и темы остаются за языковой моделью — их правка руками это отдельное решение, которого никто не принимал. Панель владельца сервиса остаётся как есть: она возвращает записи без предела, потому что деньгами распоряжается он. Правил, по которым отказ отличается от приговора, не трогаем — это failure-verdict-vs-retry. Событий не добавляем и журнал не переписываем: показываем записанное.

Берётся после records-list-screen — экран одной записи заводит она.