projects/org/@biz-lideravto/it/docs/arh/IMPORT_ARCHITECTURE.md

Архитектура системы импорта

Проект: lideravto-new
Дата: 2026-02-12
Версия: 1.0


ОБЩАЯ СХЕМА

CSV (BAZON)
    ↓
┌───────────────────────────────────────────────────────────┐
│ ВХОДНОЙ СЛОЙ (Input Layer)                               │
│ lider_importer - парсинг CSV, валидация                  │
└───────────────────────────────────────────────────────────┘
    ↓
┌───────────────────────────────────────────────────────────┐
│ СЛОЙ ДАННЫХ (Data Layer)                                 │
│ lider_models - справочник моделей                         │
│ lider_parts - словарь деталей                             │
└───────────────────────────────────────────────────────────┘
    ↓
┌───────────────────────────────────────────────────────────┐
│ ЛОГИЧЕСКИЙ СЛОЙ (Business Logic Layer)                   │
│ lider_compatibility - определение совместимости           │
│ lider_products - создание/обновление товаров              │
└───────────────────────────────────────────────────────────┘
    ↓
┌───────────────────────────────────────────────────────────┐
│ СЛОЙ ОТОБРАЖЕНИЯ (Presentation Layer)                    │
│ lider_catalog - каталог, фильтры, категории              │
│ lider_seo - SEO, canonical, мета-теги                    │
└───────────────────────────────────────────────────────────┘
    ↓
Commerce Products + Variations (Drupal)

МОДУЛИ (7 модулей)

1. lider_setup (Foundation)

Назначение: Начальная настройка сайта

Что делает:
- Создаёт таксономии (brands, conditions, aggregates, nodes)
- Создаёт термины (7 брендов, 3 состояния, 5 агрегатов, 6 узлов)
- Создаёт поля на Commerce Product (field_oem, field_cross, field_compatibility...)
- Включает необходимые модули (pathauto, metatag, search_api, facets)

Статус: ✅ Создан и установлен

Файлы:
- lider_setup.info.yml
- lider_setup.install

Запускается: Один раз при установке


2. lider_models (Reference Data)

Назначение: Управление справочником моделей грузовиков

Что делает:
- Синхронизирует данные из NocoDB таблицы lideravto_models
- Создаёт/обновляет таксономию models в Drupal
- Каждый термин = модель грузовика (Volvo FH4, MAN TGX E6...)
- Хранит метаданные: platform, cabin, generation, engines

Структура термина models:

Term: Volvo FH4
├─ field_brand: Volvo
├─ field_code: 4-FH
├─ field_platform: euro6
├─ field_cabin: FH
├─ field_generation: 4
├─ field_engines: D13K, D16K
├─ field_years: 2012+
└─ field_description: Магистральный тягач поколение 4

API:

// Получить модель по коду
$model = \Drupal::service('lider_models.repository')
  ->getModelByCode('4-FH', 'Volvo');

// Получить все модели платформы
$models = \Drupal::service('lider_models.repository')
  ->getModelsByPlatform('euro6', 'Volvo');

// Синхронизация с NocoDB
drush lider:sync-models

Файлы:
- lider_models.info.yml
- src/ModelsRepository.php
- src/ModelsSync.php (синхронизация с NocoDB)
- src/Commands/SyncModelsCommand.php (Drush команда)

Зависимости: taxonomy


3. lider_parts (Reference Data)

Назначение: Управление словарём деталей

Что делает:
- Синхронизирует данные из NocoDB таблицы lideravto_parts
- Определяет к какому узлу/агрегату относится деталь
- Возвращает тип совместимости (PLATFORM/MODEL/ENGINE/GENERATION/UNIVERSAL)

API:

// Определить тип детали
$partInfo = \Drupal::service('lider_parts.classifier')
  ->classify('Амортизатор передний');

// Результат:
// [
//   'node' => 'Подвеска',
//   'aggregate' => 'Шасси',
//   'compatibility_type' => 'PLATFORM'
// ]

// Синхронизация с NocoDB
drush lider:sync-parts

Файлы:
- lider_parts.info.yml
- src/PartsClassifier.php
- src/PartsSync.php
- src/Commands/SyncPartsCommand.php

Зависимости: -


4. lider_compatibility (Business Logic)

Назначение: Определение совместимости деталей с моделями

Что делает:
- Принимает: название детали, код модели, марку
- Определяет тип совместимости через lider_parts
- Применяет правило (PLATFORM → вся платформа, MODEL → только своя модель и т.д.)
- Возвращает список совместимых моделей

API:

$compatible = \Drupal::service('lider_compatibility.engine')
  ->expand('Амортизатор передний', '4-FH', 'Volvo');

// Результат: ['4-FH', '4-FM', '4-FMX']

Алгоритм:

function expand($partName, $modelCode, $brand) {
  // 1. Определить тип совместимости
  $partInfo = lider_parts::classify($partName);
  $compatType = $partInfo['compatibility_type'];

  // 2. Получить информацию об исходной модели
  $sourceModel = lider_models::getModelByCode($modelCode, $brand);

  // 3. Применить правило
  switch ($compatType) {
    case 'PLATFORM':
      return lider_models::getModelsByPlatform(
        $sourceModel->platform, $brand
      );

    case 'MODEL':
      return [$modelCode];

    case 'ENGINE':
      $engineCode = extractEngineCode($partName);
      return lider_models::getModelsByEngine($engineCode, $brand);

    case 'GENERATION':
      return lider_models::getModelsByGeneration(
        $sourceModel->generation, $brand
      );

    case 'UNIVERSAL':
      return lider_models::getAllModels($brand);
  }
}

Файлы:
- lider_compatibility.info.yml
- src/CompatibilityEngine.php
- src/EngineExtractor.php (извлечение кода двигателя из названия)

Зависимости: lider_models, lider_parts


5. lider_products (Business Logic)

Назначение: Создание/обновление товаров (OEM страниц)

Что делает:
- Создаёт Commerce Product по OEM номеру (если не существует)
- Добавляет совместимые модели (через lider_compatibility)
- Создаёт Commerce Product Variation (SKU) для каждого экземпляра детали
- Обрабатывает кросс-номера (аналоги)

Логика работы:

Входящая строка CSV:
┌─────────────────────────────────────┐
 Артикул: BAZON-123                  
 Название: Амортизатор передний      
 Марка: Volvo                        
 Модель: 4-FH                        
 OEM: 20499340                       
 Цена: 5200                          
 Остаток: 2                          
 Склад: СПб                          
└─────────────────────────────────────┘
    
ПРОВЕРКА: Существует ли Product с OEM=20499340?
    
    ├─ НЕТ  СОЗДАТЬ Product
       ├─ Определить совместимость
          ├─ lider_parts::classify("Амортизатор")  PLATFORM
          └─ lider_compatibility::expand("Амортизатор", "4-FH", "Volvo")
               [4-FH, 4-FM, 4-FMX]
       
       └─ Создать Commerce Product:
           ├─ title: "Амортизатор передний Volvo OEM 20499340"
           ├─ field_oem: 20499340
           ├─ field_compatibility: [tid:FH4, tid:FM4, tid:FMX4]
           ├─ field_aggregate: tid:Шасси
           └─ field_node: tid:Подвеска
    
    └─ ДА  ОБНОВИТЬ Product
        └─ Добавить модели если новые (расширение совместимости)

СОЗДАТЬ SKU (Commerce Product Variation):
    ├─ SKU: BAZON-123
    ├─ Price: 5200
    ├─ field_warehouse: СПб
    ├─ field_stock: 2
    └─ product_id:  Commerce Product (OEM 20499340)

API:

// Создать/обновить товар из CSV строки
$product = \Drupal::service('lider_products.manager')
  ->processRow($csvRow);

// Найти или создать Product по OEM
$product = \Drupal::service('lider_products.repository')
  ->findOrCreateByOem('20499340');

// Добавить SKU вариацию
$variation = \Drupal::service('lider_products.manager')
  ->addVariation($product, [
    'sku' => 'BAZON-123',
    'price' => 5200,
    'warehouse' => 'СПб',
    'stock' => 2
  ]);

Файлы:
- lider_products.info.yml
- src/ProductsManager.php (создание/обновление)
- src/ProductsRepository.php (поиск товаров)
- src/VariationBuilder.php (создание SKU)
- src/CrossReferenceManager.php (аналоги по OEM)

Зависимости: commerce_product, lider_compatibility


6. lider_importer (Input Layer)

Назначение: Импорт CSV файлов от поставщиков

Что делает:
- Читает CSV файл
- Валидирует данные (обязательные поля, форматы)
- Парсит строки в массивы
- Вызывает lider_products::processRow() для каждой строки
- Логирует результаты импорта

Процесс импорта:

1. ЗАГРУЗКА CSV
   ├─ Через админ-интерфейс (/admin/lider/import)
   ├─ Через Drush: drush lider:import bazon.csv
   └─ Через cron (автоматически из /mnt/beget-s3/lideravto/inbox/)

2. ВАЛИДАЦИЯ
   ├─ Проверка обязательных полей (Артикул, OEM, Марка, Модель)
   ├─ Проверка формата цены (число > 0)
   └─ Проверка марки (в списке поддерживаемых)

3. ПАРСИНГ
   ├─ Очистка данных (trim, приведение к нужному регистру)
   ├─ Нормализация (кодировка UTF-8)
   └─ Расшифровка модели ("4-FH"  "Volvo FH4")

4. ОБРАБОТКА
   ├─ Для каждой строки вызвать lider_products::processRow()
   ├─ Обработать ошибки
   └─ Логировать результат

5. ОТЧЁТ
   ├─ Обработано строк: 13000
   ├─ Создано товаров: 4626
   ├─ Обновлено товаров: 1234
   ├─ Создано SKU: 13000
   ├─ Ошибок: 15
   └─ Время: 3м 42с

UI (админка):

/admin/lider/import
┌────────────────────────────────────────────────┐
 Импорт CSV                                     
├────────────────────────────────────────────────┤
                                                
 Файл: [Выбрать файл] bazon.csv               
                                                
 Поставщик: [v BAZON                  ]        
                                                
 Формат: [v BAZON (стандартный)       ]        
                                                
 Режим:                                         
   ( ) Тест (без сохранения)                   
   () Импорт (создать/обновить)               
   ( ) Только новые (не обновлять)             
                                                
 [Импортировать]                                
                                                
└────────────────────────────────────────────────┘

Файлы:
- lider_importer.info.yml
- src/Form/ImportForm.php (админ-форма)
- src/CsvParser.php (парсинг CSV)
- src/CsvValidator.php (валидация)
- src/ImportProcessor.php (обработка)
- src/ImportLogger.php (логирование)
- src/Commands/ImportCommand.php (Drush)

Зависимости: lider_products


7. lider_catalog (Presentation Layer)

Назначение: Отображение каталога товаров

Что делает:
- Views для списков товаров
- Фильтры (по марке, модели, узлу, состоянию, цене)
- Категории (динамические через Views)
- Блоки (популярные, новинки, акции)

Структура URL:

/catalog                       → Весь каталог
/catalog/volvo                 → Все детали Volvo
/catalog/volvo/fh4             → Все детали для Volvo FH4
/catalog/volvo/fh4/podveska    → Подвеска для Volvo FH4
/catalog/volvo/fh4/podveska/amortizatory → Амортизаторы для Volvo FH4

/product/20499340              → Страница товара (OEM)

Views:

  1. catalog_products (основной список)
    - Display: Page, Block
    - Фильтры: brand, model, node, aggregate, condition, price
    - Сортировка: price, title, created
    - Пагинация: 24 на странице

  2. catalog_by_model (детали для модели)
    - Контекстный фильтр: model (taxonomy term)
    - Группировка: по узлу (Подвеска, Тормоза...)

  3. catalog_by_node (детали узла)
    - Контекстный фильтр: node (taxonomy term)

Блоки:

  1. Фильтры каталога
    - Facets API
    - Марка, Модель, Узел, Цена, Состояние

  2. Популярные товары
    - Сортировка по просмотрам

  3. Новинки
    - Сортировка по created (последние 30 дней)

Файлы:
- lider_catalog.info.yml
- config/install/views.view.catalog_products.yml
- config/install/views.view.catalog_by_model.yml
- config/install/facets.facet.brand.yml
- templates/product-catalog.html.twig

Зависимости: views, facets, commerce_product


8. lider_seo (Presentation Layer)

Назначение: SEO оптимизация

Что делает:
- Автоматические мета-теги
- Canonical URL (несколько моделей → одна страница)
- XML sitemap
- Structured data (Schema.org Product)
- ЧПУ (pathauto паттерны)

Canonical логика:

Товар: Амортизатор OEM 20499340
Совместим с: FH4, FM4, FMX4

Страницы категорий:
├─ /catalog/volvo/fh4/podveska    показан амортизатор
├─ /catalog/volvo/fm4/podveska    показан ТОТ ЖЕ амортизатор
└─ /catalog/volvo/fmx4/podveska   показан ТОТ ЖЕ амортизатор

Canonical URL (на всех трёх):
<link rel="canonical" href="/product/20499340">

Schema.org markup:

{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Амортизатор передний Volvo OEM 20499340",
  "sku": "20499340",
  "brand": {
    "@type": "Brand",
    "name": "Volvo"
  },
  "offers": {
    "@type": "AggregateOffer",
    "priceCurrency": "RUB",
    "lowPrice": "5000",
    "highPrice": "5200",
    "offerCount": "2",
    "availability": "https://schema.org/InStock"
  },
  "isVariantOf": {
    "@type": "ProductModel",
    "name": "Амортизатор передний"
  }
}

Файлы:
- lider_seo.info.yml
- src/MetaTagGenerator.php
- src/CanonicalUrlBuilder.php
- src/SchemaOrgBuilder.php
- config/install/pathauto.pattern.product.yml

Зависимости: metatag, pathauto, simple_sitemap


ПОРЯДОК РАЗРАБОТКИ

Фаза 1: Foundation (1 день)

Фаза 2: Business Logic (2 дня)

Фаза 3: Import (1 день)

Фаза 4: Presentation (1 день)

Фаза 5: Testing & Launch (1 день)

Итого: ~6 дней (48 часов работы)


ЗАВИСИМОСТИ МОДУЛЕЙ

lider_setup (base)
    ↓
    ├─→ lider_models
    └─→ lider_parts
            ↓
        lider_compatibility
            ↓
        lider_products
            ↓
        lider_importer
            ↓
    ├─→ lider_catalog
    └─→ lider_seo

Правило: Модуль может зависеть только от модулей выше по иерархии


ТОЧКИ РАСШИРЕНИЯ

1. Поставщики

Сейчас: BAZON
Добавить: Другие поставщики

Как:
- Создать lider_importer/src/Supplier/BazonParser.php
- Создать lider_importer/src/Supplier/OtherParser.php
- Интерфейс SupplierParserInterface

2. Кросс-номера (аналоги)

Сейчас: Не реализовано
Добавить: Поиск по аналогам OEM

Как:
- Таблица lider_cross_reference (oem_original → oem_analog)
- API: lider_products::findAnalogs($oem)

3. Автообновление цен

Сейчас: Ручной импорт
Добавить: Cron автоимпорт

Как:
- Hook_cron в lider_importer
- Автоскачивание CSV из S3
- Email отчёты

4. API для мобильного приложения

Сейчас: Только веб
Добавить: REST API

Как:
- Модуль lider_api
- REST Resource для Products
- JSON:API для каталога


ТЕСТИРОВАНИЕ

Unit тесты

// lider_compatibility
CompatibilityEngineTest::testPlatformType()
CompatibilityEngineTest::testModelType()
CompatibilityEngineTest::testEngineType()

// lider_products
ProductsManagerTest::testCreateProduct()
ProductsManagerTest::testAddVariation()
ProductsManagerTest::testFindByOem()

// lider_importer
CsvParserTest::testParse()
CsvValidatorTest::testValidate()

E2E тесты

1. Импорт CSV (10 строк)
   ├─ Проверить создано 10 Products
   ├─ Проверить создано 10 Variations
   └─ Проверить совместимость заполнена

2. Отображение каталога
   ├─ Открыть /catalog/volvo/fh4
   ├─ Проверить показаны нужные товары
   └─ Проверить фильтры работают

3. SEO
   ├─ Проверить canonical на странице товара
   ├─ Проверить schema.org markup
   └─ Проверить мета-теги

ПРОИЗВОДИТЕЛЬНОСТЬ

Импорт 13000 строк

Ожидаемое время: 3-5 минут

Оптимизации:
- Batch API (по 100 строк)
- EntityQuery вместо загрузки всех сущностей
- Кеширование справочников (models, parts)
- Отложенная индексация Search API

Мониторинг:

// Логирование
$logger->info('Обработано: @count/@total', [
  '@count' => $processed,
  '@total' => $total
]);

// Progress bar (Drush)
$progress = $this->io()->createProgressBar($total);
$progress->advance();

ФАЙЛОВАЯ СТРУКТУРА

modules/custom/
├── lider_setup/
│   ├── lider_setup.info.yml
│   └── lider_setup.install
│
├── lider_models/
│   ├── lider_models.info.yml
│   ├── src/
│   │   ├── ModelsRepository.php
│   │   ├── ModelsSync.php
│   │   └── Commands/SyncModelsCommand.php
│   └── config/install/
│       └── taxonomy.vocabulary.models.yml
│
├── lider_parts/
│   ├── lider_parts.info.yml
│   └── src/
│       ├── PartsClassifier.php
│       └── PartsSync.php
│
├── lider_compatibility/
│   ├── lider_compatibility.info.yml
│   └── src/
│       ├── CompatibilityEngine.php
│       └── EngineExtractor.php
│
├── lider_products/
│   ├── lider_products.info.yml
│   └── src/
│       ├── ProductsManager.php
│       ├── ProductsRepository.php
│       ├── VariationBuilder.php
│       └── CrossReferenceManager.php
│
├── lider_importer/
│   ├── lider_importer.info.yml
│   ├── src/
│   │   ├── Form/ImportForm.php
│   │   ├── CsvParser.php
│   │   ├── CsvValidator.php
│   │   ├── ImportProcessor.php
│   │   └── Commands/ImportCommand.php
│   └── config/install/
│       └── lider_importer.settings.yml
│
├── lider_catalog/
│   ├── lider_catalog.info.yml
│   ├── config/install/
│   │   ├── views.view.catalog_products.yml
│   │   └── facets.facet.brand.yml
│   └── templates/
│       └── product-catalog.html.twig
│
└── lider_seo/
    ├── lider_seo.info.yml
    ├── src/
    │   ├── MetaTagGenerator.php
    │   ├── CanonicalUrlBuilder.php
    │   └── SchemaOrgBuilder.php
    └── config/install/
        └── pathauto.pattern.product.yml

DRUSH КОМАНДЫ

# Синхронизация справочников
drush lider:sync-models     # NocoDB → Drupal таксономия models
drush lider:sync-parts      # NocoDB → Drupal словарь деталей

# Импорт
drush lider:import bazon.csv           # Импорт CSV
drush lider:import bazon.csv --dry-run # Тест без сохранения

# Утилиты
drush lider:rebuild-compatibility      # Пересчитать совместимость всех товаров
drush lider:update-prices bazon.csv    # Обновить только цены
drush lider:clear-cache                # Очистить кеш справочников

КОНФИГУРАЦИЯ

lider_importer.settings.yml

suppliers:
  bazon:
    name: 'BAZON'
    csv_format:
      delimiter: ','
      encoding: 'UTF-8'
      columns:
        - 'Артикул'
        - 'Название'
        - 'Марка'
        - 'Модель'
        - 'OEM'
        - 'Цена'
        - 'Остаток'
        - 'Склад'
    mappings:
      sku: 'Артикул'
      title: 'Название'
      brand: 'Марка'
      model: 'Модель'
      oem: 'OEM'
      price: 'Цена'
      stock: 'Остаток'
      warehouse: 'Склад'

import:
  batch_size: 100
  timeout: 300
  log_level: 'info'

Версия: 1.0
Дата: 2026-02-12