- паспорт: сервис объявлен архивом с бессрочным хранением записей и текстов, машинная вычитка расшифровки внутри границ, приложение — основной вход; добавлены две границы: не файловое хранилище общего назначения и не биллинг; - заведены цели upload-reliability, user-settings, usage-stats и тринадцать задач; очередь пересобрана — сперва починки, затем разведки о хранилище, затем доступ и владелец, и только потом экраны; - архитектура: четыре новых открытых вопроса — приём большого файла, учёт расхода, срок хранения, потолок шести часов.
3.1 KiB
3.1 KiB
✨ Узнавать уже загруженный файл по хеш-сумме
- Тип: feature
- Категория: Очередь
- Зачем: Один и тот же файл, отправленный дважды, распознаётся дважды и оплачивается дважды: приём не смотрит на содержимое вовсе.
- Теги: goal:upload-reliability
Двигает пункт 1 «Завершения» цели: повторная отправка того же файла возвращает прежнюю запись вместо второй задачи.
Совпадение ищется в пределах одного пользователя: чужая расшифровка по совпадению хеш-суммы не отдаётся и о её существовании отправитель не узнаёт.
Затрагивает
TranscribeService.createTranscribeJob— единая точка приёма, через неё идут оба входа;- таблица
files: колонка хеш-суммы, её миграция и индекс по паре «владелец, хеш-сумма»; - контракт
POST /api/audio: ответ на повторный файл; - ответ бота на повторно присланное голосовое;
docs/database.md— представление данных.
Критерии приёмки
- Повторная отправка того же файла тем же пользователем возвращает идентификатор прежней задачи, второй задачи в базе не появляется. Оракул — тест приёма: два вызова одним содержимым, в репозитории одна задача.
- Тот же файл от другого пользователя заводит свою задачу и своё распознавание. Оракул — тест приёма с двумя владельцами: две задачи, тексты не разделяются.
- Повторный файл не остаётся вторым экземпляром в каталоге хранения. Оракул — тест: после второго вызова в каталоге один файл.
- Незавершённая задача тоже узнаётся: повторная отправка отдаёт её состояние, а
не заводит соседнюю. Оракул — тест на задаче в состоянии
created.
Рамки
Владелец записи приходит из record-ownership — до неё дедупликация опирается
на того владельца, который уже есть. Хеш-сумма считается на сервере: подсчёт на
стороне приложения относится к chunked-upload-choice. Колонка добавляется во
всех четырёх местах репозитория SQLite (инвариант CLAUDE.md).