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

122 lines
5.4 KiB
Go

package entity
import "time"
// RecognitionStatus представляет статус операции распознавания у провайдера.
type RecognitionStatus int
const (
// RecognitionStatusInProgress - операция в процессе выполнения
RecognitionStatusInProgress RecognitionStatus = iota
// RecognitionStatusCompleted - операция завершена успешно
RecognitionStatusCompleted
// RecognitionStatusFailed - операция завершена с ошибкой
RecognitionStatusFailed
)
// String возвращает строковое представление статуса
func (s RecognitionStatus) String() string {
switch s {
case RecognitionStatusInProgress:
return "in_progress"
case RecognitionStatusCompleted:
return "completed"
case RecognitionStatusFailed:
return "failed"
default:
return "unknown"
}
}
// RecognitionResult представляет исход опроса операции распознавания.
type RecognitionResult struct {
Status RecognitionStatus
Error string // Текст ошибки (заполняется при StatusFailed)
}
// NewInProgressResult создает результат для операции в процессе выполнения
func NewInProgressResult() *RecognitionResult {
return &RecognitionResult{
Status: RecognitionStatusInProgress,
}
}
// NewCompletedResult создает результат для успешно завершенной операции
func NewCompletedResult() *RecognitionResult {
return &RecognitionResult{
Status: RecognitionStatusCompleted,
}
}
// NewFailedResult создает результат для операции, завершенной с ошибкой
func NewFailedResult(errorText string) *RecognitionResult {
return &RecognitionResult{
Status: RecognitionStatusFailed,
Error: errorText,
}
}
// IsInProgress проверяет, находится ли операция в процессе выполнения
func (r *RecognitionResult) IsInProgress() bool {
return r.Status == RecognitionStatusInProgress
}
// IsCompleted проверяет, завершена ли операция успешно
func (r *RecognitionResult) IsCompleted() bool {
return r.Status == RecognitionStatusCompleted
}
// IsFailed проверяет, завершена ли операция с ошибкой
func (r *RecognitionResult) IsFailed() bool {
return r.Status == RecognitionStatusFailed
}
// GetError возвращает текст ошибки (только для операций, завершенных с ошибкой)
func (r *RecognitionResult) GetError() string {
if r.IsFailed() {
return r.Error
}
return ""
}
// Recognition — попытка распознавания у внешнего провайдера.
//
// Всё провайдерское живёт здесь, а не колонками записи: идентификатор операции —
// самое провайдерское, что есть в модели, а копия аудио во внешнем хранилище
// существует только потому, что сегодняшний провайдер читает запись по адресу.
// Другой провайдер её не потребует, и смена провайдера не трогает доменную
// сущность вовсе.
//
// Сохранённый ответ провайдера лежит **третьим файлом в подкаталоге записи**, а
// не колонкой этой строки: шаг опроса читает её раз в несколько секунд, а
// репозиторий читает строку целиком — ответ на многочасовую запись ехал бы в
// память при каждом опросе. Хранится он потому, что результат операции у
// провайдера не переспрашивается.
type Recognition struct {
Id string
RecordID string
Provider string
Model string
// ExternalID — идентификатор операции у провайдера. Заводится **до**
// обращения к нему: окно между ответом провайдера и записью идентификатора —
// то место, где теряется оплаченное.
ExternalID string
// SourceURI — адрес, по которому провайдер читает аудио.
SourceURI string
StartedAt *time.Time
FinishedAt *time.Time
}
// RecognitionOutcome — доменный результат распознавания, каким его отдаёт
// адаптер. Формата провайдера здесь нет: разбор потока — обязанность адаптера, и
// ни один шаг конвейера не знает, каким потоком и какими полями провайдер
// отвечает.
type RecognitionOutcome struct {
// Replicas — реплики со временем от начала записи.
Replicas []Replica
// PlainText — плоский текст расшифровки.
PlainText string
// Raw — ответ провайдера целиком, как он пришёл, на хранение отдельным файлом.
Raw []byte
}