- разведка storage-without-pocketbase: шесть ролей библиотеки в этом коде, отпавший довод перевода, шесть модулей достижимы только через неё - ADR-2026-08-22-storage-without-pocketbase заменяет три записи: перевод в PocketBase, очередь коллекцией, файл за защищённым полем - задача storage-without-pocketbase встала первой строкой плана стройки
4.4 KiB
4.4 KiB
✨ Уйти с PocketBase на SQLite со своим каталогом файлов
- Тип: feature
- Категория: Очередь — Всё остальное строится поверх хранилища: экраны пишутся на типах контроллера, а dev-run-task заводит владельца панели, которой не станет
- Зачем: Библиотека держит шесть ролей и вышла за адаптер: её типы стоят во всех пяти файлах контроллера и во всех шести его проверках, панель опубликована в интернет вместе с необойдённым /%5f/, а пространство /api/ нельзя закрыть на прокси, потому что за файлами туда ходит браузер пользователя.
Сервис работает с SQLite напрямую, файлы записей лежат в своём каталоге и
отдаются своим обработчиком, маршруты и слои живут на net/http, схему двигают
свои шаги. Панель администратора исчезает вместе с адресами /_/ и /api/.
Решение — ADR-2026-08-22-storage-without-pocketbase, разведка — storage-without-pocketbase.
Затрагивает
- каталог
internal/adapter/repo/pocketbaseцеликом и его шаги схемы; - каталог
internal/controller/httpцеликом вместе с проверками; - подъём сервера и цепочку слоёв в
cmd/transcriber/main.go; - раскладку каталога данных: файл базы и каталог файлов записей — необратимое;
- публичный контракт HTTP: пространство
/api/и адрес/_/исчезают, корень/app/остаётся; - отдачу файла записи браузеру: короткий токен файла и защищённое поле коллекции;
- панель администратора как инструмент владельца сервиса;
- ключ конфига
[storage] data_dirи перечень зависимостейgo.mod; - модель угроз: адрес
/_/, дефект/%5f/и правило прокси на пространство хранилища.
Критерии приёмки
- Библиотеки нет в сборке. Оракул:
go list -deps ./... | grep -c pocketbaseдаёт0, аgo mod tidyне возвращает её модулей вgo.mod. - Чужой файл недостижим по прямой ссылке. Оракул: тест контроллера — запрос к файлу чужой записи и к несуществующей отвечает одинаково.
- Захват записи остаётся неделимым. Оракул: тест с параллельными воркерами
под
-race— запись достаётся ровно одному, второй получает отказ по значению признака захвата. - Пространства хранилища не существует. Оракул: тест маршрутов —
/api/…,/_/и/%5f/отвечают тем же, чем всякий неизвестный путь. - Схема накатывается на пустом каталоге до старта воркеров. Оракул: запуск на чистом каталоге данных — ни одного отказа в журнале до первой строки о готовности.
Рамки
Данные не переносятся: стройка, на сервере пусто. Панель не заменяется ничем —
остановленную запись возвращает в работу запрос к базе, пока этого не сделают
экраны владельца. Очередь остаётся своей таблицей с захватом одним запросом
RETURNING. Боевой каталог данных не трогать.