tasks: владельца панели заводит отдельная команда, а не ключ конфига

- admin-owner-from-config закрыта: решение владельца 2026-08-15, ключ конфига
  не заводится, требование спеки storage остаётся в силе
- dev-run-task вобрала cmd/devadmin и стоит первой строкой: инструмент и шаг
  порознь не нужны, поэтому едут одной задачей
This commit is contained in:
av
2026-08-15 20:49:50 +03:00
parent 97c6c7c440
commit 2bb252e018
4 changed files with 28 additions and 75 deletions
+26 -14
View File
@@ -1,13 +1,18 @@
# 🧹 Поднимать сервис и заглушку одной командой
- **Тип:** chore
- **Категория:** Очередь — шаг dev заводит владельца панели тем самым ключом — до него команду не собрать
- **Зачем:** Локальная проверка требует двух терминалов, ручной остановки обоих процессов и чистки каталога данных; учётную запись заводят проходом по браузеру.
- **Категория:** Очередь — оснастка локального прогона: без неё каждую проверку начинают с двух терминалов и ручной уборки
- **Зачем:** Локальная проверка требует двух терминалов, ручной остановки обоих процессов и чистки каталога данных; учётную запись заводят проходом по браузеру, а владельца панели — по одноразовой ссылке из журнала.
Шаг `task dev CONFIG=<путь> USER=<почта>` поднимает сервис и подставной
провайдер OIDC разом, кладёт данные во временный каталог, заводит учётные записи
и гасит оба процесса по Ctrl+C.
Работа состоит из двух частей, и они едут одним коммитом: инструмент
`cmd/devadmin` и шаг `dev`, который его зовёт. Порознь они не нужны — шаг без
инструмента не заведёт владельца панели, инструмент без шага останется вызовом,
который никто не делает.
Задуманное устройство:
- конфиг пишет человек и передаёт путём — шаг его не сочиняет;
@@ -15,20 +20,24 @@
каталог со своим `data_dir`, чтобы прогон начинался с пустой базы независимо от
того, что написано в конфиге. Временное живёт в `/tmp` — в `data/` писать
запрещено (CLAUDE.md, «Запреты»);
- оба процесса идут одной группой, `trap` на `INT` и `TERM` гасит их разом,
`wait` держит терминал;
- владельца панели заводит `cmd/devadmin` — отдельный main-пакет рядом с
`cmd/oidcstub`, в образ он не едет. Базу открывает тем же `pbrepo.New`, что и
сервис, и потому получает её со схемой целиком; зовётся до подъёма сервиса, на
пустом каталоге. Пароль существующего владельца не переписывает;
- шаг заводит обычную учётную запись входом: поднимает `cmd/oidcstub` с
`-email` из `USER`, сам проходит цепочку входа и тем создаёт запись;
- владельца панели заводит **ключ конфига**, который приносит
[admin-owner-from-config](admin-owner-from-config.md). До неё шаг владельца
панели завести не может — отсюда и место в списке.
- оба процесса идут одной группой, `trap` на `INT` и `TERM` гасит их разом,
`wait` держит терминал.
## Затрагивает
- `cmd/devadmin` — новый main-пакет: заводит владельца панели в базе;
- `Taskfile.yml` — шаг `dev` с переменными `CONFIG` и `USER`;
- скрипт запуска в `scripts/` — он попадает под шаг `shell` гейта;
- `CLAUDE.md`, раздел «Команды»;
- `README.md`, раздел про локальный запуск.
- `README.md`, раздел про локальный запуск;
- `Dockerfile` — строка сборки называет точку входа поимённо, и новый пакет в
образ попасть не должен.
## Критерии приёмки
@@ -37,15 +46,18 @@
порты.
- Ctrl+C гасит обоих и не оставляет висящих процессов. Оракул: `pgrep` по обоим
именам после остановки — пусто.
- После запуска в базе есть учётная запись с переданной почтой. Оракул: запрос к
коллекции пользователей во временной базе.
- После запуска в базе есть учётная запись с переданной почтой, а владелец панели
входит своим паролем. Оракул: запрос к коллекции пользователей во временной базе
и вход по `auth-with-password` в коллекцию владельцев.
- Каталог данных лежит во временном месте, а `data/` не тронут. Оракул: путь базы
из журнала подъёма и `git status` после прогона.
- `task gate` остаётся зелёным, скрипт проходит `shellcheck`. Оракул: прогон
гейта целиком.
- `task gate` остаётся зелёным, скрипт проходит `shellcheck`, а образ не получает
нового пакета. Оракул: прогон гейта целиком и `task image`.
## Рамки
Шаг локальный: наружу не ходит, боевых ключей не требует и в образ не попадает.
Распознавание при выдуманных ключах не работает — это остаётся как есть, шаг его
не подменяет.
Пароль владельца в конфиг **не заводится** — требование спеки `storage` «Пароль
владельца от панели не лежит в конфигурации» остаётся в силе, и работа его не
трогает. Распознавание при выдуманных ключах не работает — это остаётся как есть,
шаг его не подменяет.