Files
web_work/OLD_CODE/README.md
kirill.khorkov a7282f7363 Fix
2025-12-17 01:18:27 +03:00

34 KiB
Raw Blame History

AETERNA - Интернет-магазин мебели и интерьера

    ___    ________________  _   _____
   /   |  / ____/_  __/ __ \/ | / /   |
  / /| | / __/   / / / /_/ /  |/ / /| |
 / ___ |/ /___  / / / _, _/ /|  / ___ |
/_/  |_/_____/ /_/ /_/ |_/_/ |_/_/  |_|


Оглавление


Возможности

Для покупателей

  • Просмотр каталога товаров с фильтрацией по категориям, цене, цвету и материалу
  • Поиск товаров по названию
  • Детальная страница товара с характеристиками
  • Корзина покупок с возможностью изменения количества
  • Оформление заказа с выбором способа доставки и оплаты
  • Личный кабинет с историей заказов
  • Регистрация и авторизация

Для администраторов

  • Полное управление каталогом товаров (CRUD)
  • Управление категориями и подкатегориями
  • Просмотр и обработка заказов
  • Управление пользователями
  • Статистика продаж

Технологический стек

Компонент Технология
Backend PHP 7.4+
База данных PostgreSQL 12+
Стилизация LESS (компилируется в CSS)
JavaScript jQuery 3.6+
Иконки Font Awesome 5.15
ORM/DB PDO (PHP Data Objects)

Зависимости

  • PHP расширения: pdo, pdo_pgsql, mbstring, json
  • Браузерная компиляция LESS (less.js)

Структура проекта

cite_practica1/
├── admin/                    # Административная панель
│   └── index.php            # Главная страница админки
│
├── api/                      # API endpoints (дублируются в public/api/)
│   ├── auth.php             # Аутентификация пользователя
│   ├── add_to_cart.php      # Добавление товара в корзину
│   ├── cart.php             # Управление корзиной (add/update/remove/get/count)
│   ├── get_cart.php         # Получение содержимого корзины
│   ├── get_cart_count.php   # Количество товаров в корзине
│   ├── get_product.php      # Получение информации о товаре
│   ├── process_order.php    # Оформление заказа
│   ├── register_handler.php # Регистрация пользователя
│   └── update_cart.php      # Обновление количества в корзине
│
├── assets/                   # Статические ресурсы
│   ├── css/                 # Скомпилированные CSS файлы
│   ├── img/                 # Изображения товаров и интерфейса
│   ├── js/                  # JavaScript файлы
│   │   ├── checkout.js      # Логика оформления заказа
│   │   └── profile.js       # Логика профиля пользователя
│   └── less/                # LESS исходники стилей
│       ├── style.less       # Основные стили
│       ├── checkout.less    # Стили страницы оформления
│       └── mixins.less      # LESS миксины
│
├── config/                   # Конфигурация
│   ├── database.php         # Подключение к PostgreSQL
│   └── check_auth.js        # Клиентская проверка авторизации
│
├── includes/                 # Общие компоненты
│   ├── auth.php             # Функции авторизации
│   ├── footer.php           # Футер сайта
│   ├── functions.php        # Вспомогательные функции
│   └── header.php           # Шапка сайта
│
├── migrations/               # SQL миграции базы данных
│   ├── 001_initial_schema.sql        # Начальная схема (users, categories, products)
│   ├── 002_add_cart_orders.sql       # Корзина и заказы
│   ├── 003_add_product_fields.sql    # Дополнительные поля товаров
│   ├── 004_grant_admin_to_admin_mail.sql  # Права администратора
│   ├── grant_admin.php               # Скрипт назначения админа
│   ├── migrate.php                   # Раннер миграций
│   └── seed_data.sql                 # Тестовые данные
│
├── public/                   # Публичная директория (точка входа веб-сервера)
│   ├── index.php            # Главная страница
│   ├── catalog.php          # Каталог товаров
│   ├── product.php          # Страница товара
│   ├── checkout.php         # Оформление заказа / корзина
│   ├── login.php            # Страница входа
│   ├── logout.php           # Выход из аккаунта
│   ├── register.php         # Регистрация
│   ├── services.php         # Страница услуг
│   ├── delivery.php         # Доставка и оплата
│   ├── warranty.php         # Гарантия
│   ├── header_common.php    # Общий header
│   ├── footer.php           # Footer
│   ├── api/                 # API endpoints
│   ├── config/              # Конфигурация
│   ├── includes/            # Общие компоненты
│   ├── img/                 # Изображения
│   └── assets/              # Статические ресурсы
│
├── uploads/                  # Загруженные файлы
│   └── products/            # Изображения товаров
│
├── setup.sh                 # Скрипт первоначальной настройки
├── style_for_cite.less      # Основной файл стилей
└── README.md                # Этот файл

База данных

Схема базы данных

erDiagram
    users ||--o{ cart : has
    users ||--o{ orders : places
    categories ||--o{ products : contains
    categories ||--o{ subcategories : has
    products ||--o{ cart : added_to
    products ||--o{ order_items : included_in
    orders ||--|{ order_items : contains

    users {
        int user_id PK
        varchar email UK
        varchar password_hash
        varchar full_name
        varchar phone
        varchar city
        timestamp created_at
        timestamp updated_at
        timestamp last_login
        boolean is_active
        boolean is_admin
    }

    categories {
        int category_id PK
        varchar name
        varchar slug UK
        int parent_id FK
        text description
        int sort_order
        boolean is_active
        timestamp created_at
        timestamp updated_at
    }

    subcategories {
        int subcategory_id PK
        int category_id FK
        varchar name
        varchar slug UK
        text description
        int sort_order
        boolean is_active
        timestamp created_at
    }

    products {
        int product_id PK
        int category_id FK
        varchar name
        varchar slug UK
        text description
        decimal price
        decimal old_price
        varchar sku UK
        int stock_quantity
        boolean is_available
        boolean is_featured
        decimal rating
        int review_count
        varchar image_url
        varchar color
        varchar material
        varchar card_size
        timestamp created_at
        timestamp updated_at
    }

    cart {
        int cart_id PK
        int user_id FK
        int product_id FK
        int quantity
        timestamp created_at
        timestamp updated_at
    }

    orders {
        int order_id PK
        varchar order_number UK
        int user_id FK
        varchar customer_name
        varchar customer_email
        varchar customer_phone
        text delivery_address
        varchar delivery_region
        varchar postal_code
        varchar delivery_method
        varchar payment_method
        decimal subtotal
        decimal discount_amount
        decimal delivery_price
        decimal final_amount
        varchar promo_code
        varchar status
        text notes
        timestamp created_at
        timestamp updated_at
        timestamp completed_at
    }

    order_items {
        int item_id PK
        int order_id FK
        int product_id FK
        varchar product_name
        decimal product_price
        int quantity
        decimal total_price
        timestamp created_at
    }

Описание таблиц

Таблица Описание
users Пользователи системы (покупатели и администраторы)
categories Категории товаров (Диваны, Кресла, Кровати и т.д.)
subcategories Подкатегории для более детальной классификации
products Товары с ценами, описанием и характеристиками
cart Корзина покупок (связь пользователь-товар-количество)
orders Заказы с информацией о доставке и оплате
order_items Позиции заказа (товары в заказе)
migrations Служебная таблица для отслеживания миграций

Миграции

Миграции выполняются в следующем порядке:

  1. 001_initial_schema.sql - Создание таблиц users, categories, subcategories, products
  2. 002_add_cart_orders.sql - Добавление таблиц cart, orders, order_items
  3. 003_add_product_fields.sql - Дополнительные поля для товаров (color, material, card_size)
  4. 004_grant_admin_to_admin_mail.sql - Назначение прав администратора

Установка и настройка

Требования

  • PHP 7.4 или выше
  • PostgreSQL 12 или выше
  • Веб-сервер (Apache) или встроенный PHP сервер для разработки

Шаг 1: Клонирование репозитория

git clone <repository-url>
cd cite_practica1

Шаг 2: Настройка базы данных

Отредактируйте файл config/database.php:

<?php
class Database {
    private static $instance = null;
    private $connection;

    private function __construct() {
        try {
            $this->connection = new PDO(
                "pgsql:host=ВАШ_ХОСТ;port=5432;dbname=ВАШ_DBNAME",
                "ВАШ_ЛОГИН",
                "ВАШ_ПАРОЛЬ"
            );
            $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->connection->exec("SET NAMES 'utf8'");
        } catch(PDOException $e) {
            die("Ошибка подключения: " . $e->getMessage());
        }
    }

    public static function getInstance() {
        if (self::$instance == null) {
            self::$instance = new Database();
        }
        return self::$instance;
    }

    public function getConnection() {
        return $this->connection;
    }
}

Шаг 3: Запуск миграций

Вариант 1: Автоматическая настройка

chmod +x setup.sh
./setup.sh

Вариант 2: Ручной запуск миграций

php migrations/migrate.php

Вариант 3: Загрузка тестовых данных

php migrations/migrate.php --seed

Шаг 4: Настройка прав доступа

chmod -R 755 public/
chmod -R 777 uploads/

Запуск проекта

Разработка (встроенный PHP сервер)

cd public
php -S localhost:8000

Затем откройте в браузере: http://localhost:8000

Production (Apache)

Пример конфигурации Virtual Host:

<VirtualHost *:80>
    ServerName aeterna.local
    DocumentRoot /path/to/cite_practica1/public
    
    <Directory /path/to/cite_practica1/public>
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/aeterna_error.log
    CustomLog ${APACHE_LOG_DIR}/aeterna_access.log combined
</VirtualHost>

Аутентификация и авторизация

Архитектура аутентификации

flowchart TD
    A[Пользователь] --> B{Авторизован?}
    B -->|Нет| C[Страница входа]
    B -->|Да| D{Роль?}
    
    C --> E[Ввод email/пароль]
    E --> F[API: auth.php]
    F --> G{Проверка в БД}
    G -->|Успех| H[Создание сессии]
    G -->|Ошибка| I[Сообщение об ошибке]
    
    H --> J[Сохранение в SESSION]
    J --> K[Редирект на каталог]
    
    D -->|Пользователь| L[Доступ к каталогу, корзине, заказам]
    D -->|Админ| M[Доступ к админ-панели]

Система сессий

При успешной авторизации в сессию сохраняются:

$_SESSION['user_id']     // ID пользователя
$_SESSION['user_email']  // Email
$_SESSION['full_name']   // Полное имя
$_SESSION['isLoggedIn']  // true
$_SESSION['isAdmin']     // true/false
$_SESSION['login_time']  // Время входа

Защита страниц

// Требовать авторизацию
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
    header('Location: login.php?error=auth_required');
    exit();
}

// Требовать права администратора
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {
    header('Location: login.php?error=admin_required');
    exit();
}

Роли пользователей

Роль Доступ
Гость Главная страница, услуги, доставка, гарантия
Пользователь + Каталог, корзина, оформление заказов, личный кабинет
Администратор + Админ-панель, управление товарами, заказами, пользователями

Функционал

Пользовательский интерфейс

flowchart LR
    subgraph pages [Страницы]
        A[Главная] --> B[Каталог]
        B --> C[Товар]
        C --> D[Корзина]
        D --> E[Оформление]
        E --> F[Успех]
    end
    
    subgraph auth [Авторизация]
        G[Вход] --> H[Регистрация]
    end
    
    subgraph info [Информация]
        I[Услуги]
        J[Доставка]
        K[Гарантия]
        L[Контакты]
    end

Главная страница (public/index.php)

  • Hero-секция с призывом к действию
  • Преимущества компании
  • Промо-блоки с акциями
  • Секция "О нас"
  • Слайдер с готовыми решениями
  • Статистика компании
  • FAQ (частые вопросы)

Каталог товаров (public/catalog.php)

  • Сетка товаров с изображениями
  • Фильтрация по:
    • Категориям
    • Диапазону цен
    • Цвету
    • Материалу
  • Поиск по названию
  • Добавление в корзину

Страница товара (public/product.php)

  • Галерея изображений
  • Описание и характеристики
  • Цена и скидка
  • Наличие на складе
  • Кнопка добавления в корзину
  • Рекомендуемые товары

Корзина (public/checkout.php)

  • Список товаров в корзине
  • Изменение количества
  • Удаление товаров
  • Расчет итоговой суммы
  • Применение промокода
  • Форма оформления заказа

API Endpoints

Аутентификация

POST /api/auth.php

Авторизация пользователя

Запрос:

{
  "email": "user@example.com",
  "password": "password123"
}

Ответ (успех):

{
  "success": true,
  "redirect": "catalog.php"
}

Ответ (ошибка):

{
  "success": false,
  "message": "Неверный пароль"
}

Корзина

POST /api/cart.php?action=add

Добавление товара в корзину

Запрос:

{
  "product_id": 1,
  "quantity": 2
}

Ответ:

{
  "success": true,
  "message": "Товар добавлен в корзину"
}

POST /api/cart.php?action=update

Обновление количества товара

Запрос:

{
  "product_id": 1,
  "quantity": 3
}

POST /api/cart.php?action=remove

Удаление товара из корзины

Запрос:

{
  "product_id": 1
}

GET /api/cart.php?action=get

Получение содержимого корзины

Ответ:

{
  "success": true,
  "items": [
    {
      "cart_id": 1,
      "product_id": 5,
      "quantity": 2,
      "name": "Диван ROYALTY",
      "price": 78999,
      "image_url": "img2/6_6.png"
    }
  ],
  "total": 157998
}

GET /api/cart.php?action=count

Количество товаров в корзине

Ответ:

{
  "success": true,
  "count": 3
}

Товары

GET /api/get_product.php?id=1

Получение информации о товаре

Ответ:

{
  "success": true,
  "product": {
    "product_id": 1,
    "name": "Светильник MINNIGHT",
    "description": "Настольный светильник в современном стиле",
    "price": 7999,
    "old_price": 9999,
    "image_url": "img2/1_2.png",
    "color": "Черный",
    "material": "Металл",
    "stock_quantity": 15,
    "is_available": true
  }
}

Заказы

POST /api/process_order.php

Оформление заказа

Запрос:

{
  "customer_name": "Иван Иванов",
  "customer_email": "ivan@example.com",
  "customer_phone": "+79001234567",
  "delivery_address": "г. Москва, ул. Примерная, д. 1",
  "delivery_method": "courier",
  "payment_method": "card"
}

Ответ:

{
  "success": true,
  "order_number": "AET-20251216-ABC123",
  "message": "Заказ успешно оформлен"
}

Административная панель

Доступ

URL: /admin/index.php или /public/catalog_admin.php

Требуется авторизация с правами администратора (is_admin = TRUE)

Функции

flowchart TD
    A[Админ-панель] --> B[Dashboard]
    A --> C[Категории]
    A --> D[Товары]
    A --> E[Заказы]
    A --> F[Пользователи]
    
    C --> C1[Список категорий]
    C --> C2[Добавить категорию]
    C --> C3[Редактировать]
    C --> C4[Удалить]
    
    D --> D1[Список товаров]
    D --> D2[Добавить товар]
    D --> D3[Редактировать]
    D --> D4[Удалить]
    D --> D5[Загрузка изображений]
    
    E --> E1[Список заказов]
    E --> E2[Детали заказа]
    E --> E3[Изменить статус]

Управление категориями

  • Создание категорий и подкатегорий
  • Редактирование названия и описания
  • Установка порядка сортировки
  • Активация/деактивация

Управление товарами

  • Добавление новых товаров
  • Редактирование характеристик
  • Загрузка изображений
  • Установка цен и скидок
  • Управление наличием

Управление заказами

Статусы заказов:

Статус Описание
pending Ожидает обработки
processing В обработке
shipped Отправлен
delivered Доставлен
cancelled Отменен

Функции и утилиты

includes/functions.php

Проверка авторизации

/**
 * Проверка авторизации пользователя
 */
function isLoggedIn(): bool {
    return isset($_SESSION['isLoggedIn']) && $_SESSION['isLoggedIn'] === true;
}

/**
 * Проверка прав администратора
 */
function isAdmin(): bool {
    return isset($_SESSION['isAdmin']) && $_SESSION['isAdmin'] === true;
}

Защита страниц

/**
 * Требовать авторизацию - редирект на login если не авторизован
 */
function requireAuth(string $redirectUrl = 'login.php'): void {
    if (!isLoggedIn()) {
        header('Location: ' . $redirectUrl . '?error=auth_required');
        exit();
    }
}

/**
 * Требовать права администратора
 */
function requireAdmin(string $redirectUrl = 'login.php'): void {
    if (!isAdmin()) {
        header('Location: ' . $redirectUrl . '?error=admin_required');
        exit();
    }
}

Получение текущего пользователя

/**
 * Получить текущего пользователя
 */
function getCurrentUser(): ?array {
    if (!isLoggedIn()) {
        return null;
    }
    
    return [
        'user_id' => $_SESSION['user_id'] ?? 0,
        'email' => $_SESSION['user_email'] ?? '',
        'full_name' => $_SESSION['full_name'] ?? '',
        'is_admin' => isAdmin()
    ];
}

Форматирование

/**
 * Форматирование цены
 */
function formatPrice(float $price): string {
    return number_format($price, 0, '', ' ') . ' ₽';
}

/**
 * Безопасный вывод HTML
 */
function e(string $str): string {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

Генерация идентификаторов

/**
 * Генерация номера заказа
 */
function generateOrderNumber(): string {
    return 'AET-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -6));
}

/**
 * Создание slug из строки
 */
function createSlug(string $str): string {
    $slug = transliterate($str);
    $slug = strtolower($slug);
    $slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
    return trim($slug, '-');
}

Транслитерация

/**
 * Транслитерация кириллицы в латиницу
 */
function transliterate(string $str): string {
    $converter = [
        'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd',
        'е' => 'e', 'ё' => 'e', 'ж' => 'zh', 'з' => 'z', 'и' => 'i',
        // ... и т.д.
    ];
    return strtr($str, $converter);
}

Flash-сообщения

/**
 * Установить flash-сообщение
 */
function setFlashMessage(string $type, string $message): void {
    $_SESSION['flash_message'] = [
        'type' => $type,
        'message' => $message
    ];
}

/**
 * Получить и удалить flash-сообщение
 */
function getFlashMessage(): ?array {
    if (isset($_SESSION['flash_message'])) {
        $message = $_SESSION['flash_message'];
        unset($_SESSION['flash_message']);
        return $message;
    }
    return null;
}

Безопасность

Защита от SQL-инъекций

Все запросы к базе данных используют подготовленные выражения (Prepared Statements):

// ПРАВИЛЬНО - безопасно
$stmt = $db->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);

// НЕПРАВИЛЬНО - уязвимо для SQL-инъекций
$result = $db->query("SELECT * FROM users WHERE email = '$email'");

Хеширование паролей

Пароли хешируются с использованием bcrypt:

// Хеширование при регистрации
$password_hash = password_hash($password, PASSWORD_DEFAULT);

// Проверка при авторизации
if (password_verify($password, $user['password_hash'])) {
    // Пароль верный
}

Защита от XSS

Все пользовательские данные экранируются при выводе:

// Безопасный вывод
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');

// Или используя функцию-хелпер
echo e($user_input);

Защита сессий

// Регенерация ID сессии после авторизации
session_regenerate_id(true);

// Проверка авторизации на каждой странице
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
    header('Location: login.php');
    exit();
}

CSRF-защита

Рекомендуется добавить токены для форм:

// Генерация токена
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));

// В форме
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">

// Проверка
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    die('CSRF token mismatch');
}

Проверка прав доступа

// Проверка на каждой защищенной странице
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
    header('Location: login.php?error=auth_required');
    exit();
}

// Проверка прав администратора
if (!isset($_SESSION['isAdmin']) || $_SESSION['isAdmin'] !== true) {
    die('Доступ запрещен');
}

Тестовые аккаунты

При подключении к удаленной DB доступны тестовые аккаунты:

Администратор

Поле Значение
Email admin@mail.ru
Пароль admin123
Имя Администратор AETERNA
Права Полный доступ к админ-панели

Разработка

Создание новой миграции

  1. Создайте файл migrations/XXX_название.sql (где XXX - следующий номер)
  2. Напишите SQL-код
  3. Запустите php migrations/migrate.php

Пример миграции:

-- 005_add_reviews.sql
-- Добавление таблицы отзывов

CREATE TABLE IF NOT EXISTS reviews (
    review_id SERIAL PRIMARY KEY,
    product_id INTEGER REFERENCES products(product_id) ON DELETE CASCADE,
    user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
    rating INTEGER CHECK (rating >= 1 AND rating <= 5),
    comment TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_reviews_product ON reviews(product_id);

Стиль кода

  • Используйте PSR-12 для PHP
  • Именование переменных: snake_case
  • Именование функций: camelCase или snake_case
  • Именование классов: PascalCase
  • Комментируйте сложную логику
  • Используйте типизацию где возможно

Структура API endpoint

<?php
session_start();
require_once __DIR__ . '/../config/database.php';

header('Content-Type: application/json; charset=utf-8');

// Проверка авторизации
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
    echo json_encode(['success' => false, 'message' => 'Требуется авторизация']);
    exit();
}

try {
    $db = Database::getInstance()->getConnection();
    
    // Ваша логика здесь
    
    echo json_encode(['success' => true, 'data' => $result]);
    
} catch (PDOException $e) {
    echo json_encode(['success' => false, 'message' => 'Ошибка базы данных']);
}

Добавление новой страницы

  1. Создайте файл в public/
  2. Подключите header и footer
  3. Добавьте проверку авторизации если нужно
  4. Используйте единый стиль оформления
<?php
session_start();
require_once __DIR__ . '/../config/database.php';

// Проверка авторизации (опционально)
if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
    header('Location: login.php');
    exit();
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>AETERNA - Название страницы</title>
    <link rel="stylesheet/less" type="text/css" href="style_for_cite.less">
    <script src="https://cdn.jsdelivr.net/npm/less"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
    <?php include 'header_common.php'; ?>
    
    <main class="container">
        <!-- Ваш контент -->
    </main>
    
    <?php include 'footer.php'; ?>
</body>
</html>

Диаграмма архитектуры

flowchart TB
    subgraph client [Клиент]
        Browser[Браузер]
    end
    
    subgraph server [Сервер]
        subgraph public [Public Directory]
            Index[index.php]
            Catalog[catalog.php]
            Product[product.php]
            Checkout[checkout.php]
            Login[login.php]
        end
        
        subgraph api [API Layer]
            Auth[auth.php]
            Cart[cart.php]
            Order[process_order.php]
        end
        
        subgraph core [Core]
            Config[database.php]
            Functions[functions.php]
            Includes[header/footer]
        end
        
        subgraph admin [Admin Panel]
            AdminIndex[admin/index.php]
        end
    end
    
    subgraph database [База данных]
        PostgreSQL[(PostgreSQL)]
    end
    
    Browser <--> Index
    Browser <--> Catalog
    Browser <--> Product
    Browser <--> Checkout
    Browser <--> Login
    Browser <--> Auth
    Browser <--> Cart
    Browser <--> Order
    Browser <--> AdminIndex
    
    Index --> Config
    Catalog --> Config
    Product --> Config
    Checkout --> Config
    Login --> Config
    Auth --> Config
    Cart --> Config
    Order --> Config
    AdminIndex --> Config
    
    Config <--> PostgreSQL

Поток оформления заказа

sequenceDiagram
    participant U as Пользователь
    participant B as Браузер
    participant C as checkout.php
    participant API as process_order.php
    participant DB as PostgreSQL
    
    U->>B: Открывает корзину
    B->>C: GET /checkout.php
    C->>DB: SELECT cart items
    DB-->>C: Товары корзины
    C-->>B: HTML страница корзины
    
    U->>B: Заполняет форму заказа
    U->>B: Нажимает "Оформить"
    B->>API: POST /api/process_order.php
    
    API->>DB: BEGIN TRANSACTION
    API->>DB: INSERT INTO orders
    DB-->>API: order_id
    
    loop Для каждого товара
        API->>DB: INSERT INTO order_items
        API->>DB: UPDATE products (stock)
    end
    
    API->>DB: DELETE FROM cart
    API->>DB: COMMIT
    
    API-->>B: JSON success + order_number
    B-->>U: Страница успеха