feat(web-api): расширенные фильтры product/list - #580
Conversation
Support parents/nested, price/stock/vendor/flags, and options filters on the public catalog list without raw SQL, with 400 lexicon errors.
COUNT(DISTINCT) with GROUP BY returned per-row counts and broke total when options filters joined multi-value rows. Also harden empty context.
|
Спасибо, реализация аккуратная — парсер/спека/applier разнесены, тесты есть, гейт зелёный. Вопрос не к коду, а к очерёдности. В RFC #577 ты сам зафиксировал порядок:
и там же: Сейчас в Конкретная причина, почему это важно именно для этого PR: он добавляет 12 новых кодов ошибок валидации на публичный endpoint — Предлагаю: сначала #572 (и желательно #576), затем этот PR — при необходимости с косметической правкой формата ошибок под принятый envelope. PR не закрываю, гейт зелёный, вливаем сразу после. Если считаешь, что порядок здесь не критичен и переезд на envelope будет дешёвым — скажи, вольём как есть. |
Описание
Расширяет публичный
GET /api/v1/product/listвалидируемыми фильтрами витрины:parents/nested, цена, stock, vendor, флаги,options. Без сырого SQL от клиента. Без новых параметров поведение как раньше.Тип изменений
Связанные Issues
Closes #564
Refs #565 (facets follow-up), #577 (RFC)
Как это было протестировано?
Конфигурация тестирования:
feat/issue-564-product-list-filtersЧеклист
parent/categoryBC)Дополнительные заметки
Контракт (additive)
parentsmsCategoryMemberчерезCategoryProductScopeServicenested1→ expand tree (depth 10);0→ только перечисленные IDprice_min/price_maxData.price(stored). ПлагиныgetPrice()меняют отображаемую цену в format, не колонку WHEREin_stockData.stock > 0stock_minData.stock >= Nvendor_idINnew/popular/favoriteData.* = 1optionsparent/categoryбезparents— как раньше (один primary parent, без members).Реализация
ProductCatalogFilterParser— pure parse/validateProductCatalogFilterApplier— xPDO WHERE/JOIN +groupby(msProduct.id)при option JOINProductController::getList—ProductCatalogFilterException→ HTTP 400 + lexiconOut of scope
/product/searchgetPrice()