Add "Feed"
86
Feed.md
Normal file
86
Feed.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Фид товаров
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
YML-фид каталога товаров загружается с URL из настроек (`feedUrl`). Данные используются для подстановки в Mindbox-теги при рендере превью.
|
||||||
|
|
||||||
|
## Загрузка фида
|
||||||
|
|
||||||
|
Функция `_fetchFeedProducts(feedUrl)`:
|
||||||
|
|
||||||
|
1. Проверка `isPublicUrl(feedUrl)` — блокирует localhost, private IP, IPv6, hex IP
|
||||||
|
2. HTTP GET с таймаутом 90 сек, User-Agent: `AspekterVA-FeedReader/1.0`
|
||||||
|
3. Автодетект кодировки windows-1251 из Content-Type или XML declaration
|
||||||
|
4. Парсинг regex-ом (не DOM) — извлекает `<offer>` элементы
|
||||||
|
|
||||||
|
## Кэширование
|
||||||
|
|
||||||
|
### В памяти
|
||||||
|
- `feedCache` — Map `{url: {ts, products: Map}}`
|
||||||
|
- TTL: 3 часа (`FEED_CACHE_TTL = 3 * 60 * 60 * 1000`)
|
||||||
|
|
||||||
|
### На диске
|
||||||
|
- `data/feed-cache.json` — `{url, ts, products: {id: {...}}}`
|
||||||
|
- Восстанавливается при старте сервера
|
||||||
|
|
||||||
|
### Дедупликация запросов
|
||||||
|
- `feedPending` — Map текущих in-flight запросов
|
||||||
|
- Если запрос уже выполняется, новый подключается к Promise
|
||||||
|
- Stale timeout: 2 минуты (если Promise завис)
|
||||||
|
|
||||||
|
## Поля товара из фида
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
id, available, // идентификатор и наличие
|
||||||
|
name, price, oldPrice, // название, цены
|
||||||
|
image, url, // картинка и ссылка
|
||||||
|
description, // описание
|
||||||
|
categoryId, vendor, // категория и бренд
|
||||||
|
typePrefix, model, // тип товара и модель
|
||||||
|
gender, color, // гендер и цвет
|
||||||
|
discountPercent, // процент скидки
|
||||||
|
// Кастомные поля (из param):
|
||||||
|
denomination, year, dia, material, country,
|
||||||
|
condition, weight, assay, vendorCode,
|
||||||
|
reverseImage, salePercent, series
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## API эндпоинты фида
|
||||||
|
|
||||||
|
### POST /api/project/:name/feed-refresh
|
||||||
|
Принудительная перезагрузка фида:
|
||||||
|
- Очищает кэш
|
||||||
|
- Загружает заново
|
||||||
|
- Возвращает diff: `{added, removed, total}`
|
||||||
|
|
||||||
|
### POST /api/project/:name/feed-lookup
|
||||||
|
Поиск товаров по ID:
|
||||||
|
- Body: `{ids: ["123", "456"]}`
|
||||||
|
- Возвращает: `{found: [{id, name, price, ...}], notFound: ["789"]}`
|
||||||
|
|
||||||
|
### POST /api/project/:name/feed-suggest
|
||||||
|
Замена недоступного товара:
|
||||||
|
- Body: `{productId: "123", limit: 10}`
|
||||||
|
- Алгоритм скоринга:
|
||||||
|
| Фактор | Баллы |
|
||||||
|
|--------|-------|
|
||||||
|
| Тот же бренд (vendor) | +25 |
|
||||||
|
| Тот же тип (typePrefix) | +20 |
|
||||||
|
| Та же категория (categoryId) | +15 |
|
||||||
|
| Тот же гендер | +10 |
|
||||||
|
| Близкая цена | 0-10 |
|
||||||
|
| Тот же цвет | +5 |
|
||||||
|
- Исключаются товары с ценой >3x от оригинала
|
||||||
|
- Возвращает топ-N по скору
|
||||||
|
|
||||||
|
## "Нет в наличии"
|
||||||
|
|
||||||
|
При рендере:
|
||||||
|
1. Mindbox-теги подставляются из фида
|
||||||
|
2. Если товар `available === false` → на картинку накладывается CSS-оверлей
|
||||||
|
3. Список `unavailableProducts[]` возвращается клиенту
|
||||||
|
4. В UI показывается warning: "⚠ Нет в наличии (N) · фид DD.MM HH:MM"
|
||||||
|
5. Клик раскрывает список с кнопками "Заменить" для каждого товара
|
||||||
|
6. "Заменить" → показывает модал с рекомендациями из `feed-suggest`
|
||||||
Reference in New Issue
Block a user