API Products - rubyhat/fastyshop-backend GitHub Wiki

📦 Товары и услуги (Products API)

Контроллер: Api::V1::ProductsController
Версия: v1
Слой: Аутентифицированный API + Публичный просмотр


📘 Общая логика

Товары и услуги — это основной контент магазинов.
В рамках одного магазина создаются позиции с базовыми данными (title, price, description) и произвольными характеристиками (ProductPropertyValue).
Каждый товар привязан к:

  • ProductCategory
  • Shop

📄 Методы


🆕 POST /api/v1/products

Создание нового товара или услуги

🔹 Входные параметры (JSON)

Поле Тип Обязательный Пример
title string Кресло "Сити"
slug string ❌ (авто) kreslo-siti
price number 34900.0
description string Эргономичное кресло
product_category_id UUID UUID категории
shop_id UUID UUID магазина
product_property_value_ids array(UUID) Список ID характеристик
is_visible boolean true
stock_quantity integer 10

✅ Ответ (201 Created)

{
  "id": "1a2b...",
  "title": "Кресло Сити",
  "slug": "kreslo-siti",
  "price": 34900.0,
  "shop_id": "xxx",
  "stock_quantity": 10
}

✅ Чек-лист

Пункт Значение
🔒 Требуется access token ✅ Да
🔐 Политики доступа Только продавец — владелец магазина
🔗 Зависимости Магазин и категория должны существовать

💼 Бизнес-логика

  • Slug генерируется автоматически, пользователю вручную редактировать нельзя
  • Проверяется, что магазин и категория принадлежат продавцу
  • Значения характеристик (product_property_value_ids) валидируются
  • Проверка stock_quantity > 0

📚 Кейсы использования

🆕 Кейс 1: Продавец добавляет новый товар

Заполняет поля title, price, shop_id, product_category_id и нажимает "Создать".

🧮 Кейс 2: Автоматическая генерация slug

Если поле slug не указано, сервер создаёт его автоматически на основе title.

🚫 Кейс 3: Ошибка из-за отсутствия характеристик

Если переданы product_property_value_ids, но они не существуют — сервер вернёт ошибку 422.


📂 GET /api/v1/products

Получение списка всех товаров магазина

🔹 Параметры запроса

Параметр Тип Обязательный Описание
shop_id UUID Магазин, чьи товары запрашиваются
category_id UUID Фильтрация по категории
is_visible boolean Только видимые товары

✅ Ответ

[
  {
    "id": "1",
    "title": "Кресло Сити",
    "price": 34900,
    "stock_quantity": 10
  },
  ...
]

✅ Чек-лист

Пункт Значение
🔒 Требуется access token ✅ Да (для владельца)
🔐 Политики доступа Только владелец магазина
🔗 Зависимости Магазин существует и принадлежит

💼 Бизнес-логика

  • Поддерживается фильтрация по category_id и is_visible
  • Товары возвращаются с минимальной информацией
  • Только активные (is_active: true)

📚 Кейсы использования

🔎 Кейс 1: Продавец видит все свои товары

В панели управления выбирает магазин и получает весь список товаров.

📁 Кейс 2: Отображение по категории

Продавец фильтрует товары по категории при редактировании.


🔍 GET /api/v1/products/:id

Получить информацию о товаре по ID

✅ Ответ

{
  "id": "1a2b...",
  "title": "Кресло Сити",
  "price": 34900,
  "description": "Эргономичное кресло",
  "stock_quantity": 10,
  "product_category": {
    "id": "abc1...",
    "title": "Мебель"
  },
  "product_property_values": [
    {
      "id": "x1",
      "value": "Красный",
      "product_property": {
        "title": "Цвет"
      }
    }
  ]
}

✅ Чек-лист

Пункт Значение
🔒 Требуется access token ✅ Да
🔐 Политики доступа Только владелец товара
🔗 Зависимости ID товара, права на магазин

📚 Кейсы использования

🧾 Кейс 1: Редактирование товара

Продавец открывает карточку товара и видит полную информацию для редактирования.


✏️ PATCH /api/v1/products/:id

Обновление товара

🔹 Поддерживаемые поля:

  • title
  • price
  • description
  • is_visible
  • stock_quantity
  • product_property_value_ids

✅ Ответ

{
  "id": "1a2b...",
  "title": "Кресло Cити (обновл.)",
  "price": 35900
}

💼 Бизнес-логика

  • При передаче product_property_value_ids — проводится валидация
  • slug нельзя изменить после создания

📚 Кейсы использования

🖊 Кейс 1: Обновление цены и остатков

Продавец меняет цену и количество на складе.

🧪 Кейс 2: Добавление характеристик

Продавец добавляет ID свойств (product_property_value_ids), и они прикрепляются к товару.


🗑 DELETE /api/v1/products/:id

Удаление товара

✅ Ответ

{
  "message": "Товар успешно удален"
}

💼 Бизнес-логика

  • Товар удаляется физически (если не участвует в заказах)
  • В будущем — soft-delete (в планах)

📚 Кейсы использования

🧹 Кейс 1: Удаление неактуального товара

Продавец удаляет устаревший или ошибочный товар.


🌐 GET /api/v1/products/public

Публичный поиск товаров по фильтрам

🔹 Параметры:

Параметр Описание
shop_id ID магазина
category_id ID категории
query Поиск по title

✅ Ответ

[
  {
    "id": "1",
    "title": "Кресло",
    "price": 34000
  }
]

📚 Кейсы использования

🛍️ Кейс 1: Покупатель ищет товар

Клиент заходит в магазин и ищет “Кресло” — получает список по фильтру.


🛍️ GET /api/v1/shops/:shop_id/products

Публичный список всех товаров магазина

✅ Ответ

[
  {
    "id": "a1",
    "title": "Товар A"
  },
  {
    "id": "b2",
    "title": "Товар B"
  }
]

📚 Кейсы использования

🛒 Кейс 1: Каталог магазина

Покупатель заходит в магазин и видит весь доступный список товаров.


🧩 Связанные сущности

Сущность Назначение
Product Основная модель товара
ProductPropertyValue Свойства, прикреплённые к товару
Shop Владелец
ProductCategory Категория
OrderItem Связь с заказами (в будущем soft-delete)

📄 TODO / Идеи

  • Поддержка изображений (галерея)
  • Массовое обновление товаров
  • Интеграция с шаблонами (по категориям)