Общие поля группы: проверки (2026-10-11)
set -a
. dev/.env
set +a
php dev/check-group-common-fields.php
php dev/check-group-common-scope.php
# Только если нужна новая опубликованная демогруппа:
php dev/check-group-common-fields.php --demo
php dev/bench/group-fields-scale.php
# HTTP запускать после масштабного замера, без его параллельных вставок:
python3 dev/bench/group-http.py
Без --demo собственные группы/товары переводятся в корзину, manifest существующего demo не заменяется. Scope-тест оставляет свои категории/поле в корзине. ID категории 51, полей/опций и ссылки на имеющиеся медиа — fixtures test.test, не данные других магазинов. --demo оставляет группу и шесть товаров опубликованными; manifest — ignored dist/common-fields-demo.json.
Масштабный тест берёт первый товар manifest, создаёт изолированные таблицы со случайным префиксом cgqa_, проверяет реальные EntityFields/CategoryModel на 100 и 100000 товарах. EXPLAIN требует индекс владельца. В finally удаляются только собственные таблицы; магазин и чужие bn_* не меняются. Это загрузка полей/списка без активных фильтров; групповые фасеты и конкурентная HTTP-нагрузка не измеряются.
HTTP делает 20 замеров после прогрева для каждого макета/AJAX/страницы, проверяет отсутствие group_field_* SQL в Joomla debugbar, не экспортирует debug/session данные. JSON-метрики — dist, итог — QA_GROUP_COMMON_FIELDS.md. Для адресного развёртывания вызвать GroupStorage::upgradeGenerator(); установщик вызывает upgrade автоматически. Новых CSS/JS нет.
Стенд
- Сайт: https://test.test, файлы
/Volumes/Work/Server/www/test(чистая Joomla 6.2.0, шаблонdharma_starter). ПеременнаяDHARMA_SITEпо умолчанию указывает на него;dharmatest.testтолько для чтения. - Для проверок по HTTP: тестовый пользователь
dharmadev(Super Users). Логин и пароль лежат вdev/.env(в git не попадает; шаблон —dev/.env.example). Пользователяdharmaне трогаем. - Загрузка окружения:
set -a; . dev/.env; set +a.
Скрипты dev/
| Скрипт | Что делает |
|---|---|
boot.php | поднимает консольное приложение Joomla на DHARMA_SITE |
install.php <zip> | устанавливает пакет как «Установка расширений»; передавайте абсолютный путь к zip |
uninstall.php | удаляет пакет pkg_dharmashop (вместе с таблицами) |
sync.sh | раскладывает исходники в сайт без сборки zip (после первой установки): компонент, общие макеты, модули корзины, поиска, фильтра, категорий и товаров (код, media, языки) |
sync-export.sh | раскладывает компонент экспорта, плагины форматов, задачу планировщика, плагин меню и общий скрипт окна прогресса из рабочего дерева; терпим к сайту без языковых папок (чистая установка) |
check-export.php | проверки ядра экспорта на изолированных таблицах и своей папке (все сущности, возобновление, блокировки, XLSX, YML, 100 тыс. товаров); результат — dist/export-qa.json |
install-module.php <папка> [позиция] | устанавливает модуль из папки репозитория штатным установщиком (создаёт запись расширения и, если указана позиция, опубликованный экземпляр) |
reindex-search.php | полная пересборка поискового индекса на тестовом сайте |
db.sh "SQL" | запрос к базе сайта; PFX_ заменяется префиксом таблиц |
web-login.sh | вход в админку по HTTP, куки в $COOKIES (нужны DHARMA_USER, DHARMA_PASS, DHARMA_URL) |
make-category.php <extension> "<название>" [родитель] | создаёт категорию нужного типа (com_dharmashop, .brand, .badge) |
save-category.sh <extension> "Название" [родитель] [цвет] | создаёт категорию/бренд/бейдж через форму админки по HTTP |
save-product.sh "Название" <catid> <артикул> <цена> [brand] [badge] | создаёт товар через форму админки по HTTP (нужен вход web-login.sh) |
security-upload.sh | проверка защиты загрузчика изображений (токен, права, подмена типа, обход путей, SVG); см. docs/SECURITY.md |
bench/bench.php | генератор тестового каталога и замеры (generate/run/all/drop), см. docs/BENCHMARKS_NOTES.md |
bench/report.php | собирает docs/BENCHMARKS.md из dev/bench/results/*.json |
scenario/fixture.py [фаза …] | наполняет чистую локальную установку мини-магазином через формы админки по HTTP: склады, поля, категории, 8 товаров, 2 группы с вариантами, доставка, оплата, акции, контакты оформления, посадочные страницы, модули. Повторный запуск пропускает уже созданное |
scenario/scenarios.py [раздел …] | сценарии посетителя и сотрудника на наполненной установке (каталог, фильтры, поиск, страницы товаров и JSON-LD, избранное, корзина, купоны, оформление, лимиты, посадочные, админка и справка, права оператора, «Мои заказы», скорость); разделы: browse product favorites cart checkout landing admin users perf all; печатает PASS/FAIL, находки и предупреждения PHP из ответов |
scenario/lib.py | клиент для сценариев (вход, разбор форм Joomla, db()); работает только с адресами *.test, localhost, 127.0.0.1 |
Сценарии настраиваются переменными SCENARIO_URL, SCENARIO_USER, SCENARIO_PASS (тестовый суперпользователь, в репозиторий не попадает) и SCENARIO_SITE_PATH (папка сайта для чтения базы). Они создают заказы, пользователей и группу «QA оператор заказов» — запускайте только на одноразовой установке, не на сайте с реальными данными. Адреса покупателей уникальны для каждого запуска; лимит заказов с одного IP на время сценариев поднимается через форму настроек и возвращается к 10.
Адресное обновление переводов
Joomla загружает установленные переводы компонента из administrator/language/<язык>/com_dharmashop.ini и language/<язык>/com_dharmashop.ini. При адресной синхронизации языки нужно копировать туда из admin/site language исходников; копии внутри components/com_dharmashop/language не заменяют установленные. Проверять актуальность обоих RU/EN файлов. При установке пакета это делает манифест <languages>. Для кнопок админки используйте классы из установленного joomla-fontawesome.css: например, icon-folder-open; icon-layer-group в Joomla 6.2.0 отсутствует.
Сборка и установка
build.sh перед упаковкой сверяет COM_DHARMASHOP-ключи в Form XML и XML типов пунктов меню с RU/EN словарями администратора. Если перевод пропущен или имя ключа расходится, сборка останавливается с указанием языка, ключа и файла.
./build.sh # dist/pkg_dharmashop-<версия>.zip
DHARMA_SITE=/Volumes/Work/Server/www/test php dev/install.php "$PWD/dist/pkg_dharmashop-0.1.15.zip"
Версии манифестов меняются только при выпуске пакета через python3 dev/release.py bump <версия> --since <последний-тег>; во время разработки сохраняется версия последнего выпуска. Новые расширения добавляйте в EXTENSIONS в build.sh и в <files> манифеста pkg_dharmashop.xml.
В манифестах модулей используйте читаемое значение в <name>, а не языковой ключ: штатный журнал действий Joomla сохраняет это поле буквально и не переводит его. Ключи <description> по-прежнему переводятся через *.sys.ini.
С C32 пакет содержит файловое расширение files_dharmashop_layouts (первым), компонент и два SEO-плагина. Оно устанавливает карточки из files_dharmashop_layouts/layouts/ в общую библиотеку layouts/components/dharmashop/. Только файлы, перечисленные в манифесте, принадлежат расширению; дополнительные пользовательские файлы не перечисляются.
Первый переход со старой папки компонента выполняется обновлением пакета, без деинсталляции: пакетный скрипт сохраняет её перед удалением Joomla и переносит в новую папку. При ошибке или конфликте остаётся каталог восстановления tmp_path/dharmashop-layouts-*, указанный в сообщении. Не удаляйте его до разбора результата. Схема БД не меняется, каталог магазина сохраняется.
После установки этого обновления dev/sync.sh копирует общие макеты без --delete, сохраняя дополнительные файлы; старый /layouts/ компонента исключён из удаления rsync до штатной миграции. Сам sync не регистрирует файловое расширение и не выполняет миграцию, поэтому для первого перехода не подходит. Изменения поставляемых файлов при последующих обновлениях держите в переопределениях шаблона.
WebAssetManager (C35)
Реестр com_dharmashop/media/joomla.asset.json устанавливается в media/com_dharmashop/joomla.asset.json. Скрипты — отдельные файлы media/js/ с именованными ресурсами, зависимости перечислять явно. Во frontend-виде добавить реестр через $wa->getRegistry()->addExtensionRegistryFile('com_dharmashop'), затем использовать только нужный $wa->useScript(...). Для C34 это com_dharmashop.listing → установленный media/com_dharmashop/js/listing.js. Не подключать все ресурсы глобально и не писать script-теги в макетах. Uploader/gallery остаются ресурсами своих полей, нового CSS фронтенда нет.
C48: com_dharmashop.sale-countdown подключается менеджером только там, где включён таймер и есть действующая акция с discount_end. Скрипт media/js/sale-countdown.js обновляет Bootstrap badge; в HTML уже есть начальный текст на случай отключённого JavaScript.
Правила проверки реализации
После C34 пакет установлен обновлением на test.test (INSTALL OK): модель/вид category, три карточки товара и listing.js присутствуют. Тесты, HTTP-рендер, браузер и замеры не запускались. Разметку/запросы/автоматическую отправку формы ещё требуется проверить отдельно по запросу пользователя.
- После изменения схемы: удалить пакет (
dev/uninstall.php), собрать, установить, проверить число таблиц (dev/db.sh "show tables like 'PFX_dharmashop%'"). Пока релизов нет, схему правим прямо вinstall.mysql.utf8.sql; после первого релиза — только черезsql/updates/mysql/<версия>.sql. - C50 — исключение для сохранения действующего каталога: столбцы
targetвfieldgroups/fieldsдобавляются идемпотентно в пакетномscript.php::upgradeFieldTargets()при обновлении. Не деинсталлировать пакет ради этого изменения; текущие данные сохраняются. Новая установка использует обновлённыйinstall.mysql.utf8.sql. Версия остаётся0.1.0. - C51:
script.php::upgradeFieldGroupTabs()так же аддитивно добавляетfieldgroups.tab_modeсо значениемfields. Не деинсталлировать пакет; прежние группы и значения сохраняются. Административная папкаlayoutsявно включена в манифест компонента. - C59:
script.php::upgradeFieldValueStorage()добавляетfield_values.num_endи индекс, создаётcategory_field_values/category_field_texts. Установка только обновлением; определения, опции, значения и пользовательские записи сохраняются. Автоматические сценарии без запроса пользователя не запускать. - Изменения скорости на путях витрины — прогнать
dev/benchминимум на 100 000 товаров и обновитьdocs/BENCHMARKS.md. - Пустые папки в манифесте компонента ломают установку (проверено: пустая
forms). - Данные бенчмарка лежат в таблицах
bn_*той же базы; после замеровphp dev/bench/bench.php drop.
Проверка генератора групп
По запросу пользователя на проверку генерации:
set -a
. dev/.env
set +a
php dev/check-group-generator.php
Только test.test через dev/boot.php, AdministratorApplication и штатные модели. Требует два опубликованных поля выбора с двумя опциями, категорию и два имеющихся фото. Создаёт собственную группу/четыре товара; проверяет подготовку без записи, повтор, формулу/алиасы, цены/остатки, состояние, фото/тексты/поля, ошибки и лимиты. В finally переводит собственные записи в корзину, файлы не удаляет. 2026-10-11 — 20 PASS. Конкурентные запросы и искусственный сбой посередине создания отдельно не проверены. При адресном развёртывании дополнительно вызвать идемпотентный GroupStorage::upgradeGenerator(); установщик пакета вызывает общий upgrade сам.
Встроенная справка
./build.sh запускает dev/generate-help-site.py для staging-копии компонента перед упаковкой. Генератор сверяет каждый slug с файлом в docs/, формирует admin/help/manifest.json и отдельный HTML-файл на статью. Проверить его отдельно можно так:
tmp_dir=$(mktemp -d)
python3 dev/generate-help-site.py "$tmp_dir/help"
python3 -m json.tool "$tmp_dir/help/manifest.json" >/dev/null
rm -rf "$tmp_dir"
В манифесте есть только утверждённые пользовательские и разработческие статьи. При добавлении новой статьи обновите GROUPS в генераторе и пересоберите пакет. После установки проверьте экран Dharma Shop → Помощь, несколько статей из обоих разделов и справочник настроек. Документы обслуживаются только административным видом; фронтенд каталога их не загружает.
Выпуск версий и ленты обновлений
Миграции БД обязательны. Если у компонента изменился sql/install*.sql, он обязан получить новый файл в sql/updates/mysql/<версия>.sql (идемпотентный: CREATE TABLE IF NOT EXISTS, проверка колонки/индекса перед ALTER). dev/release.py bump проверяет это и отказывает, если файла нет (для осознанного пропуска — --skip-migration-check); dev/release.py status --since … печатает предупреждение. Манифест компонента должен содержать <update><schemas><schemapath type="mysql">sql/updates/mysql</schemapath></schemas></update>. Перед выпуском проверьте «обновление поверх предыдущей версии» на стенде.
Обновляется только пакет: <updateservers> есть только в pkg_dharmashop.xml и ведёт на коллекцию updates/dharma-shop.xml (её генерирует dev/release.py feed; адрес сохранён, потому что он зарегистрирован у уже установленных сайтов). В коллекции одна запись — пакет, со ссылкой на ленту updates/pkg_dharmashop.xml. У остальных расширений источника обновлений нет.
Версия у всех расширений и пакета одна — версия выпуска (bump ставит её везде). Ленты обновлений Joomla и архив пакета раздаются из публичного репозитория shivayanamahom/dharma-shop-updates (GitHub Pages для updates/*.xml, Releases для zip пакета). Исходный репозиторий может оставаться закрытым.
./build.sh # dist/pkg_dharmashop-<версия>.zip
DHARMA_SITE=/Volumes/Work/Server/www/test php dev/install.php "$PWD/dist/pkg_dharmashop-0.1.15.zip"
Версии манифестов меняются только при выпуске пакета через python3 dev/release.py bump <версия> --since <последний-тег>; во время разработки сохраняется версия последнего выпуска. Новые расширения добавляйте в EXTENSIONS в build.sh и в <files> манифеста pkg_dharmashop.xml.
С C32 пакет содержит файловое расширение files_dharmashop_layouts (первым), компонент и два SEO-плагина. Оно устанавливает карточки из files_dharmashop_layouts/layouts/ в общую библиотеку layouts/components/dharmashop/. Только файлы, перечисленные в манифесте, принадлежат расширению; дополнительные пользовательские файлы не перечисляются.
Первый переход со старой папки компонента выполняется обновлением пакета, без деинсталляции: пакетный скрипт сохраняет её перед удалением Joomla и переносит в новую папку. При ошибке или конфликте остаётся каталог восстановления tmp_path/dharmashop-layouts-*, указанный в сообщении. Не удаляйте его до разбора результата. Схема БД не меняется, каталог магазина сохраняется.
После установки этого обновления dev/sync.sh копирует общие макеты без --delete, сохраняя дополнительные файлы; старый /layouts/ компонента исключён из удаления rsync до штатной миграции. Сам sync не регистрирует файловое расширение и не выполняет миграцию, поэтому для первого перехода не подходит. Изменения поставляемых файлов при последующих обновлениях держите в переопределениях шаблона.
WebAssetManager (C35)
Реестр com_dharmashop/media/joomla.asset.json устанавливается в media/com_dharmashop/joomla.asset.json. Скрипты — отдельные файлы media/js/ с именованными ресурсами, зависимости перечислять явно. Во frontend-виде добавить реестр через $wa->getRegistry()->addExtensionRegistryFile('com_dharmashop'), затем использовать только нужный $wa->useScript(...). Для C34 это com_dharmashop.listing → установленный media/com_dharmashop/js/listing.js. Не подключать все ресурсы глобально и не писать script-теги в макетах. Uploader/gallery остаются ресурсами своих полей, нового CSS фронтенда нет.
C48: com_dharmashop.sale-countdown подключается менеджером только там, где включён таймер и есть действующая акция с discount_end. Скрипт media/js/sale-countdown.js обновляет Bootstrap badge; в HTML уже есть начальный текст на случай отключённого JavaScript.
Правила проверки реализации
После C34 пакет установлен обновлением на test.test (INSTALL OK): модель/вид category, три карточки товара и listing.js присутствуют. Тесты, HTTP-рендер, браузер и замеры не запускались. Разметку/запросы/автоматическую отправку формы ещё требуется проверить отдельно по запросу пользователя.
- После изменения схемы: удалить пакет (
dev/uninstall.php), собрать, установить, проверить число таблиц (dev/db.sh "show tables like 'PFX_dharmashop%'"). Пока релизов нет, схему правим прямо вinstall.mysql.utf8.sql; после первого релиза — только черезsql/updates/mysql/<версия>.sql. - C50 — исключение для сохранения действующего каталога: столбцы
targetвfieldgroups/fieldsдобавляются идемпотентно в пакетномscript.php::upgradeFieldTargets()при обновлении. Не деинсталлировать пакет ради этого изменения; текущие данные сохраняются. Новая установка использует обновлённыйinstall.mysql.utf8.sql. Версия остаётся0.1.0. - C51:
script.php::upgradeFieldGroupTabs()так же аддитивно добавляетfieldgroups.tab_modeсо значениемfields. Не деинсталлировать пакет; прежние группы и значения сохраняются. Административная папкаlayoutsявно включена в манифест компонента. - C59:
script.php::upgradeFieldValueStorage()добавляетfield_values.num_endи индекс, создаётcategory_field_values/category_field_texts. Установка только обновлением; определения, опции, значения и пользовательские записи сохраняются. Автоматические сценарии без запроса пользователя не запускать. - Изменения скорости на путях витрины — прогнать
dev/benchминимум на 100 000 товаров и обновитьdocs/BENCHMARKS.md. - Пустые папки в манифесте компонента ломают установку (проверено: пустая
forms). - Данные бенчмарка лежат в таблицах
bn_*той же базы; после замеровphp dev/bench/bench.php drop.
Проверка генератора групп
По запросу пользователя на проверку генерации:
set -a
. dev/.env
set +a
php dev/check-group-generator.php
Только test.test через dev/boot.php, AdministratorApplication и штатные модели. Требует два опубликованных поля выбора с двумя опциями, категорию и два имеющихся фото. Создаёт собственную группу/четыре товара; проверяет подготовку без записи, повтор, формулу/алиасы, цены/остатки, состояние, фото/тексты/поля, ошибки и лимиты. В finally переводит собственные записи в корзину, файлы не удаляет. 2026-10-11 — 20 PASS. Конкурентные запросы и искусственный сбой посередине создания отдельно не проверены. При адресном развёртывании дополнительно вызвать идемпотентный GroupStorage::upgradeGenerator(); установщик пакета вызывает общий upgrade сам.
Встроенная справка
./build.sh запускает dev/generate-help-site.py для staging-копии компонента перед упаковкой. Генератор сверяет каждый slug с файлом в docs/, формирует admin/help/manifest.json и отдельный HTML-файл на статью. Проверить его отдельно можно так:
tmp_dir=$(mktemp -d)
python3 dev/generate-help-site.py "$tmp_dir/help"
python3 -m json.tool "$tmp_dir/help/manifest.json" >/dev/null
rm -rf "$tmp_dir"
В манифесте есть только утверждённые пользовательские и разработческие статьи. При добавлении новой статьи обновите GROUPS в генераторе и пересоберите пакет. После установки проверьте экран Dharma Shop → Помощь, несколько статей из обоих разделов и справочник настроек. Документы обслуживаются только административным видом; фронтенд каталога их не загружает.
Выпуск версий и ленты обновлений
Миграции БД обязательны. Если у компонента изменился sql/install*.sql, он обязан получить новый файл в sql/updates/mysql/<версия>.sql (идемпотентный: CREATE TABLE IF NOT EXISTS, проверка колонки/индекса перед ALTER). dev/release.py bump проверяет это и отказывает, если файла нет (для осознанного пропуска — --skip-migration-check); dev/release.py status --since … печатает предупреждение. Манифест компонента должен содержать <update><schemas><schemapath type="mysql">sql/updates/mysql</schemapath></schemas></update>. Перед выпуском проверьте «обновление поверх предыдущей версии» на стенде.
Все манифесты указывают на один источник — коллекцию updates/dharma-shop.xml (её генерирует dev/release.py feed); подробные ленты updates/<расширение>.xml лежат рядом и нужны только при установке.
Версия расширения — версия выпуска, в котором оно менялось в последний раз; у пакета версия выпуска всегда. Ленты обновлений Joomla и архивы раздаются из публичного репозитория shivayanamahom/dharma-shop-updates (GitHub Pages для updates/*.xml, Releases для zip). Исходный репозиторий может оставаться закрытым.
# 1. что изменилось с прошлого выпуска (справочно; тег основного репозитория)
python3 dev/release.py status --since v0.1.1
# 2. версия пакета и всех расширений := новая версия (<updateservers> остаётся только у пакета)
python3 dev/release.py bump 0.1.2 --since v0.1.1
# 3. миграции БД: любое изменение схемы — файл com_…/admin/sql/updates/mysql/<версия>.sql (идемпотентный) и <update><schemas> в манифесте компонента
# 4. коммит, затем сборка ленты и архива пакета в рабочую копию репозитория обновлений
python3 dev/release.py feed 0.1.2 --out ../dharma-shop-updates --download-base https://github.com/shivayanamahom/dharma-shop-updates/releases/download --channel dev
# 5. публикация: коммит и push ленты, затем релиз с архивом пакета
cd ../dharma-shop-updates && git add updates && git commit -m "Ленты 0.1.2" && git push
gh release create v0.1.2 --prerelease --title "Dharma Shop 0.1.2" assets/v0.1.2/*
Проверка перед публикацией (стенд dharmashoptest): поставить прошлый пакет, выложить новые ленты на локальный сервер (php -S 127.0.0.1:8099 -t <папка> и сменить location в #__update_sites), убедиться, что Joomla находит только изменившиеся расширения, обновляется нужный плагин и пакет, а испорченная контрольная сумма блокирует установку.
Замечание про локальную проверку: PHP Kettle собран с библиотекой c-ares и при включённом VPN-туннеле без DNS в настройках сети не находит адреса («Could not resolve host»). Обновления на таком стенде проверяйте PHP ServBay (/Applications/ServBay/package/php/8.4/current/bin/php cli/joomla.php update:extensions:check) или добавьте DNS-серверы в настройках сети. Сервер раздачи для проверки — только по http: локальный HTTPS-сертификат PHP не принимает.