- проверки больше не зовут ffprobe и не меняют рабочий каталог процесса; добавлены случаи на отказ чтения метаданных и на отсутствие поля audio - заведена спека intake на приём по HTTP, ADR о подставных адаптерах, запись в журнал ревью о проверке, которая не могла упасть - go test снят из объявленных долгов CLAUDE.md, послабление errcheck для _test.go в .golangci.yml убрано
5.8 KiB
ADDED Requirements
Requirement: Приём записи по HTTP
Сервис SHALL принимать запись от внешней программы запросом POST /api/audio с
телом multipart/form-data и полем audio. Принятая запись MUST быть сохранена
и получить заведённую под неё задачу расшифровки в состоянии created; ответ
MUST нести идентификатор задачи полем job_id и её состояние полем status.
Имена полей ответа нормативны: контракт HTTP API объявлен проектом необратимым, и переименование поля ломает внешнюю программу молча.
Приём не судит о годности записи сам: расширение он берёт из имени файла, а пригодность содержимого узнаёт у источника метаданных.
Scenario: Запись принята
- GIVEN источник метаданных читает запись и отдаёт её длительность
- WHEN программа шлёт
POST /api/audioс полемaudio - THEN ответ имеет код
201, а в теле лежат непустойjob_idиstatusсо значениемcreated - AND содержимое записи целиком лежит в каталоге хранения одним файлом
Scenario: Поля с записью нет
- WHEN программа шлёт
POST /api/audioбез поляaudio - THEN ответ имеет код
400и сообщение об отсутствии записи - AND ни файла, ни задачи не заводится
Scenario: Размеру записи приём не судья
- GIVEN источник метаданных читает запись и отдаёт её длительность
- WHEN программа шлёт запись нулевой длины
- THEN ответ имеет код
201: собственного порога по размеру у приёма нет
Requirement: Имя файла в хранилище
Сервис SHALL сохранять принятую запись под собственным именем — идентификатором, к которому приписано расширение из имени файла отправителя. Имя, данное отправителем, MUST не попадать в хранилище: оно приходит извне и содержимым своим приёму не подконтрольно.
Расширения в присланном имени нет — сервис MUST подставить .audio, чтобы у
файла на диске расширение было всегда.
Scenario: Расширение взято из имени отправителя
- WHEN программа шлёт запись с именем
test.mp3 - THEN файл в каталоге хранения имеет расширение
.mp3
Scenario: Имени без расширения назначено своё
- WHEN программа шлёт запись с именем
testбез расширения - THEN файл в каталоге хранения имеет расширение
.audio
Requirement: Отказ чтения метаданных
Сервис SHALL отвечать отказом, когда источник метаданных не смог прочитать
принятую запись. Ответ MUST иметь код 500, а причина отказа MUST не попадать в
тело ответа: она принадлежит журналу, а не отправителю.
Scenario: Источник метаданных вернул ошибку
- GIVEN источник метаданных не может прочитать запись
- WHEN программа шлёт
POST /api/audioс этой записью - THEN ответ имеет код
500 - AND задача расшифровки не заводится
Requirement: Опрос готовности задачи
Сервис SHALL отдавать состояние задачи расшифровки по запросу
GET /api/status/:id. Ответ MUST нести идентификатор полем job_id, состояние
полем status и время заведения полем created_at, а текст расшифровки полем
transcription_text, и это поле MUST отсутствовать в ответе, пока текста нет:
пустая строка на месте отсутствующего текста читается как «расшифровка пуста».
Scenario: Задача найдена
- WHEN программа спрашивает состояние заведённой задачи
- THEN ответ имеет код
200и несётjob_id,statusиcreated_at
Scenario: Расшифровки ещё нет
- WHEN программа спрашивает состояние задачи, которая ещё не дошла до текста
- THEN поля
transcription_textв ответе нет вовсе
Scenario: Задачи с таким идентификатором нет
- WHEN программа спрашивает состояние по неизвестному идентификатору
- THEN ответ имеет код
404и сообщение о ненайденной задаче