Files
transcriber/tasks/items/orphan-file-on-failed-intake.md
T
av d2c85af80a tasks: целевая картина пересобрана — три цели, тринадцать задач, сдвинутые границы
- паспорт: сервис объявлен архивом с бессрочным хранением записей и текстов,
  машинная вычитка расшифровки внутри границ, приложение — основной вход;
  добавлены две границы: не файловое хранилище общего назначения и не биллинг;
- заведены цели upload-reliability, user-settings, usage-stats и тринадцать
  задач; очередь пересобрана — сперва починки, затем разведки о хранилище,
  затем доступ и владелец, и только потом экраны;
- архитектура: четыре новых открытых вопроса — приём большого файла, учёт
  расхода, срок хранения, потолок шести часов.
2026-08-11 10:05:22 +03:00

62 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🐞 Убирать записанный файл, когда приём отказал на середине
- **Тип:** fix
- **Категория:** Очередь
- **Зачем:** Отказ чтения метаданных и отказ записи на диск оставляют файл в каталоге хранения без задачи и без учёта: сопоставить его не с чем, удалять приходится руками.
- **Теги:** review-2026-08-11, goal:upload-reliability
Приём пишет файл на диск, потом спрашивает у источника метаданных длительность,
потом заводит запись в учёте и задачу. Уборка при отказе есть **только на
последнем шаге**: отказ `fileRepo.Create` зовёт `os.Remove`, а отказы записи на
диск и чтения метаданных возвращают ошибку, оставляя файл лежать.
Сопоставить такой файл не с чем: записи в `files` под него нет, задачи нет,
имя — случайный идентификатор. На сервере это `data/files`, где лежат голосовые
сообщения живых людей, а проект по паспорту «не хранит записи как архив».
Найдено проходом `review-specs` ревью дизайна change
`2026-08-11-fix-http-handler-tests`; отчёт триажа —
`openspec/changes/archive/2026-08-11-fix-http-handler-tests/review/triage.md`.
Вынесено сюда решением человека на контрольной точке.
## Воспроизведение
Асимметрия видна в самом коде:
```
sed -n '110,160p' internal/service/transcribe.go
```
Ветка `fileRepo.Create` (строки 152–157) содержит `os.Remove(storageFilePath)` с
комментарием «Удаляем файл если не удалось создать запись в БД». Ветки
`io.Copy`, `dst.Close` и `metaviewer.GetInfo` (строки 116–133) возвращают ошибку
без уборки, хотя файл к этому моменту уже создан.
Прогоном: `TestCreateTranscribeJob_MetaViewerFailure` в
`internal/controller/http/transcribe_test.go` доводит приём до этой ветки —
после него в каталоге хранения лежит файл, а `countJobs` равен нулю.
## Затрагивает
- `internal/service/transcribe.go`, функция `createTranscribeJob` — три ветки
отказа между созданием файла и заведением записи в учёте;
- `internal/controller/http/transcribe_test.go` — случай отказа метаданных
получает проверку на отсутствие файла;
- раскладка `data/files` не меняется: имена и формат прежние.
## Критерии приёмки
- Отказ чтения метаданных не оставляет файла в каталоге хранения. Оракул — тест
на подставном источнике, возвращающем ошибку: каталог пуст после запроса.
- Отказ записи на диск на середине не оставляет частично записанного файла.
Оракул — тест с источником данных, обрывающимся на середине чтения.
- Уборка сама не заслоняет исходную ошибку: отправитель по-прежнему получает
отказ, а причина уезжает в журнал. Оракул — тот же тест, код ответа и запись в
перехваченном журнале.
## Рамки
Уборка файлов, осиротевших **до** этой правки, сюда не входит: их надо найти
сверкой каталога с учётом, и это отдельная работа с боевыми данными.