tasks: целевая картина пересобрана — три цели, тринадцать задач, сдвинутые границы
- паспорт: сервис объявлен архивом с бессрочным хранением записей и текстов, машинная вычитка расшифровки внутри границ, приложение — основной вход; добавлены две границы: не файловое хранилище общего назначения и не биллинг; - заведены цели upload-reliability, user-settings, usage-stats и тринадцать задач; очередь пересобрана — сперва починки, затем разведки о хранилище, затем доступ и владелец, и только потом экраны; - архитектура: четыре новых открытых вопроса — приём большого файла, учёт расхода, срок хранения, потолок шести часов.
This commit is contained in:
+17
-5
@@ -134,7 +134,18 @@
|
||||
текст расшифровки начинает уходить на сторону — сдвиг периметра
|
||||
[security.md](security.md).
|
||||
- **Долгие записи.** Потолок сегодня неизвестен и не замерялся: 20 МиБ на приём
|
||||
из Telegram — точно, ограничения `deferred-general` по длине — нет.
|
||||
из Telegram — точно, ограничения `deferred-general` по длине — нет. Расчётный
|
||||
потолок проекта — шесть часов, и он взят с запасом, а не замером.
|
||||
- **Приём большого файла.** Форма читается целиком, предел
|
||||
`router.MaxMultipartMemory` — 32 МиБ, обрыв начинает загрузку заново.
|
||||
Загрузку частями разбирает разведка `chunked-upload-choice`; её выбор меняет
|
||||
публичный контракт приёма и потому идёт через решение в `adr/`.
|
||||
- **Учёт расхода.** Распознавание и языковая модель оплачиваются по факту, а
|
||||
учёта по пользователям нет: метрики считают сервис целиком. Что именно
|
||||
копится — записи о потреблении или счётчики — решает задача
|
||||
`usage-accounting`.
|
||||
- **Срок хранения.** Записи и тексты решено хранить бессрочно (паспорт,
|
||||
2026-08-11), а рост каталога `data/files` ничем не ограничен и не наблюдается.
|
||||
- **Формат для распознавания.** Конвертер отдаёт ogg/vorbis (`libvorbis`), а
|
||||
SpeechKit получает `ContainerAudio_OGG_OPUS`. Расхождение не разобрано: то ли
|
||||
сервис определяет содержимое сам, то ли часть записей теряется на этом.
|
||||
@@ -149,7 +160,8 @@
|
||||
счётчики через `client_golang` или перейти на OpenTelemetry с трассировкой —
|
||||
решает разведка `opentelemetry-fit`. Коллектор был бы процессом, которого в
|
||||
выкладке сегодня нет.
|
||||
- **Выводы из текста.** Заголовок, пересказ и темы решено считать внешним
|
||||
сервисом с OpenAI-совместимым интерфейсом. Появляется пятая внешняя
|
||||
зависимость, платная, и текст расшифровки начинает уходить ещё на одну
|
||||
сторону — сдвиг периметра [security.md](security.md).
|
||||
- **Выводы из текста.** Литературный текст, заголовок, темы и пересказ решено
|
||||
считать внешним сервисом с OpenAI-совместимым интерфейсом за шлюзом bifrost.
|
||||
Появляется пятая внешняя зависимость, платная, и текст расшифровки начинает
|
||||
уходить ещё на одну сторону — сдвиг периметра [security.md](security.md). Не
|
||||
решено, отдельный это шаг конвейера или продолжение шага распознавания.
|
||||
|
||||
+54
-22
@@ -6,38 +6,51 @@
|
||||
|
||||
## Цель
|
||||
|
||||
Превращать записанную речь в текст, который можно читать и искать.
|
||||
Превращать записанную речь в текст, который можно читать и искать, и хранить
|
||||
этот текст вместе с записью.
|
||||
|
||||
**Сервис — архив, и это решено 2026-08-11.** Прежде граница читалась «отдаём
|
||||
текст и на этом заканчиваем»; теперь расшифровки и исходные записи лежат
|
||||
бессрочно, а список отбирается по темам. Причина в основном сценарии: семейный
|
||||
архив загружают один раз, а возвращаются к нему годами.
|
||||
|
||||
**Потребители** — список закрытый: он определяет, что считать нужным, а что
|
||||
интересным.
|
||||
|
||||
| Кто | Что ему нужно от нас |
|
||||
| --- | --- |
|
||||
| Владелец сервиса | Отправить голосовое сообщение из Telegram и получить текст ответом. Работает сегодня |
|
||||
| Приглашённый пользователь | Войти в приложение через свою учётную запись, загрузить запись, забрать текст. Приложение ставится на телефон; каждый видит только свои записи |
|
||||
| Внешняя программа | Отдать файл по HTTP и опросить готовность. Работает сегодня, без разграничения доступа |
|
||||
| Владелец сервиса | Загрузить диктофонную запись или видео из семейного архива с телефона и получить текст. Видеть, кто сколько загрузил и во что это обошлось |
|
||||
| Приглашённый пользователь | Войти в приложение через свою учётную запись, загрузить запись, забрать текст, вернуться к ней через месяц. Приложение ставится на телефон; каждый видит только свои записи |
|
||||
| Пользователь Telegram | Отправить боту голосовое сообщение и получить текст ответом. Работает сегодня |
|
||||
| Внешняя программа | Отдать файл по HTTP, представившись своим токеном, и опросить готовность. Работает сегодня, но токенов нет и доступ не разграничен |
|
||||
|
||||
**Основной вход — приложение**, бот и HTTP API дополняют его. До 2026-08-11
|
||||
основным был бот, и порядок здесь перевёрнут сознательно: диктофонная запись на
|
||||
несколько часов через Telegram не проходит вовсе.
|
||||
|
||||
Цель достигнута, когда:
|
||||
|
||||
- запись любого распространённого формата принимается без предварительной
|
||||
подготовки, включая дорожку из видео;
|
||||
- запись длиной в несколько часов доходит до текста, а не прерывается ошибкой при
|
||||
- запись длиной до шести часов доходит до текста, а не прерывается ошибкой при
|
||||
достижении предела;
|
||||
- сервисом пользуются несколько человек, и записи одного не видны другому;
|
||||
- текст доступен там же, где загружали, — в приложении и в Telegram, и человек
|
||||
узнаёт о его готовности, не держа приложение открытым.
|
||||
- текст доступен там же, где загружали, — в приложении и в Telegram. Человек
|
||||
узнаёт о его готовности, не держа приложение открытым;
|
||||
- расшифровка не теряется: к записи возвращаются через месяц и находят её по
|
||||
заголовку и темам;
|
||||
- владелец видит расход по каждому пользователю и понимает, во что обходится
|
||||
приглашение ещё одного человека.
|
||||
|
||||
## Что целью не является
|
||||
|
||||
Граница домена. По ней в теме `architecture` судят, не перенесено ли понятие
|
||||
через границу.
|
||||
|
||||
- **Редактор текста.** Расшифровку отдаём как есть; правка, разметка, экспорт в
|
||||
форматы документов — не наша работа.
|
||||
- **Хранилище записей.** Отдаём текст и на этом заканчиваем: библиотекой, архивом
|
||||
и поиском по прошлым записям сервис не становится. Сколько запись лежит на
|
||||
диске после обработки — вопрос срока хранения, а его нет вовсе:
|
||||
[database.md](database.md), «Представление данных».
|
||||
- **Правка текста руками.** Машинную вычитку расшифровки отдаём — литературный
|
||||
текст стоит рядом с сырым, — а редактором не становимся: текст руками не
|
||||
правим, не размечаем и не экспортируем в форматы документов. Граница сдвинута
|
||||
2026-08-11: до того запрет читался «расшифровку отдаём как есть».
|
||||
- **Разговор о записи.** Ответы на вопросы по содержанию и поиск по смыслу — за
|
||||
границей. Заголовок, пересказ и темы **внутри** границы: она сдвинута
|
||||
2026-08-10, и до того запись читалась «мы отдаём текст, а не выводы из него».
|
||||
@@ -51,20 +64,39 @@
|
||||
- **Диктофон.** Запись звука делает телефон, а приложение принимает готовый
|
||||
файл. Своей записи и работы без сети не делаем — граница цели
|
||||
[web-access](../tasks/items/web-access.md).
|
||||
- **Файловое хранилище общего назначения.** Храним аудио и видео, отданные ради
|
||||
речи в них. Складом произвольных файлов, папками и общим доступом к чужим
|
||||
записям сервис не становится.
|
||||
- **Учёт денег.** Считаем объём, минуты и токены по каждому пользователю и
|
||||
показываем их владельцу. Цен, счетов и отказов по исчерпании квоты не делаем:
|
||||
пользователя, потратившего слишком много, останавливает разговор или отзыв
|
||||
доступа в Authelia.
|
||||
|
||||
## Типовые сценарии
|
||||
|
||||
1. **Голосовое из Telegram.** Пользователь шлёт боту голосовое сообщение, бот
|
||||
Первые два — основные, и сегодня не работает ни один: приложения нет.
|
||||
|
||||
1. **Семейный архив.** Человек открывает приложение на телефоне, выбирает до
|
||||
десяти записей разом — диктофонные дорожки и видео, — и закрывает его.
|
||||
Загрузка показывает ход. Файл, который уже загружали, не грузится второй
|
||||
раз. Когда текст готов, приходит уведомление; в списке запись видна
|
||||
заголовком и темами.
|
||||
2. **Возвращение к записи.** Через месяц человек открывает список, находит
|
||||
запись по заголовку или теме и читает вычитанный текст, а при нужде — сырую
|
||||
расшифровку.
|
||||
3. **Голосовое из Telegram.** Пользователь шлёт боту голосовое сообщение, бот
|
||||
отвечает «обрабатываю», через минуту приходит текст ответом на то же
|
||||
сообщение. Записи, чей текст длиннее предела сообщения Telegram, приходят
|
||||
несколькими частями.
|
||||
2. **Файл через Telegram.** То же для аудиофайла или документа с аудио: бот
|
||||
отличает их по MIME-типу и расширению.
|
||||
3. **Загрузка по HTTP.** Программа шлёт `POST /api/audio`, получает идентификатор
|
||||
задачи и опрашивает `GET /api/status/:id`, пока не увидит `done` и текст.
|
||||
4. **Отказ на середине.** Конвертация или распознавание не удались — задача
|
||||
переходит в `failed`, а пользователь Telegram получает сообщение о том, что
|
||||
именно не вышло, и предложение повторить.
|
||||
несколькими частями. Работает сегодня.
|
||||
4. **Файл через Telegram.** То же для аудиофайла или документа с аудио: бот
|
||||
отличает их по MIME-типу и расширению. Работает сегодня.
|
||||
5. **Загрузка по HTTP.** Программа шлёт `POST /api/audio` со своим токеном,
|
||||
получает идентификатор задачи и опрашивает `GET /api/status/:id`, пока не
|
||||
увидит `done` и текст. Работает сегодня, но без токена и без разграничения
|
||||
доступа.
|
||||
6. **Отказ на середине.** Конвертация или распознавание не удались — задача
|
||||
переходит в `failed`, а пользователь получает сообщение о том, что именно не
|
||||
вышло, и предложение повторить.
|
||||
|
||||
## Референсы
|
||||
|
||||
|
||||
Reference in New Issue
Block a user