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.
This commit is contained in:
sdarbinyan
2026-07-10 13:10:35 +04:00
parent 86de2cc45b
commit aed0a47388
37 changed files with 1257 additions and 77 deletions

View File

@@ -24,6 +24,10 @@
- attributes
- stockStatus
- rating
- media
- specificationGroups
- variantOptions
- relatedCollections
## Product Engagement Models
- RatingSummary
@@ -41,6 +45,26 @@
- 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 }`
## Строгие правила
- Цена и валюта должны передаваться как валидная пара.
- Скрытые товары не участвуют в публичных витринах.
@@ -63,7 +87,35 @@
"images": [
{ "url": "https://cdn.example.com/items/7812/main.jpg", "isMain": true }
],
"badges": ["featured", "new"]
"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]
}
]
}
```
@@ -76,3 +128,4 @@
- Возвращать актуальные цены и доступность.
- Стабильно поддерживать идентификаторы товаров.
- Предоставлять медиа и атрибуты в согласованном формате.
- Поддерживать обратную совместимость: новые поля опциональны, старые payload остаются валидными.