Разведка job-queue-choice — очередь написана вручную: захват не транзакционен, повторов и счётчика попыток нет, очереди мёртвых задач нет. Стоит перед сменой хранилища, чтобы не переписывать захват дважды. Цель text-insights: заголовок, пересказ и темы внешним сервисом с OpenAI-совместимым интерфейсом. Граница паспорта сдвинута — «понимание сказанного» было записано как то, чем проект не является; за границей остались ответы на вопросы по записи и поиск по смыслу. Цель service-observability в сопровождении и разведка opentelemetry-fit: /metrics остаётся и развивается, способ решает замер.
6.5 KiB
6.5 KiB
Паспорт проекта
Зачем это и для кого. architecture.md отвечает «как устроено», tasks/ROADMAP.md — «в каком порядке», паспорт — «зачем и для кого».
Цель
Превращать записанную речь в текст, который можно читать и искать.
Потребители — список закрытый: он определяет, что считать нужным, а что интересным.
| Кто | Что ему нужно от нас |
|---|---|
| Владелец сервиса | Отправить голосовое сообщение из Telegram и получить текст ответом. Работает сегодня |
| Приглашённый пользователь | Войти в приложение через свою учётную запись, загрузить запись, забрать текст. Приложение ставится на телефон; каждый видит только свои записи |
| Внешняя программа | Отдать файл по HTTP и опросить готовность. Работает сегодня, без разграничения доступа |
Цель достигнута, когда:
- запись любого распространённого формата принимается без предварительной подготовки, включая дорожку из видео;
- запись длиной в несколько часов доходит до текста, а не прерывается ошибкой при достижении предела;
- сервисом пользуются несколько человек, и записи одного не видны другому;
- текст доступен там же, где загружали, — в приложении и в Telegram, и человек узнаёт о его готовности, не держа приложение открытым.
Что целью не является
Граница домена. По ней в теме architecture судят, не перенесено ли понятие
через границу.
- Редактор текста. Расшифровку отдаём как есть; правка, разметка, экспорт в форматы документов — не наша работа.
- Хранилище записей. Отдаём текст и на этом заканчиваем: библиотекой, архивом и поиском по прошлым записям сервис не становится. Сколько запись лежит на диске после обработки — вопрос срока хранения, а его нет вовсе: database.md, «Представление данных».
- Разговор о записи. Ответы на вопросы по содержанию и поиск по смыслу — за границей. Заголовок, пересказ и темы внутри границы: она сдвинута 2026-08-10, и до того запись читалась «мы отдаём текст, а не выводы из него». Направление — цель text-insights.
- Собственные модели. Не обучаем и не держим у себя ни модель распознавания, ни языковую модель: и речь, и выводы из текста считает внешний сервис.
- Управление учётными записями. Пользователей заводит и проверяет внешний провайдер, свою регистрацию и свои пароли не делаем.
- Живая расшифровка. Работаем с готовой записью, поток в реальном времени не обрабатываем.
- Диктофон. Запись звука делает телефон, а приложение принимает готовый файл. Своей записи и работы без сети не делаем — граница цели web-access.
Типовые сценарии
- Голосовое из Telegram. Пользователь шлёт боту голосовое сообщение, бот отвечает «обрабатываю», через минуту приходит текст ответом на то же сообщение. Записи, чей текст длиннее предела сообщения Telegram, приходят несколькими частями.
- Файл через Telegram. То же для аудиофайла или документа с аудио: бот отличает их по MIME-типу и расширению.
- Загрузка по HTTP. Программа шлёт
POST /api/audio, получает идентификатор задачи и опрашиваетGET /api/status/:id, пока не увидитdoneи текст. - Отказ на середине. Конвертация или распознавание не удались — задача
переходит в
failed, а пользователь Telegram получает сообщение о том, что именно не вышло, и предложение повторить.
Референсы
Где смотреть prior art, когда упёрлись.
- Yandex SpeechKit, отложенное распознавание — модель
deferred-general, которой пользуемся: она и задаёт потолок по длине записи и формату. - Whisper и его серверные обёртки — запасной путь, если внешний сервис перестанет устраивать по цене или по качеству русской речи.
- PocketBase — кандидат в хранилище взамен сегодняшнего SQLite. Источником учётных записей его не рассматриваем: вход решено делать через OIDC у Authelia (architecture.md, «Открытые вопросы»).