хранилище переехало с PocketBase на SQLite со своим каталогом файлов

- база своя: два пула, захват одним UPDATE ... RETURNING, шаги схемы на goose
  под файловым замком, одна миграция начальной схемы вместо семи прежних
- транспорт переписан на net/http: свои слои, свой ограничитель частоты,
  отдача файла с проверкой владельца; панель /_/ и пространство /api/ исчезли
- по находкам ревью: журнал не пишет путь под корнем приложения, ключ бюджета
  читается справа налево, узнавание известного идёт читающим пулом
This commit is contained in:
av
2026-08-23 08:06:04 +03:00
parent 1edf8cb225
commit c9b7765646
118 changed files with 11668 additions and 6679 deletions
+1 -25
View File
@@ -35,15 +35,6 @@ const (
HaltReasonStuck = "stuck"
)
const (
SourceUnknown = "unknown"
SourceApi = "api"
// SourceTelegram — историческое значение. Вход Telegram убран, новых записей
// с этим источником не появляется, а константа остаётся: на неё ссылается
// применённый шаг схемы `202608140002`, а применённый шаг не переписывается.
SourceTelegram = "telegram"
)
// AudioRecord — аудиозапись, центральная сущность сервиса.
//
// Приложения к ней — файлы, тексты, структура реплик, темы, журнал событий и
@@ -57,7 +48,6 @@ type AudioRecord struct {
// хранилище не бывает. Назначается один раз, при приёме, и конвейером не
// меняется.
OwnerID string
Source string
// Title и Brief читаются вместе со списком, сотней штук разом, и потому
// лежат колонками записи, а не строками `texts`.
@@ -142,7 +132,7 @@ const MaxOriginalFilenameLen = 255
//
// Живёт в домене, а не в транспорте: имя доходит до колонки записи одним путём,
// и правило чистки обязано быть одно. Управляющие знаки убираются потому, что
// иначе доезжают до экрана и до панели владельца; резка идёт **после** уборки,
// иначе доезжают до экрана; резка идёт **после** уборки,
// иначе потолок съедали бы знаки, которых в сохранённом имени всё равно не будет.
//
// Режется по знакам, а не по байтам: имя русское чаще, чем латинское, и обрезка
@@ -162,20 +152,6 @@ func SanitizeOriginalFilename(name string) string {
return string(runes)
}
// AllStates — закрытый перечень рубежей для схемы хранилища.
func AllStates() []string {
out := make([]string, 0, len(stages))
for _, s := range stages {
out = append(out, s.Name)
}
return out
}
// AllHaltReasons — закрытый перечень причин остановки для схемы хранилища.
func AllHaltReasons() []string {
return []string{HaltReasonStepFailed, HaltReasonAttempts, HaltReasonStuck}
}
// MoveToState двигает запись на новый рубеж и чистит служебные поля прошлого.
//
// Время входа в рубеж ставится заново: с этой минуты идёт отсчёт застревания.