- admin-owner-from-config первой строкой: сервис заводит владельца панели по ключу конфига; задача отменяет требование спеки storage, и это названо в рамках - dev-run-task следом: task dev поднимает сервис и заглушку разом, гасит оба по Ctrl+C; зависит от ключа конфига
60 lines
5.4 KiB
Markdown
60 lines
5.4 KiB
Markdown
# ✨ Заводить владельца панели по ключу конфига
|
|
|
|
- **Тип:** feature
|
|
- **Категория:** Очередь — решение владельца 2026-08-15: ключ конфига нужен и локальному прогону, и выкладке
|
|
- **Зачем:** Владельца панели заводят по одноразовой ссылке из журнала при первом подъёме, и пароль после этого не хранится нигде: на каждой чистой базе шаг повторяется руками — и локально, где база пересоздаётся каждый прогон, и на выкладке с чистого листа.
|
|
|
|
Сервис на подъёме заводит владельца панели администратора по ключу конфига,
|
|
когда такой учётной записи ещё нет.
|
|
|
|
Сторонней командой этого сегодня не сделать: точка входа разбирает свои флаги и
|
|
сразу грузит конфиг, поэтому команды хранилища до неё не доходят — проверено
|
|
2026-08-15, `go run ./cmd/transcriber superuser upsert …` падает на разборе
|
|
конфига. Отсюда и ключ: другого места, откуда взять пароль, у сервиса нет.
|
|
|
|
## Затрагивает
|
|
|
|
- секция конфига и её проверка на старте — новый ключ, `internal/config`;
|
|
- приведение настроек хранилища при подъёме —
|
|
`internal/adapter/repo/pocketbase/provider.go`, там же, где применяются
|
|
настройки провайдера OIDC;
|
|
- `config.example.toml` — образец ключа;
|
|
- `docs/conventions/config.md` — конвенция конфига;
|
|
- `docs/security.md` — пароль владельца панели становится содержимым конфига, а
|
|
вход в панель заводится сам;
|
|
- `openspec/specs/storage/spec.md`, требование «Пароль владельца от панели не
|
|
лежит в конфигурации» — задача его **отменяет**. Там же сценарий «Владелец
|
|
пароля ещё не задан» с проверкой «ни один ключ конфигурации не несёт пароля от
|
|
панели».
|
|
|
|
## Критерии приёмки
|
|
|
|
- Подъём на пустой базе с заполненным ключом заводит владельца, и он входит в
|
|
панель этим паролем. Оракул: подъём на временном каталоге данных, затем вход по
|
|
`/_/` — и запрос к собственному адресу хранилища с полученной сессией.
|
|
- Подъём с пустым ключом никого не заводит и старт не роняет. Оракул: подъём на
|
|
пустой базе с пустым значением — сервис слушает порт, в коллекции владельцев
|
|
записей нет.
|
|
- Повторный подъём с уже заведённым владельцем пароль не переписывает. Оракул:
|
|
сменить пароль в панели, поднять сервис заново, войти новым паролем — вход
|
|
проходит.
|
|
- Пароль не встречается ни в журнале, ни в тексте ошибки. Оракул: поиск значения
|
|
по выводу подъёма, включая подъём с негодным значением ключа.
|
|
|
|
## Рамки
|
|
|
|
Задача идёт **против записанного требования**, и это её главное условие. Спека
|
|
`storage` сегодня запрещает ровно то, что здесь заводится, и довод у неё свой:
|
|
пароль от панели открывает все записи и все файлы разом, а секрет, лежащий в
|
|
конфиге, уезжает вместе с ней в выкладку. Отменять требование — решение владельца
|
|
от 2026-08-15; принято оно с открытыми глазами, потому что своей команды завести
|
|
владельца у сервиса нет. Работа обязана снять требование дельта-спекой, а не
|
|
обойти его молча.
|
|
|
|
Имя ключа конфига проект числит **необратимым** (CLAUDE.md, «Работа»): раз
|
|
заведённый, он поедет в выкладку и в роль Ansible из `pet-project-server`.
|
|
Инвариант «Секрет не покидает конфиг» распространяется на этот пароль целиком.
|
|
Пустое значение обязано значить «никого не заводить»: иначе выкладка без ключа
|
|
перестанет подниматься. Переписывать пароль существующего владельца нельзя —
|
|
человек мог сменить его в панели.
|