Files
marketplaces/docs/platform/10-product-domain.md
sdarbinyan aed0a47388 feat(product): add reusable Product Experience 2.0
Unify product details modules behind config-driven contracts so teams can
extend UX without changing runtime architecture or bootstrap flow.

Keep backward compatibility with existing product payloads by treating new
media/specification/variant/related structures as optional extensions.

Improve conversion and content discoverability with reusable actions,
typed media rendering, grouped specifications, dynamic variants, and
multi-collection related products.
2026-07-10 13:10:35 +04:00

4.8 KiB

10. Домен товаров

Назначение

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

Поведение системы

  • Товары загружаются по API для листинга, карточки и связанных коллекций.
  • Frontend отображает только те поля, которые есть в контракте.
  • Бизнес-правила доступности товара приходят из backend.

Обязательные JSON-свойства товара

  • itemID
  • name
  • price
  • currency
  • categoryID
  • visible

Опциональные свойства

  • discount
  • images
  • badges
  • simpleDescription
  • attributes
  • stockStatus
  • rating
  • media
  • specificationGroups
  • variantOptions
  • relatedCollections

Product Engagement Models

  • RatingSummary
    • average: number
    • totalReviews: number
    • distribution: [{ stars, count, share }]
  • Review
    • id, rating, title, text, author, anonymous, verifiedPurchase, createdAt
    • likes/dislikes placeholders
    • photos: string[] (reserved for future uploads)
  • Question
    • id, text, author, createdAt, likes, dislikes
    • answers: Answer[]
  • Answer
    • id, text, author, createdAt
    • isOfficialSeller, isAccepted

Product Experience 2.0 Optional Contracts

  • media: [{ type, url, thumbnailUrl?, alt?, title?, labels? }]
    • type: image | video | pdf | manual | warranty
    • frontend renderer picks viewer by type
  • specificationGroups: [{ key, label?, labels?, attributes: [{ key, value, label?, labels?, unit? }] }]
    • supports grouped specifications and translated labels
  • variantOptions: [{ key, label?, labels?, options: [{ value, label?, labels?, available? }] }]
    • supports arbitrary variant groups (color, size, storage, etc.)
  • relatedCollections: [{ id, title, titles?, products: number[] }]
    • supports multiple related collections from backend

Product Page Config Extensions

productPage optional config additions:

  • reviews.mode: pages | load-more
  • questions.allowSubmission: boolean
  • actions: { enabled, addToCart, buyNow, wishlist, compare, share, notifyMe }

Строгие правила

  • Цена и валюта должны передаваться как валидная пара.
  • Скрытые товары не участвуют в публичных витринах.
  • categoryID должен ссылаться на существующую категорию.
  • Виджет не изменяет товарные данные, только отображает.
  • Frontend feature-слой работает только через ProductFacade.
  • DTO/API shape не импортируется в feature components.
  • reviews/questions не хранятся в bootstrap, только их feature-конфиг.

Пример JSON товара

{
  "itemID": 7812,
  "name": "Laptop Pro 14",
  "price": 129990,
  "currency": "RUB",
  "categoryID": 55,
  "visible": true,
  "discount": 10,
  "images": [
    { "url": "https://cdn.example.com/items/7812/main.jpg", "isMain": true }
  ],
  "badges": ["featured", "new"],
  "media": [
    { "type": "image", "url": "https://cdn.example.com/items/7812/main.jpg" },
    { "type": "video", "url": "https://cdn.example.com/items/7812/demo.mp4" },
    { "type": "pdf", "url": "https://cdn.example.com/items/7812/spec.pdf" }
  ],
  "specificationGroups": [
    {
      "key": "display",
      "labels": { "en": "Display", "ru": "Экран" },
      "attributes": [
        { "key": "size", "value": "14", "unit": "inch" },
        { "key": "resolution", "value": "2880x1800" }
      ]
    }
  ],
  "variantOptions": [
    {
      "key": "storage",
      "options": [{ "value": "256GB" }, { "value": "512GB" }]
    }
  ],
  "relatedCollections": [
    {
      "id": "similar-products",
      "title": "Похожие товары",
      "products": [9030, 9031]
    }
  ]
}

Ответственность Frontend

  • Показывать корректную цену, скидку, бейджи и доступность.
  • Поддерживать переход из листинга в карточку товара.
  • Учитывать locale/currency из tenant-конфигурации.

Ответственность Backend

  • Возвращать актуальные цены и доступность.
  • Стабильно поддерживать идентификаторы товаров.
  • Предоставлять медиа и атрибуты в согласованном формате.
  • Поддерживать обратную совместимость: новые поля опциональны, старые payload остаются валидными.