add: описание DSL (draft 1)

This commit is contained in:
2026-08-02 18:12:58 +03:00
parent ff1369f200
commit c1ee3ae930
+114
View File
@@ -0,0 +1,114 @@
# Спецификация: LPON Store Hub DSL (Компактный конструктор интерфейсов на кортежах)
драфт
## 1. Обзор и цели
Мы реализуем гибкий, управленный данными (Data-Driven) конструктор страниц внутри бэкенда Django для **LPON.RU**.
Вместо написания отдельных вьюх (Views) и шаблонов под каждый формат или раздел (например, `/catalog/cassettes/`, `/catalog/vinyl/`), мы формируем динамические **Страницы-Хабы (Hub Pages)** с помощью компактного JSON Tuple DSL, который хранится прямо в базе данных.
Система завязана на модель `TbArticle` с типом `l_article_type = 'HUB'`. Конфигурация хранится в JSON-поле метаданных статьи (`j_article_metadata['hub']`).
---
## 2. Синтаксис и структура JSON DSL
Массив `hub` представляет собой список позиционных кортежей (массивов). Движок определяет тип блока на основе длины массива и типов переданных значений.
### Правила синтаксиса:
```json
{
"hub": [
["source-slug", "view_mode"],
["source-slug", limit, "sort_rule", "view_mode"],
["module-or-article-slug"]
]
}
```
## 3. Спецификация блоков
### Тип A: Блок предложений товаров (по умолчанию Длина = 4)
Выводит подборку товаров (TbOffer), полученную на основе категории, тега формата или слаг-коллекции.
Формат: `[ "slug", limit, "sort", "view_mode" ]`
Параметры:
1. `slug` (str): Уникальный слаг TbMusicStyle, TbArticle (Категория/Тег) или идентификатор формата (например, cassettes-studio, cassettes-used-blank).
2. `limit` (int): Количество выводимых товаров (например, 5, 20). Фолбэк при ошибке: 10.
3. `sort` (str): Правило сортировки:
- `views` → -i_offer_views (самые просматриваемые)
- `favorites` → -i_offer_favorites (самые популярные / в избранном)
- `newest` → -t_offer_created (новинки)
- `price_asc` → f_offer_price (сначала дешевые)
- `price_desc` → -f_offer_price (сначала дорогие)
4. `view_mode` (str): Компонент рендеринга (шаблон):
- `carousel` → Горизонтальная карусель / слайдер.
- `grid` → Стандартная сетка карточек.
- `list` → Компактный вертикальный список.
Пример: ["cassettes-studio", 5, "views", "carousel"]
Замечания: `view_mode` -- это название зарегистрированного шаблона в системе. Если передан неизвестный `view_mode` или он отсутствует, используется дефолтный `list`.
### Тип B: Баннер / Вложенная статья / Вложенный хаб (Длина = 2)
Встраивает существующую статью, рекламный баннер или массив вложенного хаба.
Формат: [ "slug", "view_mode" ]
Параметры:
1. `slug` (str): Слаг целевой TbArticle.
2. `view_mode` (str): Режим отображения:
- `slider` / `hero` → Главный баннер / промо-слайдер.
- `teaser` → Тизер статьи с кнопкой «Читать далее».
- `full` → Полный HTML-контент статьи, встроенный inline.
Пример: ["hero-banner-cassettes", "slider"]
### Тип C: Динамический модуль / Плагин (Длина = 1)
Запускает кастомный Python-модуль, зарегистрированный в системе (например, расчет скидок, интерактивные виджеты, реклама).
Формат: [ "module-slug" ]
Параметры:
1. `slug` (str): Уникальный идентификатор, зарегистрированный в PluginRegistry (например, module-promo-mandarin, module-ad-banner-1).
Пример: ["module-promo-mandarin"]
## 4. Полный пример конфига (j_article_metadata)
{
"hub": [
["hero-cassettes-2026", "slider"],
["cassettes-studio", 6, "views", "carousel"],
["cassettes-studio", 20, "newest", "grid"],
["module-mandarin-promo"],
["cassettes-maxell-used-ud2-c90-ver2", 6, "popular", "carousel"],
["cassettes-tdk-ned-cding2-c60", 20, "price_desc", "list"],
["guide-how-to-clean-heads", "teaser"]
]
}
## 5. Защита и логика бэкенда (Требования к Python / Django)
При разработке парсера DSL:
1. Защита от зацикливания и бесконечной рекурсии:
- Передавать множество `visited_slugs` при рендере страницы.
- Если вложенный блок пытается загрузить `slug`, который уже есть в `visited_slugs`, пропускать блок или выводить отладочный HTML-комментарий (`<!-- DSL Error: Circular reference detected for slug -->`).
2. Ограничение глубины вложенности:
- Жестко ограничить максимальную глубину рекурсии: `MAX_RECURSION_DEPTH = 2` (устанавливается в `settings.py`).
3. Отказоустойчивость (Graceful Degradation):
- Если limit передан не числом или sort содержит неизвестную строку, парсер должен тихо применить безопасные дефолты (`limit=10`, `sort='newest'`, `view_mode='grid'`). Ошибка синтаксиса в JSON никогда не должна приводить к `500 Server Error`.
- Если `slug` не найден в базе, блок пропускается, а в HTML выводится комментарий: `<!-- DSL Error: Slug not found -->`.
4. Изоляция данных:
- Внутри DSL запрещено использовать сырые имена полей БД (например, k_offer_to_item__s_item). Все выборки данных маппятся строго через `slug` и внутренние обработчики запросов (Query Handlers).
- Все ключи из json['hub'] должны быть объявлены заранее.
5. Валидация slug
- Нужно добавить в валидатор админки статей (TbArticle) проверку на "не совпадение" slug с существующими роутами сайта из `'urls.py'` (чтобы не было конфликта URL-ов).