приём и чтение записей сведены к одному контракту приложения

- адреса приложения переехали в своё пространство `/app/`, опрос готовности
  убран целиком: рубеж и причину остановки владелец узнаёт карточкой записи,
  текст — отдельным адресом названного вида
- заведена единая точка отображения доменной ошибки и слой, приводящий к той же
  форме отказы библиотеки: тело несёт машиночитаемый код рядом с сообщением
- у записи появились имя файла отправителя, длительность и размер своими
  колонками, а у ленты владельца — свой индекс: без него страница сканировала
  весь архив сервиса
This commit is contained in:
av
2026-08-15 13:51:23 +03:00
parent 79ff12548f
commit 3a2da3004b
55 changed files with 5506 additions and 466 deletions
+28
View File
@@ -1,6 +1,7 @@
package metrics
import (
"slices"
"strconv"
"strings"
)
@@ -33,6 +34,33 @@ var knownFormats = map[string]struct{}{
"audio": {}, // умолчание сервиса, когда расширения в имени не было
}
// PublicFormats — тот же перечень, но для подсказки диалогу выбора файла в
// приложении: **без** собственного умолчания сервиса.
//
// Второй перечень рядом с первым разошёлся бы с ним молча, поэтому источник
// один. `audio` из него вычтено: это не формат, а умолчание на случай имени без
// расширения, и подсказкой человеку оно выходить не должно.
//
// Сервис по этому перечню **не судит**: приём о годности записи не решает сам —
// расширение он берёт из имени файла, а пригодность содержимого узнаёт у
// источника метаданных. Перечень служит диалогу выбора файла, не более; норму
// держит capability `archive`.
func PublicFormats() []string {
out := make([]string, 0, len(knownFormats))
for format := range knownFormats {
if format == defaultServiceFormat {
continue
}
out = append(out, format)
}
slices.Sort(out)
return out
}
// defaultServiceFormat — собственное умолчание сервиса на случай имени без
// расширения. Форматом не является.
const defaultServiceFormat = "audio"
// FormatLabel приводит расширение к виду, годному для метки метрики.
//
// Расширение приходит из имени, которое дал отправитель, и потому может быть