- 11 записей типа goal закрыты с причиной, называющей задачи-наследники; ROADMAP.md удалён, индекс остался один — BACKLOG.md; - 33 записи переписаны: ссылка «Двигает пункты N «Завершения» цели» уступила место прямому утверждению — без целей номера пунктов вели в никуда; - шапка BACKLOG.md размечена парой <!-- стадия -->, порядок строк теперь объявлен зависимостью, а не важностью.
3.4 KiB
3.4 KiB
✨ Узнавать уже загруженный файл по хеш-сумме
- Тип: feature
- Категория: Очередь — Дедупликация ищет совпадение в пределах пользователя — то есть после владельца записи, и экономит деньги с первого дня приложения.
- Зачем: Один и тот же файл, отправленный дважды, распознаётся дважды и оплачивается дважды: приём не смотрит на содержимое вовсе.
Повторная отправка того же файла возвращает прежнюю запись вместо второй задачи.
Совпадение ищется в пределах одного пользователя: чужая расшифровка по совпадению хеш-суммы не отдаётся и о её существовании отправитель не узнаёт.
Затрагивает
TranscribeService.createTranscribeJob— единая точка приёма, через неё идут оба входа;- таблица
files: колонка хеш-суммы, её миграция и индекс по паре «владелец, хеш-сумма»; - контракт
POST /api/audio: ответ на повторный файл; - ответ бота на повторно присланное голосовое;
docs/database.md— представление данных.
Критерии приёмки
- Повторная отправка того же файла тем же пользователем возвращает идентификатор прежней задачи, второй задачи в базе не появляется. Оракул — тест приёма: два вызова одним содержимым, в репозитории одна задача.
- Тот же файл от другого пользователя заводит свою задачу и своё распознавание. Оракул — тест приёма с двумя владельцами: две задачи, тексты не разделяются.
- Повторный файл не остаётся вторым экземпляром в каталоге хранения. Оракул — тест: после второго вызова в каталоге один файл.
- Незавершённая задача тоже узнаётся: повторная отправка отдаёт её состояние, а
не заводит соседнюю. Оракул — тест на задаче в состоянии
created.
Рамки
Владелец записи приходит из record-ownership — до неё дедупликация опирается
на того владельца, который уже есть. Хеш-сумма считается на сервере: подсчёт на
стороне приложения относится к chunked-upload-choice. Колонка добавляется во
всех четырёх местах пакета хранилища internal/adapter/repo/pocketbase —
applyToRecord, recordToJob, acquireColumns, acquiredRow с её toJob, —
плюс шаг схемы (инвариант CLAUDE.md).