API Shops - rubyhat/fastyshop-backend GitHub Wiki

🏬 Магазины продавца (Shops API)

Контроллер: Api::V1::ShopsController
Версия: v1
Слой: Аутентифицированный API и публичный доступ (/shops/catalog, GET /shops/:id)


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

  • Каждый продавец (SellerProfile) может создать до 2 магазинов
  • Магазин создаётся в связке с юридическим профилем (LegalProfile)
  • Магазин содержит общие поля: название, тип, контакты, категория
  • Публичный доступ к каталогу и витрине магазина
  • Магазин может быть деактивирован (мягкое удаление)
  • Магазины могут быть онлайн, офлайн или гибридными.

📄 Методы

🆕 POST /api/v1/shops

Создание магазина

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

Поле Тип Обязательный Пример
title string Магазин мебели "ДОМ"
contact_phone string 77001234567
contact_email string [email protected]
physical_address string г. Алматы, ул. Абая, д. 25
shop_type string online / offline / hybrid
shop_category_id UUID UUID категории из seeds
legal_profile_id UUID UUID юр. лица продавца
seller_profile_id UUID UUID seller-профиля

✅ Ответ (201 Created)

{
  "id": "shop-uuid",
  "slug": "magazin-mebeli-dom",
  "title": "Магазин мебели ДОМ",
  "shop_type": "offline"
}

✅ Чек-лист

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

📋 Валидации

  • title — обязательное, уникальное в пределах одного продавца
  • shop_type — одно из: online, offline, hybrid
  • Проверка, что продавец не превысил лимит (2 магазина)
  • legal_profile_id принадлежит продавцу
  • Продавец может редактировать/удалять только свои магазины
  • Удаление - "мягкое", то есть в базе данных по факту данные не удаляются, а меняется статус на is_active: false, при попытке открытии магазина должна вернуться ошибка с текстом, что магазин был удален. Все категории, товары этого магазина должны также каскады "мягко" удалены и при попытке их запроса возвращать ошибку с текстом, что магазин был удален.

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

  • slug формируется автоматически на основе title
  • Продавец может создать не более 2 магазинов (временно, пока не введены тарифные планы)
  • После создания магазин отображается в /catalog и доступен по URL
  • При смене legal_profile_id необходимо пройти новую верификацию (в будущем)
  • В будущем при неоплате тарифного плана магазины и их категории + товары будут автоматически мягко удаляться, а при возобновлении оплаты автоматически восстанавливаться, поэтому важно не удалять данные из базы данных

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

🛍️ Кейс 1: Продавец создаёт первый магазин

Продавец указывает название, контакты, выбирает юр. лицо и категорию.

🚫 Кейс 2: Превышен лимит магазинов

Продавец пытается создать 3-й магазин — сервер возвращает 422.


📂 GET /api/v1/shops

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

✅ Ответ

[
  {
    "id": "shop-uuid",
    "title": "Магазин А",
    "slug": "magazin-a",
    "is_active": true
  }
]

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

  • Отображение списка магазинов в панели управления
  • Фильтрация активных / неактивных

🔍 GET /api/v1/shops/:id

Получение магазина по ID (публично)

✅ Ответ

{
  "id": "shop-uuid",
  "title": "Магазин мебели",
  "slug": "magazin-mebeli",
  "contact_phone": "77001234567"
}

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

  • Публичная страница магазина
  • Отображение магазина по ссылке в каталоге

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

Редактирование магазина

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

  • title, contact_phone, contact_email, physical_address, logo_url

✅ Ответ

{
  "id": "shop-uuid",
  "title": "Магазин мебели (обновлён)"
}

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

  • Обновление контактной информации
  • Редактирование адреса офиса

🗑 DELETE /api/v1/shops/:id

Деактивация магазина (мягкое удаление)

✅ Ответ

{
  "message": "Магазин успешно деактивирован"
}

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

  • Продавец временно закрывает магазин
  • Магазин не отображается в каталоге

🌍 GET /api/v1/shops/catalog

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

✅ Ответ

[
  {
    "id": "shop-uuid",
    "title": "Магазин мебели",
    "slug": "magazin-mebeli",
    "shop_type": "online"
  }
]

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

  • Поиск магазинов по категориям
  • Отображение витрины всех продавцов

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

Сущность Назначение
Shop Магазин
SellerProfile Владелец магазина
LegalProfile Юр. лицо, использующееся в магазине
ShopCategory Категория магазина

📄 TODO / Идеи

  • Добавить аватар магазина
  • Публичный рейтинг, отзывы
  • Поддержка мульти-языка
  • Фильтрация по городу, категории
  • Если магазин оффлайн/гибрит сделать поле physical_address - обязательным