Files
transcriber/README.md
T
av c9b7765646 хранилище переехало с PocketBase на SQLite со своим каталогом файлов
- база своя: два пула, захват одним UPDATE ... RETURNING, шаги схемы на goose
  под файловым замком, одна миграция начальной схемы вместо семи прежних
- транспорт переписан на net/http: свои слои, свой ограничитель частоты,
  отдача файла с проверкой владельца; панель /_/ и пространство /api/ исчезли
- по находкам ревью: журнал не пишет путь под корнем приложения, ключ бюджета
  читается справа налево, узнавание известного идёт читающим пулом
2026-08-23 08:06:04 +03:00

154 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Transcriber Service
Сервис расшифровки аудиозаписей. Вход один — HTTP API.
## Возможности
- Приём аудиофайлов через HTTP API
- Конвертация в ogg через ffmpeg
- Распознавание речи через Yandex SpeechKit
- Отслеживание статуса задач расшифровки
- Своё хранилище: SQLite для метаданных и каталог файлов записей рядом с ним; метрики Prometheus
## Технологии
- **Язык**: Go 1.26, CGO не нужен
- **HTTP**: стандартная библиотека, `net/http`
- **Распознавание**: Yandex SpeechKit + Yandex Object Storage (S3)
- **Конвертация**: ffmpeg
- **База данных**: SQLite через modernc.org/sqlite, CGO не нужен
- **Шаги схемы**: pressly/goose/v3, библиотекой — накат при старте
- **Файлы записей**: свой каталог, подкаталог на запись
- **Метрики**: prometheus/client_golang
## Установка и запуск
1. Клонируйте репозиторий
2. Установите зависимости:
```bash
go mod tidy
```
3. Скопируйте образец конфига и заполните его:
```bash
cp config.example.toml config.toml
```
4. Запустите приложение:
```bash
go run ./cmd/transcriber -c config.toml
```
Сервер запустится на порту из `[server] port`, по умолчанию 8080. Нужен
установленный `ffmpeg`.
### Кого пускают
Кто пришёл, сервис узнаёт из заголовка `Remote-User`, который ставит обратный
прокси, сходив к Authelia; своего входа у сервиса нет. Кому верить, задаёт
перечень доверенных адресов в секции `[auth]`. Подробности —
[docs/security.md](docs/security.md), «Что разграничивает доступ»; известные
прорехи образца конфига — [docs/conventions/config.md](docs/conventions/config.md).
Локально прокси нет, а браузер заголовков не ставит — на место контура встаёт
подставной прокси из оснастки:
```bash
go run ./cmd/devtools proxy
```
Приложение после этого открывают **по адресу прокси** — `http://localhost:9000`.
В перечне доверенных адресов при этом должен стоять петлевой; строки под это
стоят в `config.example.toml`.
## Деплой
Деплой запускается из `pet-project-server`:
```bash
inv pl -- transcriber
```
Плейбук сам зовёт `task image` (контракт роли `app_image`): образ собирается
локально и едет на сервер через `docker save`/`load`, реестр не участвует.
Локально образ можно собрать и руками — `task image` даст `transcriber:dev`.
## HTTP API
Адреса приложения живут под корнем `/app`: `POST /app/audiorecords` — приём
записи, `GET /app/audiorecords` — страница своих записей,
`GET /app/audiorecords/{id}` — карточка, `GET /app/audiorecords/{id}/text` —
текст названного вида, `GET /app/audiorecords/{id}/file` — файл записи названной
копии, `GET /app/me` — кто пришёл, `GET /app/config` — пределы, которые сервис
объявляет приложению. Отдельными адресами стоят `GET /metrics` — метрики
Prometheus с префиксом `transcriber_` — и `GET /health` — проверка живости.
Своего входа у сервиса нет: кто пришёл, называет заголовок обратного прокси
([access](openspec/specs/access/spec.md)). Больше на этом порту не отвечает
ничего: всякий прочий путь получает разметку приложения.
Контракт приёма и опроса нормативен и живёт в
[openspec/specs/intake/spec.md](openspec/specs/intake/spec.md): поля запроса и
ответа, коды и условия. Менять его — необратимое действие
([CLAUDE.md](CLAUDE.md), «Работа»), и второго описания у него быть не должно.
## Состояния задач
Перечень состояний, переходы между ними и число воркеров —
[docs/database.md](docs/database.md), разделы «Таблицы» и «Представление
данных»; как сложен конвейер целиком — [docs/architecture.md](docs/architecture.md).
## Структура проекта
```
transcriber/
├── cmd/
│ ├── transcriber/ # Точка входа сервиса: конфиг, миграции, сборка зависимостей, запуск
│ └── devtools/ # Оснастка разработчика: подставной прокси и возврат записи в работу
├── internal/
│ ├── entity/ # Модели: запись, файл, результат распознавания
│ ├── ident/ # Выдача и разбор идентификаторов строк (ULID)
│ ├── contract/ # Интерфейсы адаптеров и репозиториев, типы ошибок
│ ├── config/ # Разбор config.toml
│ ├── metrics/ # Метрики Prometheus
│ ├── service/ # Конвейер расшифровки
│ ├── controller/
│ │ ├── http/ # HTTP-обработчики
│ │ └── worker/ # Фоновые воркеры
│ └── adapter/
│ ├── converter/ffmpeg/ # Конвертация аудио
│ ├── metaviewer/ffmpeg/ # Длительность аудио
│ ├── recognizer/yandex/ # SpeechKit + Object Storage
│ └── repo/sqlite/ # Репозитории, подключение к базе, шаги схемы, каталог файлов
└── data/ # Каталог данных: база и файлы записей вместе
├── transcriber.db # База (создаётся автоматически)
├── migrate.lock # Замок наката схемы
└── records/ # Файлы записей: подкаталог на запись
```
## Хранилище
Таблицы базы — аудиозапись и её приложения. Поля, ключи, правило времени и
идентификаторов, раскладка файлов записи и механика захвата задачи воркером —
[docs/database.md](docs/database.md). Панели владельца у сервиса нет: единственное
его действие вне экранов — возврат остановленной записи в работу подкомандой
оснастки.
```bash
go run ./cmd/devtools resume -c config.toml <идентификатор записи>
```
## Разработка
Схему двигают шаги `pressly/goose/v3` —
`internal/adapter/repo/sqlite/migrations`, файл на шаг, версия шага — число в
начале имени файла. Непринятые шаги накатываются при старте, прежде чем поднимутся
входы и стартуют воркеры; отказ шага роняет старт. Применённый шаг не
переписывается: изменение — только новым файлом шага.
Проверки перед коммитом — одной командой:
```bash
task gate
```
Что она гоняет, чем краснеет и какой отказ считается объявленным долгом —
[CLAUDE.md](CLAUDE.md), раздел «Гейт».