projects/org/ideal-shop/V2-drupal11-bootstrap/STEP_BY_STEP.md

Пошаговый план с чекпоинтами

Версия: 2.0.0
Дата: 2026-01-07


Обзор

Этап → Действие → Тест → Чекпоинт → Следующий этап

4 чекпоинта готовности:
1. Базовая тема (Lite)
2. Commerce (Shop)
3. Advanced Features (Advanced)
4. Production Ready (Max)


ЧЕКПОИНТ 1: Базовая тема

Цель

Создать минимальную рабочую тему Drupal.

Результат: Главная страница рендерится, CSS/JS работают


Шаг 1.1: Инициализация

Действие

# 1. Создать проект (Drupal CMS — не vanilla Drupal, содержит SEO/media рецепты)
composer create-project drupal/cms ideal-shop
cd ideal-shop

# 2. Установить Drupal
vendor/bin/drush site:install standard \
  --db-url=sqlite://db.sqlite \
  --site-name="Ideal Shop" \
  --account-pass=admin \
  -y

Тест

# Проверка установки
vendor/bin/drush status | grep "Database"
# Ожидаемый вывод: Database: Connected

# Проверка доступности
vendor/bin/drush runserver 127.0.0.1:8080 &
sleep 3
curl -f http://127.0.0.1:8080/
# Ожидаемый код: 200

Критерии


Шаг 1.2: Создать структуру темы

Действие

mkdir -p web/themes/custom/ideal_theme
cd web/themes/custom/ideal_theme

# Создать структуру
mkdir -p {components,templates,css,js,translations,images,pwa}

Файлы

ideal_theme.info.yml:

name: Ideal Theme
type: theme
description: 'Дочерняя тема Bootstrap Barrio для e-commerce магазина'
package: Custom
core_version_requirement: ^11
base theme: bootstrap_barrio

libraries:
  - ideal_theme/global-styling

regions:
  header_top: 'Header Top'
  header: Header
  primary_menu: 'Primary menu'
  content: Content
  sidebar_first: 'Left sidebar'
  footer_first: 'Footer column 1'
  footer_second: 'Footer column 2'
  footer_bottom: 'Footer bottom'

⚠️ Регионы должны совпадать с регионами Bootstrap Barrio или расширять их.
Bootstrap Barrio уже предоставляет Bootstrap 5 CSS/JS — не нужно подключать вручную.

ideal_theme.libraries.yml:

global-styling:
  css:
    theme:
      css/tokens.css: {}
      css/global.css: {}
  js:
    js/cart-ajax.js: {}
  dependencies:
    - core/drupal
    - core/once

css/tokens.css (дизайн-токены из THEME-SPEC):

:root {
  /* Цвета */
  --color-primary:    #1a4f8a;
  --color-primary-h:  #1a6abf;
  --color-accent:     #e63946;
  --color-success:    #28a745;
  --color-text:       #222222;
  --color-muted:      #6c757d;
  --color-bg:         #ffffff;
  --color-bg-light:   #f8f9fa;
  --color-border:     #dee2e6;

  /* Типографика */
  --font-base:    'Inter', -apple-system, sans-serif;
  --font-size-sm: 0.875rem;
  --font-size-md: 1rem;
  --font-size-lg: 1.125rem;

  /* Скругления */
  --radius-sm:  4px;
  --radius-md:  8px;
  --radius-lg:  12px;

  /* Тени */
  --shadow-card:  0 2px 8px rgba(0,0,0,0.08);
  --shadow-hover: 0 4px 16px rgba(0,0,0,0.14);
}

js/main.js:

(function (Drupal) {
  'use strict';

  Drupal.behaviors.idealTheme = {
    attach: function (context, settings) {
      console.log('Ideal Theme loaded');
    }
  };
})(Drupal);

Тест

# Проверка структуры
ls -la web/themes/custom/ideal_theme/
# Должны быть: ideal_theme.info.yml, css/, js/

# Проверка YAML синтаксиса
yamllint ideal_theme.info.yml
yamllint ideal_theme.libraries.yml

Критерии


Шаг 1.3: Включить тему

Действие

cd /path/to/ideal-shop

# Включить тему
vendor/bin/drush theme:install ideal_theme -y
vendor/bin/drush config:set system.theme default ideal_theme -y
vendor/bin/drush cr

Тест

# Проверка активации
vendor/bin/drush theme:list | grep ideal_theme
# Ожидаемый вывод: ideal_theme (default theme)

# Тест страницы
curl -s http://127.0.0.1:8080/ | grep "Ideal Theme loaded"
# Должен найти JS код

# Проверка CSS
curl -s http://127.0.0.1:8080/themes/custom/ideal_theme/css/base.css
# HTTP 200

Критерии


Шаг 1.4: Создать шаблоны

Действие

templates/layout/page.html.twig:

<div class="page-wrapper">
  <header class="header">
    <div class="container">
      {{ page.header }}
    </div>
  </header>

  <main class="main">
    <div class="container">
      {{ page.content }}
    </div>
  </main>

  <footer class="footer">
    <div class="container">
      {{ page.footer }}
    </div>
  </footer>
</div>

Тест

# Очистить кэш
vendor/bin/drush cr

# Проверка структуры HTML
curl -s http://127.0.0.1:8080/ | grep '<div class="page-wrapper">'
curl -s http://127.0.0.1:8080/ | grep '<header class="header">'
curl -s http://127.0.0.1:8080/ | grep '<footer class="footer">'

# Все должны найтись

Критерии


✅ ЧЕКПОИНТ 1: ГОТОВО

Проверка готовности

Автоматический тест:

#!/bin/bash
# tests/checkpoint-1.sh

echo "🧪 Testing Checkpoint 1: Base Theme"

# 1. Тема включена
drush theme:list | grep "ideal_theme (default theme)" || exit 1

# 2. Главная страница
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/)
[ "$HTTP" = "200" ] || exit 1

# 3. CSS загружается
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/themes/custom/ideal_theme/css/base.css)
[ "$HTTP" = "200" ] || exit 1

# 4. JS работает
curl -s http://127.0.0.1:8080/ | grep "Ideal Theme loaded" || exit 1

# 5. HTML структура
curl -s http://127.0.0.1:8080/ | grep '<div class="page-wrapper">' || exit 1

echo "✅ Checkpoint 1 PASSED"

Стратегия тестирования

Метрики

Следующий шаг

Чекпоинт 2: Commerce


ЧЕКПОИНТ 2: Commerce

Цель

Добавить e-commerce функционал.

Результат: Каталог товаров, страница товара, корзина, checkout работают


Шаг 2.1: Установить Commerce

Действие

# Установить модули
composer require drupal/commerce

# Применить рецепт
vendor/bin/drush recipe recipes/ideal_shop_core

recipes/ideal_shop_core/recipe.yml:

name: 'Ideal Shop - Core Commerce'
description: 'Commerce + Store + Product type + Checkout flow'
type: 'Site'

install:
  - commerce
  - commerce_product
  - commerce_cart
  - commerce_checkout
  - commerce_order
  - commerce_payment
  - commerce_price
  - commerce_store

config:
  actions:
    commerce.settings:
      simple:
        default_country: 'RU'

Тест

# Проверка модулей
vendor/bin/drush pm:list | grep commerce_product
vendor/bin/drush pm:list | grep commerce_cart
vendor/bin/drush pm:list | grep commerce_checkout

# Все должны быть Enabled

Критерии


Шаг 2.2: Создать Product Type

Действие

# Создать product type через Drush
vendor/bin/drush commerce:create-product-type \
  --label="Product" \
  --id="product" \
  --variation-type="default"

Тест

# Проверка
vendor/bin/drush entity:list commerce_product_type
# Должен быть: product

# Создать тестовый товар
vendor/bin/drush commerce:create-product \
  --type="product" \
  --title="Test Product" \
  --sku="TEST-001" \
  --price="100.00"

# Проверить что создался
vendor/bin/drush entity:list commerce_product

Критерии


Шаг 2.3: Создать шаблоны Commerce

Действие

templates/commerce/commerce-product--full.html.twig:

<article class="product">
  <h1 class="product-title">{{ product_entity.label }}</h1>

  <div class="product-price">
    {{ content.variations }}
  </div>

  <div class="product-description">
    {{ content.body }}
  </div>

  <div class="product-add-to-cart">
    {{ content.variations[0].add_to_cart }}
  </div>
</article>

templates/commerce-cart/cart-block.html.twig:

<div class="cart-block">
  {% if content.items %}
    <div class="cart-items">
      {{ content.items }}
    </div>
    <div class="cart-total">
      {{ content.total }}
    </div>
    <a href="/cart" class="cart-link">View Cart</a>
  {% else %}
    <p>Cart is empty</p>
  {% endif %}
</div>

Тест

# Очистить кэш
vendor/bin/drush cr

# Проверка товара
curl -s http://127.0.0.1:8080/product/1 | grep '<article class="product">'

# Проверка корзины
curl -s http://127.0.0.1:8080/cart | grep '<div class="cart-block">'

Критерии


Шаг 2.4: Создать каталог

Действие

# Применить рецепт каталога
vendor/bin/drush recipe recipes/ideal_shop_catalog

recipes/ideal_shop_catalog/recipe.yml:

name: 'Ideal Shop - Catalog'
description: 'Категории + Views каталога + Facets + Search API'
type: 'Site'

install:
  - views
  - views_ui

config:
  import:
    catalog:
      - views.view.products

recipes/ideal_theme_catalog/config/views.view.products.yml:

id: products
label: 'Products Catalog'
module: views
display:
  default:
    display_plugin: default
    display_title: Default
  page_1:
    display_plugin: page
    display_title: Page
    path: catalog

Тест

# Проверка View
vendor/bin/drush views:list | grep products

# Проверка страницы
curl -f http://127.0.0.1:8080/catalog
# HTTP 200

Критерии


✅ ЧЕКПОИНТ 2: ГОТОВО

Проверка готовности

Автоматический тест:

#!/bin/bash
# tests/checkpoint-2.sh

echo "🧪 Testing Checkpoint 2: Commerce"

# 1. Commerce модули
drush pm:list | grep "commerce_product.*Enabled" || exit 1

# 2. Product type
drush entity:list commerce_product_type | grep "product" || exit 1

# 3. Каталог
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/catalog)
[ "$HTTP" = "200" ] || exit 1

# 4. Товар
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/product/1)
[ "$HTTP" = "200" ] || exit 1

# 5. Корзина
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/cart)
[ "$HTTP" = "200" ] || exit 1

# 6. Checkout
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/checkout)
[ "$HTTP" = "302" ] || [ "$HTTP" = "200" ] || exit 1

echo "✅ Checkpoint 2 PASSED"

User Flow тест

// tests/e2e/buy-product.spec.ts
import { test, expect } from '@playwright/test';

test('User can buy a product', async ({ page }) => {
  // 1. Открыть каталог
  await page.goto('/catalog');
  await expect(page).toHaveTitle(/Catalog/);

  // 2. Открыть товар
  await page.click('.product-card:first-child a');
  await expect(page).toHaveURL(/\/product\/\d+/);

  // 3. Добавить в корзину
  await page.click('button:has-text("Add to cart")');
  await expect(page.locator('.cart-block')).toContainText('1 item');

  // 4. Перейти в корзину
  await page.click('a:has-text("View Cart")');
  await expect(page).toHaveURL('/cart');

  // 5. Checkout
  await page.click('a:has-text("Checkout")');
  await expect(page).toHaveURL(/\/checkout/);
});

Стратегия тестирования

Метрики

Следующий шаг

Чекпоинт 3: Advanced Features


ЧЕКПОИНТ 3: Advanced Features

Цель

Добавить продвинутые функции.

Результат: Фильтры, поиск, отзывы, wishlist, промокоды работают


ℹ️ Search API + Facets уже включены в ideal_shop_catalog (Чекпоинт 2).
SEO (Pathauto, Metatag, Sitemap) входит в Drupal CMS по умолчанию.
Здесь добавляем: отзывы, избранное, промокоды.


Шаг 3.1: Отзывы (Fivestar)

Действие

composer require drupal/fivestar
vendor/bin/drush recipe recipes/ideal_shop_reviews

Тест

vendor/bin/drush pm:list | grep fivestar
# Ожидаемый вывод: fivestar  Enabled

# Проверить поле на product type
vendor/bin/drush field:info commerce_product default
# Должно быть поле field_rating

Критерии


Шаг 3.2: Wishlist (Избранное)

Действие

composer require drupal/commerce_wishlist
vendor/bin/drush recipe recipes/ideal_shop_wishlist

Тест

vendor/bin/drush pm:list | grep commerce_wishlist
# Ожидаемый вывод: commerce_wishlist  Enabled

# Проверить роут wishlist
vendor/bin/drush router:debug | grep wishlist
# Должен быть маршрут /wishlist

Критерии


Шаг 3.3: Промокоды

Действие

# commerce_promotion входит в drupal/commerce
vendor/bin/drush recipe recipes/ideal_shop_promo

Тест

vendor/bin/drush pm:list | grep commerce_promotion
# Ожидаемый вывод: commerce_promotion  Enabled

# Создать тестовый промокод
vendor/bin/drush php-eval "
  \$promotion = \Drupal\commerce_promotion\Entity\Coupon::create([
    'code' => 'TEST10',
    'promotion_id' => 1,
  ]);
  \$promotion->save();
  echo 'Coupon created';
"

Критерии


✅ ЧЕКПОИНТ 3: ГОТОВО

Автоматический тест

#!/bin/bash
# tests/checkpoint-3.sh

echo "🧪 Testing Checkpoint 3: Advanced Features"

# 1. Fivestar
drush pm:list | grep "fivestar.*Enabled" || exit 1

# 2. Wishlist
drush pm:list | grep "commerce_wishlist.*Enabled" || exit 1

# 3. Wishlist page
HTTP=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080/wishlist)
[ "$HTTP" = "200" ] || [ "$HTTP" = "403" ] || exit 1

# 4. Promotions enabled
drush pm:list | grep "commerce_promotion.*Enabled" || exit 1

# 5. Промокод в checkout flow
drush php-eval "echo \Drupal::service('plugin.manager.commerce_checkout_pane')->hasDefinition('coupon_redemption') ? 'yes' : 'no';" | grep "yes" || exit 1

echo "✅ Checkpoint 3 PASSED"

Метрики


ЧЕКПОИНТ 4: Production Ready

Цель

Подготовить тему к production.

Результат: Все тесты проходят, документация готова


Шаг 4.1: Lighthouse аудит

# Запустить сервер
vendor/bin/drush runserver 127.0.0.1:8080 &

# Lighthouse (нужен Node.js + lighthouse пакет)
npx lighthouse http://127.0.0.1:8080/ \
  --only-categories=performance,accessibility,best-practices,seo \
  --output=json --output-path=./lighthouse-report.json

Тест

# Проверить Lighthouse scores из JSON
node -e "
  const r = require('./lighthouse-report.json');
  const scores = r.categories;
  const perf = Math.round(scores.performance.score * 100);
  const a11y = Math.round(scores.accessibility.score * 100);
  console.log('Performance:', perf, perf >= 85 ? '✅' : '❌');
  console.log('Accessibility:', a11y, a11y >= 90 ? '✅' : '❌');
"

Шаг 4.2: Все 4 стратегии тестирования

Development (linting)

# PHP syntax check (нет npm build — Bootstrap Barrio подключает Bootstrap сам)
find web/themes/custom/ideal_theme -name "*.php" -o -name "*.theme" | \
  xargs -I{} php -l {}
# Все файлы: No syntax errors

# YAML валидация
find web/themes/custom/ideal_theme -name "*.yml" | \
  xargs -I{} php -r "yaml_parse(file_get_contents('{}'));"

Integration

./scripts/test-install.sh
# Успешно

Deployment

./tests/test-deployment.sh
# Все варианты (Lite/Shop/Max) работают

Configuration

./tests/test-matrix.sh
# Критические комбинации проходят

✅ ЧЕКПОИНТ 4: PRODUCTION READY

Финальная проверка

Чеклист:

Метрики


🎉 РЕЛИЗ

Готово к production!

Следующие шаги:
1. Создать git tag
2. Опубликовать на Drupal.org
3. Создать демо-сайт
4. Написать статью


Версия: 2.1.0
Дата: 2026-03-24