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