CMS Catalog - Ecommerce

lsnull

Куратор темы
Регистрация
18 Сен 2013
Сообщения
420
Реакции
135
Всем привет.
Пишу CMS Каталога товаров / объявлений.

В CMS Catalog входит:
корзина товаров, гибкая и мощная форма публикации товаров, формирование заказа, сделки, статусы товара (отслеживание статуса), личная переписка между продавцом и покупателем (в заказе), страница профиля, два типа регистрации: продавец и дилер, баланс профиля, управление товарами, истории покупок/продаж/просмотров, похожие товары, избранное, добавление в сравнение, гибкий и удобный фильтр по товарам, поиск по товарам, история цен товара, отзывы и рейтинг товара, продление срока публикаций товара, галерея товара, гибкая и мощная система предустановленных полей для характеристик товаров (пользовательские поля), адаптивный и современный дизайн + Админка с необходимым функционалом и разный другой функционал для заказов, статей, пользователей и админки.

Пощупать можно по адресу Для просмотра ссылки Войди или Зарегистрируйся

Кого заинтересовал, пишите комменты.

Приложение изначально спроектировано как полноценное Full-Stack приложение на Node.js (Express + React + Vite).
Вот как устроена эта архитектура:
  • Режим Node.js (Основной) Когда приложение запускается на сервере Node.js (например, в Docker, Cloud Run, VPS или локально при разработке), за всё отвечает файл server.ts. Он обслуживает фронтенд и самостоятельно обрабатывает все запросы к API по адресу /api/*, напрямую обращаясь к базе данных MySQL через модуль mysql2. В этом режиме PHP вообще не требуется и никак не задействуется.
  • Режим PHP (Альтернативный / Хостинг) Папка php_rest_api была создана как альтернативный бэкенд для развертывания проекта на классических веб-хостингах (shared-хостингах), где нет возможности запустить постоянный процесс Node.js, но есть поддержка PHP и MySQL.
Благодаря добавленному глобальному перехватчику fetch в src/main.tsx, приложение определяет окружение автоматически:

  • Если это локальная среда разработки или облачный контейнер (Node.js), запросы идут напрямую на бэкенд Express (/api/*).
  • Если проект запущен на внешнем PHP-хостинге, запросы «на лету» перенаправляются на PHP-роутер (/php_rest_api/index.php/api/*).



Screenshot_77.png



В общем очень попрошу о баг репорте, что бы отладить до идеала сборку под PHP что бы работал весь функционал как на Node,js так и на PHP.Сейчас есть баги с функционалом после сборки на PHP:
Endpoint '/api/collections/3/products' with method 'POST' is not implemented in our MVC PHP API.

Endpoint '/api/compare/toggle' with method 'POST' is not implemented in our MVC PHP API.

1. Исправление Избранного и Сравнения товаров (Wishlist & Comparisons)​

  • Причина бага: В методе /api/db-state при получении состояния базы данных возвращались полные строки товаров для избранного и сравнения, в то время как фронтенд ожидал сырые пары отношений { user_id, product_id } из связующих таблиц. Из-за отсутствия этих полей фильтрация на клиенте data.favorites.filter((f) => f.user_id === userKey) всегда возвращала пустой массив. Это приводило к тому, что избранное сбрасывалось, а плавающая панель сравнения (floating-compare-tray) не отображалась.
  • Решение:
    • В модели /public/php_rest_api/models/Product.php функции getFavorites() и getComparisons() изменены для выборки пар user_id, product_id напрямую из таблиц favorites и comparisons.
    • В контроллере /public/php_rest_api/controllers/ProductController.php в методе getDbState() добавлено приведение типов к целым числам (integer), чтобы гарантировать прохождение строгих проверок === во фронтенде.
    • Добавлена поддержка передачи параметров как в формате camelCase (userId, productId), так и в snake_case (user_id, product_id) в обработчиках переключения избранного и сравнения, с автовыбором активной сессии в качестве запасного варианта.

2. Сохранение Основных характеристик (Custom Values / Characteristics)​

  • Причина бага: При создании или редактировании товара фронтенд отправляет AJAX-запрос на специальный эндпоинт POST /api/products/:id/custom-values для сохранения структурированных динамических характеристик. Этот роут отсутствовал в файле маршрутизации PHP REST API, из-за чего данные не сохранялись в таблицу product_custom_values (возвращалась ошибка 404).
  • Решение:
    • В файле маршрутизатора /public/php_rest_api/index.php зарегистрирован роут POST products/:id/custom-values.
    • В контроллере /public/php_rest_api/controllers/ProductController.php реализован метод saveProductCustomValues($productId), который проверяет права доступа пользователя (владелец товара или администратор), очищает старые характеристики товара и в транзакционном режиме вставляет новые значения характеристик.

Часть уже пофиксил, расширил api для сборки

исправил проблему с удалением связанных данных и очистил зависшие избранные товары!

Что было еще сделано:​

  1. Каскадное удаление при удалении товара:
    • В обработчик удаления товара (DELETE /api/products/:id в /server/routes/products.ts) добавлено автоматическое предварительное удаление всех связанных записей из базы данных.
    • Теперь при удалении товара автоматически стираются:
      • Избранное (favorites)
      • Сравнения (comparisons)
      • Отзывы и комментарии (reviews)
      • Товары в коллекциях (collection_products)
      • Дополнительные характеристики (значения кастомных полей) (product_custom_values)
      • История изменения цен (product_price_history)
      • История просмотров (viewing_history)
      • Уведомления, связанные с товаром (notifications)
      • Загруженные изображения товара (физическая папка с файлами)
  2. Очистка существующих «битых» связей на старте сервера:
    • В /server.ts интегрирован фоновый скрипт очистки базы данных, запускающийся при старте приложения.
    • Он находит любые зависшие (сиротские) записи в избранном, отзывах, сравнениях и других таблицах, у которых оригинальный товар был удален ранее, и автоматически удаляет их.
    • Это мгновенно решило проблему с уже зависшими в избранном удаленными товарами, так как сервер был успешно перезапущен!



  • Интеграция авторизации при добавлении товара:
    • При нажатии на кнопку "+ Добавить товар" неавторизованным пользователем теперь сначала открывается модальное окно Авторизации/Регистрации.
    • После успешного входа или регистрации система автоматически открывает форму создания нового товара, обеспечивая бесшовный пользовательский опыт без лишних кликов.
  • Двухэтапная форма (Мастер создания товара):
    • Для оптимизации пространства и удобства заполнения блок «Дополнительные Характеристики (Пользовательские Поля)» вынесен во второй этап (вкладку).
    • В случае наличия дополнительных характеристик для категории товара сверху формы отображается элегантный переключатель вкладок («1. Основные параметры» и «2. Дополнительные характеристики»).
    • Кнопки навигации («Далее →» и «← Назад») позволяют комфортно переключаться между шагами.
  • Фиксированные кнопки управления:
    • Кнопки отмены и сохранения изменений теперь жестко зафиксированы в нижней части модального окна (фиксированный футер).
    • Поля ввода прокручиваются независимо внутри модального окна, в то время как кнопки всегда остаются на виду.
    • В точности соблюдены требуемые подписи к кнопкам на русском языке:
      • В режиме добавления товара: «Отменить» и «Добавить товар».
      • В режиме редактирования товара: «Отмена» и «Сохранить изменения».



1. Унифицированная основная логика ценообразования​

  • Доминирование основной цены:
    Изменены правила расчёта и отображения цен. Теперь product.price всегда используется как основная цена товара для всех расчётов в корзине, при оформлении заказа, для скидок и оптовых цен.
  • Вторичный диапазон цен:
    Если указан «Диапазон цен (от/до)», он отображается как вторичная вспомогательная справочная строка («Диапазон цен (Справочно: X – Y»), а не полностью заменяет или скрывает основную стоимость товара. Эти изменения внедрены в:
    • Карточках товаров в каталоге (CatalogView.tsx);
    • Странице детального просмотра (ProductDetailsView.tsx);
    • Модальном окне быстрого просмотра товара (ProductDetailModal.tsx).

2. Многоуровневое (трёхступенчатое) оптовое ценообразование​

  • Интеграция с базой данных и сохраняемость:
    Расширена схема БД пользовательскими столбцами для второго уровня (wholesale_price_2, wholesale_threshold_2) и третьего уровня (wholesale_price_3, wholesale_threshold_3).
    Добавлены автоматические миграционные запросы при запуске БД, которые автоматически создают эти новые столбцы, если они ещё не существуют.
  • Динамический расчёт оптовых цен:
    Централизована логика эффективной цены в файлах /server/routes/features.ts и /server/routes/wallet.ts.
    Алгоритм сначала проверяет наличие действующих акционных цен, а затем последовательно перебирает все три оптовых уровня (сортировка порогов по убыванию), чтобы определить наименьшую допустимую цену для выбранного количества.
  • Формы создания и редактирования товаров:
    Обновлён ProductFormModal.tsx — добавлены три полностью локализованные строки ввода для оптовых уровней (для каждого — цена и порог количества).
    Они подключены с чистыми валидаторами, а данные синхронизированы с API сохранения/обновления на бэкенде.
  • Современная сетка карточек уровней:
    Одиночный блок с ценой заменён на элегантную сетку-«бенто» с карточками оптовых уровней.
    Динамически отображаются только заполненные уровни в виде модульных справочных карточек, показывающих прогрессивные ступени скидок.




Обеспечен корректный расчёт оптовых пороговых цен и их динамическое обновление в реальном времени при изменении количества товаров в корзине.

Выполненные работы:

  1. Реализация оптовой логики в корзине
    В файле /src/components/cart/ShoppingCart.tsx добавлена надёжная вспомогательная функция getItemCalculatedUnitPrice, которая эмулирует серверный механизм оценки многоуровневых оптовых и акционных цен. Функция учитывает действующие акции и все три пороговых уровня оптовых скидок, заданных в метаданных товара.
  2. Расчёт промежуточных сумм и согласованность цен
    Блок useMemo, отвечающий за вычисление субтотала в панели корзины, полностью переработан. Теперь он итеративно обходит элементы корзины и суммирует промежуточные итоги на основе скорректированных оптовых цен за единицу. Это гарантирует полное соответствие детализированных сумм, применённых скидок и итоговой стоимости в панели с серверными данными.
  3. Улучшенная визуальная обратная связь
    Цена за единицу товара в панели корзины стала интерактивной: при достижении оптового порога или попадании под акцию выделяется сниженная оптовая цена, а рядом отображается перечёркнутая исходная цена.
    Для всех денежных отображений на этапе оформления (сводки по шагам, проверка купонов, прогноз остатка после списания со счёта, модальные окна печатных квитанций) применена утилита formatPrice, что обеспечивает единообразное отображение валюты, выбранной пользователем.
  4. Для всех отображений валют в процессе оформления заказа (включая сводки по стоимости этапов, проверку купонов, оценку остатка после списания с кошелька и модальные окна печати квитанций) использована утилита formatPrice, что обеспечивает правильное соответствие валюте, выбранной пользователем на сайте.



Реализована функциональность «Черновик товара» с соблюдением принципа единственной ответственности (SRP) и стандартов работы с базой данных.
1. Эволюция схемы базы данных

В server.ts добавлен автоматический блок миграции, который создаёт в таблице products стандартный защищённый флаг is_draft (тип TINYINT DEFAULT 0).
2. Унифицированная логика контроллера на бэкенде
  • Улучшен эндпоинт POST /products — теперь он создаёт товар и возвращает его статус черновика с сохранением безопасности.
  • Переработан эндпоинт PUT /products/:id — он объединяет входящие данные с существующей записью, что предотвращает потерю данных при частичных обновлениях и позволяет независимо переключать состояние черновика.
3. Управление на уровне форм
В модальном окне редактирования товара (ProductFormModal) в разделе «Расширенные атрибуты» добавлен высококонтрастный блок управления статусом публикации и черновиком. Использованы стандартные цветовые схемы (акцент янтарного цвета) с поддержкой русской и английской локализации.
Состояния формы корректно инициализируются и синхронизируются при редактировании, что исключает побочные эффекты в виде бесконечных циклов.
4. Списки товаров и управление жизненным циклом
  • Обновлён хук фильтрации useProductFilters — теперь черновики исключаются из публичного каталога.
  • В таблице списка товаров в личном кабинете добавлен индикатор статуса (Активен / Черновик), обеспечивающий мгновенную визуальную обратную связь для владельца.
  • В панели действий со списком реализована кнопка быстрого переключения Опубликовать / Снять с публикации, позволяющая владельцу изменять статус публикации товара одним кликом.



Внедрение системы управления пользователями и блокировок (User Management & Banning) в панели администратора (каталог RBAC), обеспечив полную совместимость как с локальным сервером разработки на Node.js, так и с виртуальным хостингом на PHP:

Визуальное оформление и дизайн интерфейса

  • Интерактивная панель пользователя: Модернизировал представление каталога RBAC в панели администратора, добавив сворачиваемую карточку формы с высокой контрастностью для обработки как регистрации, так и редактирования профиля пользователя.
  • Эстетичные статусные бейджи и индикаторы блокировки: Реализовал бейджи статуса в реальном времени (например, «Активен» изумрудным цветом, «Заблокирован до...» розовым или «Заблокирован навсегда» тёмно-бордовым) с встроенным описанием причины и аккуратной вёрсткой с увеличенными отступами.
  • Интуитивные опции блокировки: Добавил выдвижную панель административной блокировки с предустановленными пресетами:
    • Активен (без блокировки) Снимает все ограничения.
    • Блокировка на 60 дней: Автоматически рассчитывает точную дату разблокировки через 60 дней от текущего момента.
    • Блокировка навсегда: Устанавливает перманентную блокировку.
    • Произвольная дата: Отображает интерактивный выбор даты и времени для установки пользовательских ограничений.
Базовая бизнес-логика и логика принудительного контроля

  • Принудительные меры:Полностью связал вводимые администратором данные с API. Если пользователь в данный момент заблокирован:
    • Ему запрещается публиковать новые товары или редактировать существующие.
    • Ему запрещается оставлять отзывы о товарах.
    • Ему запрещается оценивать чужие объявления.
  • Синхронизация между платформами: Логика полностью синхронизирована как в среде разработки (Node.js/Express), так и в рабочей среде (PHP API). Наш продакшн-сборки, загруженные из каталога dist в корневую папку виртуального хостинга, будут работать безупречно с идентичными ограничениями и обновлениями базы данных.



Исправил поведение форм авторизации и регистрации на сайте, чтобы они были доступны только гостям и неавторизованным пользователям.

Основные изменения:​

  • Защита отображения форм: Теперь формы входа (login) и регистрации (register) отображаются на главной странице и в модальном окне только в том случае, если пользователь еще не авторизован (currentUser равен null).
  • Автоматическое перенаправление: Если авторизованный пользователь попытается перейти на экраны авторизации или регистрации (или если он только что успешно выполнил вход/зарегистрировался), приложение автоматически перенаправит его обратно к списку товаров (list) с небольшой плавной задержкой, чтобы дать возможность прочитать уведомление об успешном входе.
  • Блокировка модального окна: Модальное окно авторизации теперь автоматически скрывается и не может быть открыто, если в приложении установлена активная пользовательская сессия.



Онлайн-проверка занятости Username при регистрации​

  • Добавление функции проверки: В поле Username формы регистрации добавлена кнопка со значком лупы (поиска) для моментальной проверки занятости имени пользователя.
  • Интерактивные статусы: При нажатии выполняется реальный запрос к базе данных через API. Пользователь видит красивое состояние загрузки с анимацией, а затем один из следующих статусов:
    • Имя пользователя свободно! (с зеленой галочкой)
    • Это имя пользователя уже занято. (с красным крестиком)
    • Текст ошибки (например, если поле пустое или отсутствует связь с сервером).
  • Синхронизация полей: При изменении текста в поле Username состояние проверки сбрасывается для обеспечения актуальности.

Добавление поля Email и обязательная валидация всех полей​

  • Новое поле: В форму регистрации добавлено полноценное поле Email с placeholder-ом yourname@example.com.
  • Обязательность и метки: Все поля формы регистрации снабжены визуальными индикаторами обязательности в виде красных звездочек (*) и снабжены HTML5-атрибутом required.
  • Всесторонняя валидация:
    • Клиентская сторона: Добавлены регулярные выражения для проверки формата электронной почты и сверка соответствия паролей перед отправкой.
    • Серверная сторона (Node.js & PHP): Реализована строгая валидация входящих параметров, валидация формата e-mail методом filter_var (в PHP), а также уникальности Email в базе данных с возвратом ошибки 409 (Conflict) в случае совпадения.

Полная поддержка PHP REST API (public/php_rest_api)​

  • Синхронизация кода: Обновлен контроллер UserController.php и роутер index.php в папке public/php_rest_api. Добавлен роут auth/check-username, поддерживающий как GET, так и POST запросы, и обновлена логика register для сохранения реального email-адреса вместо заглушки.



Что было сделано еще:​

  1. Интерактивная валидация в UI (Регистрация):
    • В компоненте src/components/auth/AuthForms.tsx добавлена мгновенная проверка вводимого username по регулярному выражению /^[a-zA-Z0-9_]+$/.
    • Если пользователь вводит недопустимые символы (включая кириллицу), прямо под полем мгновенно отображается понятное предупреждение: «Имя пользователя должно содержать только латинские символы и нижнее подчеркивание. Кириллица недопустима.»
    • Кнопка проверки занятости логина (checkUsernameAvailability) теперь тоже предварительно валидирует формат, предотвращая отправку некорректных запросов к серверу.
  2. Защита при отправке формы:
    • В хуке src/hooks/useAuth.ts (метод handleSimulatedRegister) добавлена жесткая проверка перед отправкой формы регистрации. Если логин содержит недопустимые символы, процесс регистрации прерывается с выводом ошибки в интерфейсе.
  3. Серверная валидация (Node.js):
    • В файле /server/routes/auth.ts методы /check-username и /register теперь дополнительно валидируют входящий username по регулярному выражению на сервере. При наличии недопустимых символов возвращается статус 400 Bad Request с аналогичным текстом ошибки на русском языке.
  4. Обновление PHP REST API (public/php_rest_api):
    • В контроллере /public/php_rest_api/controllers/UserController.php для методов register и checkUsername добавлена проверка формата логина через регулярные выражения PHP (preg_match('/^[a-zA-Z0-9_]+$/', $username)).
    • Обновлен файл /src/data.ts (встроенный исходный код PHP во вкладке администратора) для синхронизации логики валидации.


Реализовал как пагинацию, так и ленивую загрузку (бесконечный скролл / кнопку «Загрузить ещё») для списка товаров, строго следуя методологии Feature-Sliced Design (FSD)

Архитектура и реализованные функции:

Уровень Shared UI (shared/ui) :


  • Создал переиспользуемый, визуально отполированный компонент пагинации. Он обрабатывает разбивку по страницам, граничные значения, элементы управления первой/последней/предыдущей/следующей страницей, а также включает селектор количества элементов на странице (шт.), красиво стилизованный с помощью Tailwind CSS в соответствии с цветовой гаммой приложения (сланцевые/индиго оттенки).
Уровень Shared Hooks (shared/hooks) :

  • Реализовал стандартный, типобезопасный хук useIntersectionObserver. Он подключается к целевому элементу внизу списка и динамически запускает подгрузку дополнительных порций товаров, когда пользователь прокручивает каталог почти до конца.
Управляющая панель с переключением режимов:

  • Интегрировал элегантный, адаптивный переключатель режима отображения прямо в панель инструментов каталога. Пользователи могут бесшовно переключаться между тремя состояниями списка:
    • Страницы (Пагинация) Стандартный постраничный вывод с динамическими элементами управления.
    • Лента (Ленивая загрузка) Бесконечная лента товаров с плавным индикатором загрузки, дополненная резервной кнопкой «Загрузить ещё товары».
    • Всё сразу (Показать все) Стандартное отображение списка со всеми подходящими записями одновременно.
Сброс состояния и надёжная синхронизация:

  • Встроил наблюдатели сброса состояния в движок списка. Изменение поискового запроса, выбор категорий, изменение ползунка цен или обновление параметров сортировки мгновенно сбрасывают индекс пагинации и счётчики ленивой загрузки в ноль, предотвращая ошибки отображения за пределами допустимого диапазона.


  1. Защита от «мертвых» ссылок (Wishlist, Compare, History)
    • В контекст приложения (src/context/AppContext.tsx) добавлены строгие проверки на существование продуктов.
    • Теперь My Wishlist, сравнение товаров и история просмотров динамически очищаются от любых удаленных товаров (даже если они закешированы в браузерных cookies или локальном хранилище localStorage). Это полностью решает проблему висящих счетчиков и битых элементов.
  2. Синхронизация PHP REST API (Корзина для гостей и пользователей)
    • В PHP-контроллере ProductController.php реализован полноценный CRUD-набор эндпоинтов для корзины (getCart, addToCart, updateCartQuantity, removeFromCart, clearCart, mergeCart).
    • Маршрутизатор public/php_rest_api/index.php обновлен: добавлены соответствующие пути для обработки API-запросов корзины.
    • В метод оформления заказа checkout() в ProductController.php внедрена автоматическая очистка корзины из базы данных после успешной оплаты.
  3. Слияние гостевой корзины при авторизации (PHP)
    • В UserController.php добавлен метод mergeGuestCart(), который автоматически переносит все добавленные гостем товары в аккаунт зарегистрировавшегося или вошедшего пользователя, а затем очищает временный идентификатор гостя (guest_cart_id).
  4. Тестирование и проверка:
    • Все изменения полностью совместимы с архитектурой Feature-Sliced Design (FSD).
    • Были успешно запущены линтер и компилятор проекта — сборка прошла без единой ошибки (Build succeeded).



Установил и настроил ESLint для проекта с использованием самой современной и производительной конфигурации Flat Config (v9)

Что это даёт и для чего нужен ESLint?​

ESLint — это статический анализатор кода (ли́нтер), который автоматически сканирует файлы вашего проекта прямо во время написания кода или перед сборкой.
 

Вложения

  • Screenshot_82.png
    Screenshot_82.png
    627,8 KB · Просмотры: 13
  • Screenshot_81.png
    Screenshot_81.png
    481,7 KB · Просмотры: 12
  • Screenshot_80.png
    Screenshot_80.png
    162,5 KB · Просмотры: 8
  • Screenshot_79.png
    Screenshot_79.png
    274,1 KB · Просмотры: 7
  • Screenshot_78.png
    Screenshot_78.png
    450,9 KB · Просмотры: 7
  • Screenshot_76.png
    Screenshot_76.png
    1,1 MB · Просмотры: 6
  • Screenshot_75.png
    Screenshot_75.png
    428,2 KB · Просмотры: 5
  • Screenshot_74.png
    Screenshot_74.png
    424,9 KB · Просмотры: 4
  • Screenshot_73.png
    Screenshot_73.png
    582 KB · Просмотры: 4
  • Screenshot_72.png
    Screenshot_72.png
    702 KB · Просмотры: 4
  • Screenshot_71.png
    Screenshot_71.png
    310,6 KB · Просмотры: 4
  • Screenshot_70.png
    Screenshot_70.png
    339,7 KB · Просмотры: 4
  • Screenshot_69.png
    Screenshot_69.png
    330,6 KB · Просмотры: 4
  • Screenshot_68.png
    Screenshot_68.png
    317,7 KB · Просмотры: 4
  • Screenshot_67.png
    Screenshot_67.png
    185 KB · Просмотры: 4
  • Screenshot_66.png
    Screenshot_66.png
    147,3 KB · Просмотры: 6
Последнее редактирование:

Как происходит миграция!
Необходимые поля и таблицы для миграции, автоматически применяются и выполняются системой при запуске приложения.​

Вот как устроен этот механизм в нашей архитектуре:

1. Как работает система миграций БД​

В проекте в файле /src/db-store.ts настроена процедура автоматической инициализации и обновления структуры БД (initializeDb), которая выполняется при старте сервера:
  1. Создание новых таблиц (CREATE TABLE IF NOT EXISTS): Если таблица еще не существует в базе данных, сервер создаст её со всеми требуемыми связями при запуске.
  2. Безопасное добавление новых колонок (ALTER TABLE ADD COLUMN): При добавлении нового функционала мы вносим нужные поля в скрипт обновления в db-store.ts. При запуске сервер выполняет безопасный ALTER TABLE, оборачивая его в обработку исключений (чтобы колонка добавлялась, если её ещё нет, и не вызывала ошибок, если она уже существует).

2. Какие колонки были внесены для нового функционала:​

Для реализованных функций отмены покупки продавцом, подтверждения получения товара и динамических рейтингов в базу данных были автоматически добавлены следующие поля:
  • В таблицу orders:
    • cancel_reason TEXT — причина отмены заказа;
    • seller_cancel_reason TEXT — указанная продавцом причина отмены покупки на начальном этапе;
    • cancelled_by INT — ID пользователя, отменившего заказ;
    • cancelled_by_role VARCHAR(50) — роль отменившего (seller, buyer, admin);
    • buyer_received_at TIMESTAMP / deal_completed_at TIMESTAMP — временные метки завершения сделки.
  • В таблицу products:
    • rating DECIMAL(3,2) — рейтинг товара (автоматически снижается на -0.5★ при отмене покупки продавцом на этапе Processing).
  • В таблицу users:
    • trust_score INT — показатель доверия / репутация продавца (снижается на -10 при отмене заказа на начальном этапе);
    • bayesian_rating DECIMAL(3,2) — авторский рейтинг продавца.

Итог:​

Дополнительных ручных действий по миграции не требуется — всё уже прописано в схеме инициализации БД, база данных в рабочем окружении автоматически обновлена и готова к работе.
 

Реализован полный функционал подписки на уведомления о наличии товаров, управления подписчиками для авторов, а также автоматических оповещений и каскадной очистки данных.​

Screenshot_253.png

Screenshot_254.png Screenshot_250.png Screenshot_252.png

Что было реализовано:​

  • Подписка на уведомление о наличии (Notify When Available) :
    • Если товар активен в каталоге, но его нет в наличии (availability_status === 'out_of_stock' или остаток равен 0), для пользователей отображается интерактивная кнопка «Уведомить о наличии» в каталоге (сетка и список), детальном просмотре (ProductDetailsView) и модальном окне товара (ProductDetailModal).
    • Пользователи могут в один клик подписаться и отписаться от получения уведомления.
    • При подписке автор товара получает уведомление о новом заинтересованном покупателе.
  • Панель подписчиков для автора товара:
    • Автор товара (или администратор) видит статус количества подписчиков (например, «Подписчики: 3»).
    • По клику открывается модальное окно ProductSubscribersModal со списком пользователей, датой подписки и прямым переходом в их профили.
  • Оповещение подписчиков при появлении товара:
    • При редактировании товара или пополнении остатка (stock > 0, статус переведен в in_stock) всем подписчикам отправляется мгновенное системное уведомление: «Товар снова в наличии!» со ссылкой на товар, а подписки автоматически завершаются.
  • Оповещение при снятии с публикации и удалении:
    • Снятие с публикации / деактивация (is_active = 0) : все подписчики получают оповещение «Товар снят с публикации», после чего записи подписок автоматически очищаются.
    • Удаление товара: подписчики получают персональное оповещение «Товар был удален», подписки удаляются.
  • Полное каскадное удаление всех связанных данных товара:
    • При удалении товара гарантированно и безвозвратно удаляются:
      • Все подписки на наличие товара (product_availability_subscriptions)
      • Все отзывы и пользовательские рейтинги (reviews)
      • Все добавления товара в избранное (wishlist)
      • Все добавления товара в сравнение (comparison_items)
      • Все позиции в корзинах покупателей (cart_items)
      • Все связи с коллекциями и подборками (collection_products)
      • Все пользовательские характеристики товара (product_custom_values)
      • Все просмотры и история посещений (viewing_history, product_views)
      • Все промо-акции и акции скидок товара (promotions)
      • Все физические файлы изображений товара на диске и записи в БД (product_images)
      • Уведомления, привязанные к товару (notifications)
  • Архитектура и локализация:
    • Модуль вынесен в Feature-Sliced Design структуру: src/features/product-notifications/.
    • Добавлены переводы для всех языков интерфейса (RU, EN, UK, DE, ES) и поддержка иконок уведомлений в NotificationsHub.
 
Назад
Сверху