docs: проект единой админки конфигов и indpic (#22)
This commit is contained in:
1 parent
847c642ca6
commit
b3b14ec193
1 file changed
+174
@@ -0,0 +1,174 @@
|
|||||||
|
# Единая админка прелендингов — preland#22
|
||||||
|
|
||||||
|
Дата: 25.10.2026. Статус: проект на согласование; реализация и выпуск ещё не выполнены.
|
||||||
|
Реестр: http://git.dira89kv.beget.tech:3000/anton/preland/issues/22.
|
||||||
|
Размещение и доступы: preland#21. Секреты в документ не входят.
|
||||||
|
|
||||||
|
## Задача владельца
|
||||||
|
|
||||||
|
Одна защищённая админка на поддомене stage управляет фактическими config.json и
|
||||||
|
наборами indpic четырёх независимых прелендингов. Редактирование и публикация контента
|
||||||
|
проходят без Git, ручной работы с JSON и разноса файлов через FTP-клиент.
|
||||||
|
Домены и хостинги можно добавлять, менять и отключать через эту же админку.
|
||||||
|
|
||||||
|
Начальные цели: zoomila.ru, zoomika.ru, zoompixel.ru, zoomstage.online.
|
||||||
|
Отключённые .online не подключаются. Рабочее имя админки: admin.zoomstage.online.
|
||||||
|
Размещение на отдельном поддомене и повторное использование редактора indpic CPanel
|
||||||
|
поручены владельцем; конкретное имя admin и технические решения ниже предложены агентом.
|
||||||
|
|
||||||
|
## Подход
|
||||||
|
|
||||||
|
Предлагается отдельное PHP-приложение в репозитории preland, с собственным Docker-образом
|
||||||
|
и отдельной поставкой. Оно использует SFTP/SSH, а для каталогов на том же сервере —
|
||||||
|
ограниченный файловый адаптер. Работа с конфигом не требует запуска деплоя.
|
||||||
|
Управление не публикуется внутри поставки обычных прелендингов.
|
||||||
|
|
||||||
|
Перенос всей Yii2 CPanel потребовал бы базы и зависимостей основного сайта; его API
|
||||||
|
и релиз стали бы зависимостью обычного изменения настроек. Поэтому переносится
|
||||||
|
конкретный редактор наборов, его внешний вид, поведение и файловый валидатор,
|
||||||
|
а зависимые от БД операции заменяются файловым реестром админки.
|
||||||
|
Клиентский FTP из браузера не подходит для серверных проверок и хранения доступов.
|
||||||
|
|
||||||
|
Источник переиспользования: api origin/master 591a67cc8302,
|
||||||
|
components/indpic/IndpicSetStorage.php и indpic-блок
|
||||||
|
modules/cpanel/views/settings/index.php, соответствующие действия SettingsController.
|
||||||
|
Копия снабжается ссылкой на источник и совместимыми контрактными тестами.
|
||||||
|
Бизнес-логика основного API, платежи, PIN и маршруты основного сайта не меняются.
|
||||||
|
|
||||||
|
## Экран настроек
|
||||||
|
|
||||||
|
Список доменов показывает stage/production, состояние соединения и последнее чтение.
|
||||||
|
Открытие домена читает текущий удалённый файл; локальная копия не считается источником
|
||||||
|
истины. При недоступности хоста сохранение в него недоступно, другие цели работают.
|
||||||
|
|
||||||
|
Вместо текстового JSON — поля адреса основного сайта, строки реквизитов и восемь
|
||||||
|
групп UTM: indpic, theme, degr, reg, banch, tp, cons, focus. Для каждой группы —
|
||||||
|
вариант по умолчанию, таблица вариантов и неотрицательные веса, пояснения значений.
|
||||||
|
Поддерживаются добавление и удаление строк весов. Реквизиты редактируются строками.
|
||||||
|
Дополнительные уже существующие поля показываются типизированными вложенными полями
|
||||||
|
(текст, число, переключатель, массив, объект), без редактора JSON. Отсутствующие
|
||||||
|
неизвестные поля не создаются автоматически. Секреты не выводятся в диагностику.
|
||||||
|
|
||||||
|
Текущий zoompixel.ru может содержать старые semantic-ключи/значения. Они отображаются
|
||||||
|
понятными вариантами через действующий utm-codec; сохранение меняет только выбранные
|
||||||
|
поля. Неизменённые поля, их типы и значения сохраняются. Конфликтующие старый и новый
|
||||||
|
ключи нельзя молча объединять: показывается понятная ошибка до записи.
|
||||||
|
|
||||||
|
После редактирования пользователь отмечает один или несколько доменов и нажимает
|
||||||
|
«Применить к выбранным». Перед кнопкой видны выбранные поля и домены. По умолчанию
|
||||||
|
отмечен только открытый домен; нет скрытого автоматического выбора всех целей.
|
||||||
|
Распространяются только изменённые/явно выбранные поля, остальные настройки каждой
|
||||||
|
цели сохраняются. Можно явно выбрать целую группу UTM или все поля формы.
|
||||||
|
Если значения между доменами отличаются, показывается «Разные значения»; без явного
|
||||||
|
ввода пользователя это состояние не превращается в новое значение.
|
||||||
|
|
||||||
|
До публикации для каждой цели проверяются типы/структура, допустимые UTM 1–9,
|
||||||
|
варианты theme/reg/banch/focus, веса, существование indpic для default и ненулевых
|
||||||
|
весов. Для degr/tp/cons используются номера групп, проверяемые по доступным данным
|
||||||
|
основного сайта. Если каталог доступен, неизвестный номер блокируется. Если каталог
|
||||||
|
недоступен, разрешён ручной выбор номера 1–9 с явной пометкой «Существование группы
|
||||||
|
на основном сайте не проверено» в форме и результате; сохранение не выдаётся за
|
||||||
|
проверку API. Это решение исполнителя сохраняет независимость редактора от API;
|
||||||
|
соответствующие состояния включены в приёмку. Выдуманного списка групп нет.
|
||||||
|
Сумма весов может быть нулевой: действующий
|
||||||
|
преленд тогда использует default. Адрес сайта — допустимый HTTPS-хост без пути.
|
||||||
|
|
||||||
|
## Сохранение и массовые операции
|
||||||
|
|
||||||
|
Каждая форма хранит версию прочитанного файла (SHA-256). Непосредственно перед записью
|
||||||
|
проверяется текущая версия под блокировкой публикации. Если файл изменился снаружи,
|
||||||
|
цель получает конфликт и предложение перечитать/повторно применить изменения.
|
||||||
|
Чужая версия не затирается. Успешная запись: резерв вне webroot, временный файл,
|
||||||
|
проверка JSON, атомарная замена и повторное чтение/сверка. Протокол и адаптер должны
|
||||||
|
поддерживать этот контракт, иначе соединение нельзя включить для записи.
|
||||||
|
SSH доступен на начальных REG.RU-хостах и позволяет выполнить проверку/замену под
|
||||||
|
удалённой блокировкой; одной локальной блокировки админки недостаточно.
|
||||||
|
|
||||||
|
Массовое применение — независимые операции с отдельными статусами: ожидание,
|
||||||
|
выполняется, сохранено и проверено, конфликт, ошибка, неизвестный результат.
|
||||||
|
Сбой одной цели не отменяет уже успешные и не мешает остальным. Общего обещания
|
||||||
|
«всё сохранено» при частичном успехе нет. Повтор выполняется только для выбранных
|
||||||
|
неуспешных целей; после таймаута сначала перечитывается фактическое состояние.
|
||||||
|
Задание и результаты сохраняются на сервере, обновление страницы их не теряет.
|
||||||
|
Есть журнал с доменом, временем, изменёнными полями и исходом без паролей.
|
||||||
|
Восстановление выбранной резервной версии проходит ту же защиту от конфликта.
|
||||||
|
|
||||||
|
## Наборы indpic
|
||||||
|
|
||||||
|
Переиспользуется таблица CPanel: номер/название, default, проверка, ZIP, действия;
|
||||||
|
добавление ZIP либо проверка набора, уже загруженного по SFTP, модальное окно результата.
|
||||||
|
Номер для прелендинга ограничен 1–9 действующим внешним UTM-контрактом.
|
||||||
|
Название хранится в приватном реестре админки, default/веса — в config.json цели.
|
||||||
|
|
||||||
|
Один архив можно отправить на один или несколько выбранных доменов. Проверка до
|
||||||
|
доставки: каталог номера набора и ровно 90 обязательных изображений, отсутствие
|
||||||
|
лишних/повторных/вложенных/опасных путей, чтение каждого изображения и размеры
|
||||||
|
из существующего IndpicSetStorage. Лимиты ZIP, распаковки и времени задаются сервером.
|
||||||
|
Проверенный набор передаётся в непубличную подготовительную папку на целевом хосте,
|
||||||
|
проверяются все файлы/SHA-256, затем переключается каталог с резервом и откатом при
|
||||||
|
ошибке. Папки подготовки/резерва никогда не обслуживаются веб-сервером.
|
||||||
|
Для уже загруженного по SFTP набора файлы проверяются тем же валидатором.
|
||||||
|
|
||||||
|
Загрузка не меняет default и веса автоматически. Назначение default — явная операция
|
||||||
|
сохранения config.json. Нельзя активировать неполный набор. Замена существующего
|
||||||
|
набора предварительно предупреждает о текущем использовании. Удаление из реестра,
|
||||||
|
как в CPanel, оставляет файлы; нельзя убрать набор, используемый default или весом>0.
|
||||||
|
Удаление физического контента не входит в исходное поручение.
|
||||||
|
|
||||||
|
## Подключения и защита
|
||||||
|
|
||||||
|
Отдельный вход по логину/паролю, хеш пароля, HTTPS, HttpOnly/SameSite session,
|
||||||
|
CSRF, ограничение попыток. Админка использует отдельные доступы ограниченного объёма;
|
||||||
|
приватный ключ root основного сервера приложению не передаётся.
|
||||||
|
Список целей, их имена, окружение, хост/порт, пользователь, корневая папка,
|
||||||
|
проверенный ключ SFTP и секрет редактируются на странице подключений.
|
||||||
|
Секрет можно заменить, но нельзя прочитать обратно в интерфейсе.
|
||||||
|
Проверка соединения должна подтвердить права и реальные пути до включения записи.
|
||||||
|
|
||||||
|
Приватное состояние, ключи, резервные копии, архивы и журнал — вне webroot/Git,
|
||||||
|
с ограниченными правами и персистентными Docker-томами. Удаление подключения отключает
|
||||||
|
управление и убирает его из списка целей, не удаляя сайт и контент хостинга.
|
||||||
|
Одновременные операции на одном конфиге/наборе сериализуются. Приложение не выполняет
|
||||||
|
произвольные команды, пути ограничены каталогом выбранной цели, host key проверяется.
|
||||||
|
|
||||||
|
## Независимость контента от Git и выпуск
|
||||||
|
|
||||||
|
Текущий workflow не заливает /N/, но --stage-sets сравнивает их с Git, а --remote
|
||||||
|
также включает их в общее сравнение. После замены существующего набора это блокировало
|
||||||
|
бы последующий выпуск кода. В #22 разделить проверки: поставляемый код/статические
|
||||||
|
ресурсы проверяются по manifest Git, runtime-наборы — по фактическому контракту 90
|
||||||
|
изображений и действующим ссылкам config, без требования импорта в Git.
|
||||||
|
Проверки не выключаются; тестами доказывается, что корректная замена набора пропускается,
|
||||||
|
повреждённый активный набор блокирует проверку, кодовой deploy не меняет config и /N/.
|
||||||
|
Устаревшие требования обязательной синхронизации наборов в Git обновляются явно по #22.
|
||||||
|
|
||||||
|
Админка выпускается отдельно от прелендов, с TLS на admin.zoomstage.online и четырьмя
|
||||||
|
подключениями. Изменение UTM пользователем не вызывает commit/push/CI. Реальные
|
||||||
|
production-настройки/наборы при установке не меняются. Проверочные записи — в выделенной
|
||||||
|
тестовой цели/наборе с последующим контролируемым восстановлением; отсутствие доступа
|
||||||
|
или непроверенный сценарий оставляет #22 открытой.
|
||||||
|
|
||||||
|
## Приёмка
|
||||||
|
|
||||||
|
В Docker: контракт валидатора CPanel, JSON-типы/semantic-совместимость, патч только
|
||||||
|
выбранных полей, конфликт и два одновременных сохранения, резерв/откат, разрыв связи,
|
||||||
|
таймаут после записи, повтор задания. Локальная SFTP-цель проверяет настоящий протокол.
|
||||||
|
ZIP: корректный набор, отсутствующий файл, размер/формат, лишний/повторный путь,
|
||||||
|
traversal, лимиты, ошибка публикации и сохранение старого рабочего набора.
|
||||||
|
|
||||||
|
В штатном браузере: вход, открыть/изменить/сохранить/перезагрузить конфиг; разные
|
||||||
|
значения, выбор одного/двух доменов и только нужных полей; частичный отказ, повтор,
|
||||||
|
конфликт и восстановление; ZIP и ошибка с последующей успешной загрузкой; управление
|
||||||
|
подключениями. Desktop/mobile и матрица всех общих состояний/четырёх целей.
|
||||||
|
На установленной админке: TLS/авторизация, чтение всех четырёх целей, безопасный
|
||||||
|
реальный цикл записи/повторного чтения и загрузки на тестовых данных. Итог, версия,
|
||||||
|
проверки и ограничения записываются в #22 и KB до закрытия задачи.
|
||||||
|
|
||||||
|
## Решения исполнителя и незавершённое
|
||||||
|
|
||||||
|
На усмотрение исполнителя: PHP-библиотека SFTP, детали приватного файлового реестра,
|
||||||
|
лимиты и хранение заданий, распараллеливание в пределах ресурсов. Выбор подтверждается
|
||||||
|
тестами и совместимостью с существующим хостингом; установки на Windows-хост нет.
|
||||||
|
Пока не выполнены: согласование этого проекта, реализация, проверки, настройка DNS/TLS,
|
||||||
|
выдача ограниченных доступов и запуск. Секреты/возможности среды требуют фактической
|
||||||
|
проверки; исторический успешный SFTP-вход не доказывает готовность центральной админки.
|
||||||
Reference in new issue
Block a user