Files
preland/docs/superpowers/plans/2026-10-25-preland22-admin.md
T

11 KiB
Raw Blame History

preland#22 — план реализации единой админки

Спецификация: ../specs/2026-10-25-preland22-admin-design.md; основной реестр preland#22. Владелец 25.10 поручил выполнение командой до production без повторного подтверждения. Метод: writing-plans, dispatching-parallel-agents для независимых файловых областей, TDD, систематическая диагностика при сбоях, независимое review и verification-before-completion. Работа в уже изолированном wt/preland21; исходные checkout/ветки не переключаются.

Цель: безопасно редактировать поля runtime-конфигов и публиковать indpic на выбранных доменах. Архитектура: отдельное PHP-приложение admin/, прямые local/SFTP+SSH-адаптеры, приватный файловый реестр/очередь заданий, повторное использование CPanel indpic UI/валидатора. Стек: PHP8.3, phpseclib3, Imagick/ZIP, Apache, отдельный CLI-worker, Docker, nginx/TLS. Python используется в инструментах QA/инфраструктуры, Yii2 — источник совместимого контракта, новые прикладные микросервисы без функциональной причины не добавляются.

Общие ограничения и карта поверхности

  • Русский интерфейс/документация, все поля config через формы, JSON-editor отсутствует.
  • Четыре начальные цели, произвольный дальнейший реестр; .online кроме stage не включать.
  • Изменения только выбранных полей/целей, конфликты версий, резерв вне webroot, атомарная публикация и повторное чтение, статусы/повтор каждой цели независимо.
  • Секреты только вне Git/webroot; ключ root приложению не передаётся.
  • indpic1–9, ZIP и 90файлов проверяются действующим валидатором CPanel.
  • Сохранить runtime config и /N/ при кодовом deploy; guard runtime проверяет контракт, а статические ресурсы остаются привязаны к manifest Git.
  • Все зависимости/тесты в Docker. Browser plugin not available: реальный UI в Docker Playwright.
  • Карта UI: login, домены/подключения, настройки/доп.поля, выбор целей/полей, задания/частичный успех/конфликт/повтор, резерв/восстановление, indpic ZIP/SFTP/default.

Общий HTTP-контракт для независимой реализации

Все ответы JSON: {ok:true,...} либо {ok:false,error:"понятный текст"}; безопасные HTTP-коды. POST/PUT/DELETE требуют header X-CSRF-Token после login; multipart также использует header.

  • POST /api/login {username,password}; GET /api/state → {csrf,user,targets}; POST /api/logout.
  • targets имеют id,name,domain,environment,type(local|sftp),host,port,user,root,host_key, enabled,has_secret; сервер никогда не возвращает secret/private_key.
  • POST /api/targets {target:{...},secret?:string}; DELETE /api/targets {id}; POST /api/targets/test {id} проверяет подключение и безопасные пути.
  • GET /api/config?target=id → {config,version,warnings,sets}; version=SHA256 текущего файла.
  • POST /api/apply {targets:[{id,version}],changes:[{path:[string...],value:any,delete?:bool}]} → {job}; версии каждой цели берутся её собственным чтением, не от исходного домена.
  • GET /api/jobs?id=id → {job}; без id → {jobs}; POST /api/jobs/retry {id,targets:[id...]} → {job}. job={id,status,results:[{target,status,message,version?}],...}; статусы queued,running, success,error,conflict,unknown; статус задания queued,running,completed.
  • GET /api/backups?target=id → {backups:[{id,created_at}]}; POST /api/restore {target,id,version} → {job}.
  • GET /api/sets?target=id → {sets:[{number,name,exists,default,in_use}],version}; POST /api/sets/upload multipart file,number,name,targets(JSON-массив id) → {job}; POST /api/sets/check {targets:[id],number} → {job}; POST /api/sets/register аналогично +name; POST /api/sets/name {target,number,name}; POST /api/sets/delete {target,number}; default задаётся /api/apply по path utm/indpic/default и текущей version. Технические расширения контракта допустимы с синхронизацией агентов и записью в #22.

Задача 1 (#22): серверная логика и файловый контракт

Владелец: backend (Yii2 senior/PHP senior, security/transport). Файлы: admin/src/, admin/public/index.php, admin/bootstrap.php, admin/bin/, admin/composer.json/lock, admin/tests/backend*.php; не менять UI/Docker/CI.

  • RED: выбранный patch сохраняет поля/типы, чужая версия не затирается, массовая ошибка одной цели не откатывает другие, резерв восстанавливается по версии.
  • Реализовать auth/CSRF, защищённый реестр соединений, транспорт local и SFTP/SSH, серверные задания/worker, конфиги/валидацию/историю и HTTP-контракт выше.
  • Перенести IndpicSetStorage с атрибуцией; проверять ZIP до доставки, затем хеши, публикацию/откат; регистрацию SFTP-набора, имена/default/удаление из реестра.
  • GREEN в Docker, реальные подключения через локальную SFTP-цель, auth/error/race/ZIP tests.

Задача 2 (#22): интерфейс на основе CPanel

Владелец: frontend senior, дизайнер, верстальщик. Файлы: admin/views/dashboard.php, admin/public/assets/, admin/tests/ui.cjs. Вход public/index.php рендерит dashboard.php для обычных URL; API выше.

  • Форма входа, домены, редактор всех config-полей и UTM, один/несколько выбранных доменов и только изменённые поля; версии до редактирования, без silent overwrite.
  • Таблица/действия indpic копируют CPanel, включая ZIP/SFTP и понятное окно проверки.
  • Подключения/история/резерв, задания/частичные ошибки/повтор, loading/error/recovery; безопасный текстовый вывод любых серверных полей, desktop/mobile/keyboard.
  • Реальные browser сценарии login→чтение→ввод→выбор2целей→применить→reload; ошибка/восстановление/ZIP; сохранить screenshot и console evidence вне repo.

Задача 3 (#22): runtime guard и доставка

Владелец: DevOps/QA (независимо от admin/). Файлы: bin/release-assets.php, новый bin/check-runtime-sets.php, tests/check-runtime-sets.php, .gitea/workflows/deploy.yml, AGENTS.md/CLAUDE.md/README.md только относящиеся части.

  • RED: корректно заменённый runtime-набор не требует Git; повреждённый активный набор/невалидный default выявляется; общая проверка статики не ослабевает.
  • Изменить --stage-sets/--remote на контрактную проверку runtime /N/ и manifest только кода/поставляемых ресурсов; admin/ и приватные файлы не входят в preland releaseFiles.
  • GREEN в Docker + старые preland tests/manifest; документация обновляет #11 явно.

Задача 4 (#22): интеграция, инфраструктура и приёмка

Владелец: ведущий агент (Senior DevOps/Linux/Windows, QA и release). Файлы: admin/Dockerfile, admin/compose.yaml, admin/deploy/, admin/README.md, локальные output/preland22/; KB Спеки/Планы/Инфраструктура и индекс.

  • Создать образ/локальный стенд и SSH/SFTP fixture, запустить backend/guard тесты.
  • Реальный UI-клик в Docker Playwright 1440/390: все общие состояния и контракты из спецификации, с отдельными read/save/conflict/partial/retry/ZIP свидетельствами.
  • Независимое review всего diff; исправить существенные замечания, повторить затронутые сценарии, подготовить rollback и неизменяемую версию образа.
  • Настроить admin.zoomstage.online DNS/TLS/nginx, ограниченные local mount/SFTP доступы, секреты в приватном состоянии, отдельный worker; текущий трафик не прерывать.
  • Проверить на установленной админке вход/чтение всех4целей, реальный безопасный write/read/ZIP/error/recovery с возвратом исходных runtime; никаких ложных PASS.
  • Опубликовать код и KB, занести итог/проверки/версии/ограничения в #22, закрыть только после завершения. Неисполненные обязательные сценарии оставить открытыми.

Особое внимание review

  1. Разные версии/типы/legacy-alias четырёх файлов и потеря неизвестных полей — тест задачи1.
  2. Таймаут после фактической записи/обновление страницы — задания/повтор задачи1+2.
  3. Повреждённый ZIP/размер/traversal/лимит/ошибка активации — задача1 и UI задачи2.
  4. Подмена пути/host key, утечка пароля, CSRF/сессия и незавершённые задания — задача1/4.
  5. Runtime-изменения не должны блокировать выпуск или публиковать admin-секреты — задача3/4.