From 5b6b2d2053975b7e3ffa6e8fbafeedea889b2fbd Mon Sep 17 00:00:00 2001 From: Panfilov Konstantin Date: Sun, 25 Oct 2026 10:46:16 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BB=D0=B0=D0=BD=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B0=D0=B4?= =?UTF-8?q?=D0=BC=D0=B8=D0=BD=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B5=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B4=D0=B8=D0=BD=D0=B3=D0=BE=D0=B2=20(#22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/2026-10-25-preland22-admin.md | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 docs/superpowers/plans/2026-10-25-preland22-admin.md diff --git a/docs/superpowers/plans/2026-10-25-preland22-admin.md b/docs/superpowers/plans/2026-10-25-preland22-admin.md new file mode 100644 index 0000000..df44766 --- /dev/null +++ b/docs/superpowers/plans/2026-10-25-preland22-admin.md @@ -0,0 +1,118 @@ +# 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.