- json-api-for-spa: адреса приложения уехали в своё пространство /app/, приём стал POST /app/audiorecords, опрос /api/status/:id убран, заведены список, карточка, текст, /app/me и /app/config; имя файла отправителя легло своей колонкой рядом с заголовком - три действия над записью — правка заголовка, возврат в работу и журнал событий — собраны задачей audiorecord-actions - голова очереди: контракт, каркас, экран загрузки, список, действия - в прежних задачах поправлены адреса, рубежи конвейера и остатки Telegram
43 lines
3.5 KiB
Markdown
43 lines
3.5 KiB
Markdown
# ✨ Узнавать уже загруженный файл по хеш-сумме
|
|
|
|
- **Тип:** feature
|
|
- **Категория:** Очередь — Дедупликация ищет совпадение в пределах пользователя — то есть после владельца записи, и экономит деньги с первого дня приложения.
|
|
- **Зачем:** Один и тот же файл, отправленный дважды, распознаётся дважды и оплачивается дважды: приём не смотрит на содержимое вовсе.
|
|
|
|
Повторная отправка того же файла возвращает прежнюю запись вместо второй.
|
|
|
|
Совпадение ищется **в пределах одного пользователя**: чужая расшифровка по
|
|
совпадению хеш-суммы не отдаётся и о её существовании отправитель не узнаёт.
|
|
|
|
## Затрагивает
|
|
|
|
- `TranscribeService.createRecord` — единственный путь, которым запись
|
|
появляется в хранилище;
|
|
- таблица `files`: колонка хеш-суммы, её миграция и индекс по паре «владелец,
|
|
хеш-сумма»;
|
|
- контракт `POST /app/audiorecords`: признак повторного файла в ответе — место
|
|
под него согласовано задачей `json-api-for-spa`;
|
|
- `docs/database.md` — представление данных.
|
|
|
|
## Критерии приёмки
|
|
|
|
- Повторная отправка того же файла тем же пользователем возвращает
|
|
идентификатор прежней записи с признаком повтора, второй записи в базе не
|
|
появляется. Оракул — тест приёма: два вызова одним содержимым, в репозитории
|
|
одна запись, во втором ответе признак повтора.
|
|
- Тот же файл от другого пользователя заводит свою запись и своё распознавание.
|
|
Оракул — тест приёма с двумя владельцами: две записи, тексты не разделяются.
|
|
- Повторный файл не остаётся вторым экземпляром в каталоге хранения. Оракул —
|
|
тест: после второго вызова в каталоге один файл.
|
|
- Незавершённая запись тоже узнаётся: повторная отправка отдаёт её рубеж, а не
|
|
заводит соседнюю. Оракул — тест на записи с рубежом `uploaded`.
|
|
|
|
## Рамки
|
|
|
|
Владелец записи обязателен с 2026-08-14 — его держит схема хранилища, — и
|
|
дедупликация опирается на него. Хеш-сумма считается на сервере: подсчёт на
|
|
стороне приложения относится к `chunked-upload-choice`. Колонка добавляется во
|
|
всех местах пакета хранилища `internal/adapter/repo/pocketbase`, которые
|
|
перечисляет инвариант `CLAUDE.md` «Колонки записи правятся в двух местах», плюс
|
|
шаг схемы.
|