- разведка storage-without-pocketbase: шесть ролей библиотеки в этом коде, отпавший довод перевода, шесть модулей достижимы только через неё - ADR-2026-08-22-storage-without-pocketbase заменяет три записи: перевод в PocketBase, очередь коллекцией, файл за защищённым полем - задача storage-without-pocketbase встала первой строкой плана стройки
86 lines
7.5 KiB
Markdown
86 lines
7.5 KiB
Markdown
# Хранилище, файлы и вход переезжают в PocketBase
|
||
|
||
- **Дата:** 2026-08-11
|
||
- **Источник:** [../research/pocketbase.md](../research/pocketbase.md) — записка
|
||
разведки `pocketbase-admin-fit`
|
||
- **Статус:** заменено на [ADR-2026-08-22-storage-without-pocketbase](ADR-2026-08-22-storage-without-pocketbase.md)
|
||
|
||
## Решение
|
||
|
||
PocketBase заменяет SQLite с goqu и goose и берёт на себя три вещи разом:
|
||
состояние задач и метаданные, файлы записей своим полем и своей раскладкой на
|
||
диске, вход пользователей через Authelia своим провайдером OIDC. Панель
|
||
администратора работает по всем трём частям только в таком составе.
|
||
|
||
## Почему
|
||
|
||
Разведка мерила панель по трём частям, и порознь ни одна перевода не оправдывала.
|
||
Правку записей панель даёт целиком, а две остальные упираются в то, где лежат
|
||
данные. Цитата из источника, раздел про пользователей:
|
||
|
||
> Панель показывает свою коллекцию пользователей и ничего больше. Отсюда
|
||
> следствие для целевого входа: **пользователи Authelia в панели не появятся,
|
||
> если вход делает само приложение**.
|
||
|
||
И раздел про файлы:
|
||
|
||
> Сегодняшняя раскладка `data/files` с именами-UUID панели не видна. Путь она
|
||
> покажет строкой — прослушать и скачать запись по ней нельзя. Способа
|
||
> сослаться на файл, уже лежащий на диске мимо её каталога, нет.
|
||
|
||
Там же то, что связывает файлы с сохранностью архива:
|
||
|
||
> **Резервные копии накрывают ровно её каталог.** Файлы, оставленные снаружи, в
|
||
> них не попадут — то есть панель и встроенное резервное копирование покупаются
|
||
> одной и той же ценой.
|
||
|
||
Отвергнуты два половинчатых пути, и оба по одной причине — они покупают перевод,
|
||
не покупая того, ради чего он затевался:
|
||
|
||
> **Держать файлы на диске как сейчас, а в базе — путь строкой.** Отвергнуто:
|
||
> панель тогда не даёт по файлам ничего, и встроенные копии их не накрывают.
|
||
> Довод, ради которого перевод затевался, пропадает целиком.
|
||
>
|
||
> **Оставить вход у приложения, а PocketBase взять только хранилищем.**
|
||
> Отвергнуто: пользователей панель в этом случае не показывает вовсе, и одна из
|
||
> трёх частей вопроса остаётся без ответа навсегда, а не до какой-то задачи.
|
||
|
||
Запись попадает в журнал по двум основаниям сразу. **Откат дорогой:** меняется
|
||
раскладка файлов на диске, а она в `../../CLAUDE.md` названа необратимой.
|
||
**Пересматривается прежнее решение:** вход через OIDC собирались делать в самом
|
||
приложении — так это записано в `../architecture.md`, «Открытые вопросы», и так
|
||
поставлена задача `oidc-login`. Парного статуса «заменено на» прежняя запись не
|
||
получает: своего ADR у неё нет, решение жило открытым вопросом архитектуры.
|
||
|
||
## Последствия
|
||
|
||
- `+` панель даёт владельцу править записи, видеть пользователей и слушать сами
|
||
файлы. Проверено на версии 0.39.10; в библиотечной сборке панель отдаётся по
|
||
адресу `/_/` того же порта.
|
||
- `+` база и записи съезжаются под один каталог, и копия сервера накрывает их
|
||
разом. Своё копирование по расписанию с выгрузкой в S3-совместимое хранилище у
|
||
PocketBase тоже есть, но копии сервер уже делает своими средствами — берём мы
|
||
встроенное или нет, здесь не решено.
|
||
- `+` требование CGO уходит: PocketBase ходит в SQLite через
|
||
`modernc.org/sqlite`, и пробник собрался при `CGO_ENABLED=0`. Свойство стека в
|
||
`../../CLAUDE.md` перестаёт быть верным.
|
||
- `−` раскладка `data/files` меняется необратимо: файл ложится в
|
||
`pb_data/storage/<коллекция>/<запись>/<имя>_<10 случайных символов>` рядом с
|
||
файлом атрибутов. Момент перехода назначает человек; данные прежней базы не
|
||
переносятся по прежнему решению задачи `pocketbase-storage`.
|
||
*Уточнено 2026-08-12:* каталог задаётся ключом `[storage] data_dir` со
|
||
значением `data`. Суффикс из десяти знаков дописывает конструктор имени,
|
||
которого сервис не зовёт, — имя задаёт он сам. Действующая раскладка —
|
||
[../database.md](../database.md), «Представление данных».
|
||
- `−` вход перестаёт быть нашим: задача `oidc-login` переписывается с
|
||
собственной обработки ответа провайдера на настройку провайдера в PocketBase.
|
||
Что делать с сессией и где она живёт, решает уже не наш код.
|
||
- `−` появляется секрет, которого не было: пароль суперпользователя панели. Сама
|
||
PocketBase Authelia к панели не подпускает — ни OIDC, ни второй фактор у
|
||
коллекции суперпользователей включить не удалось. Своё ограничение по списку
|
||
адресов у неё есть, но им же можно запереть себя: сброса в наборе команд нет.
|
||
- `−` панель висит на том же порту, что и приложение, а порт опубликован в
|
||
интернет через обратный прокси. **Закрывает её контур:** тем же решением адрес
|
||
`/_/` закрывает Authelia на прокси, пропуская группу администраторов. Приложение
|
||
тут ни при чём, и задачи в беклоге у этого нет.
|