# 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 товара ```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 остаются валидными.