Skip to content

feat(web-api): нормализовать контракт ответа корзины - #600

Open
Ibochkarev wants to merge 1 commit into
betafrom
feat/issue-570-cart-response-contract
Open

feat(web-api): нормализовать контракт ответа корзины#600
Ibochkarev wants to merge 1 commit into
betafrom
feat/issue-570-cart-response-contract

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

Web API корзины (GET /api/v1/cart/get и мутации add/change/change-option/remove/clean) отдаёт стабильный JSON для Nuxt.

В data появляется items: всегда массив, в том числе [] для пустой корзины. Скидки (old_price, discount_price, discount_cost) лежат на позиции, не только в properties. status сохраняет те же ключи: счётчики как int, деньги с round 2, вес с round 3.

Итоги товаров по-прежнему считает CartItemManager::calculateStatus. Доставка, оплата и финальная сумма остаются на GET /api/v1/order/cost. Opt-in include_thumbs=1 подмешивает thumb одним batch-запросом по msProductData.

Пустой data.cart теперь JSON-объект {}, не []. Клиенты с Array.isArray(cart) нужно перевести на items или на object/array dual. Непустой cart по-прежнему map по product_key (legacy toArray, включая order_id).

Тип изменений

  • Новая функциональность (non-breaking change)
  • Исправление бага (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Пустой cart: []cart: {} может затронуть клиентов, которые ждут массив. Подробности в заметках ниже.

Связанные Issues

Closes #570

Как это было протестировано?

Локальный CI-гейт (без полной установки MODX/MySQL), PHP lint + vueManager jobs из .github/workflows/ci.yml:

cd core/components/minishop3
composer ci:php
# exit 0
# php -l: 609 files
# smoke: 88 OK (включая CartResponseContractTest)
# PHPUnit: 244 tests, 538 assertions, 9 skipped (@group mysql), 2 deprecations

composer stan
# exit 0, No errors

npm run lint:ci не запускался: Vue не менялся.

  • Ручное тестирование
  • Автоматические тесты (composer ci:php / composer test, npm run lint:ci, composer stan / GitHub Actions CI)
  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: ветка feat/issue-570-cart-response-contract от beta
  • MODX: не поднимался (unit/smoke)
  • PHP: 8.4.17

Скриншоты (если применимо)

Не применимо (JSON API).

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en)
  • PHPStan проходит без новых ошибок (composer stan / CI job PHPStan)
  • ESLint проходит без ошибок (npm run lint:ci для Vue)
  • Обновлён CHANGELOG.md (для значимых изменений)

Лексиконы и Vue не затрагивались. CHANGELOG по правилам репозитория пишется при релизе.

Дополнительные заметки

Проекция живёт в CartResponseNormalizer на границе Web API. Draft и CartItemManager не переписывались. События msOnGetCart / msOnGetStatusCart и SSR render на месте.

ApiClient.buildUrl копирует ?query рядом с route и ctx. Иначе include_thumbs попадал внутрь route и не доходил до PHP.

Вне scope: include_order_costs=1, tax/VAT, Manager cart API.

Ревью: 1 цикл правок (query thumbs + пустые options как {} + bool-флаг на HTTP-границе). Deferred: sanitizing order_id в legacy data.cart (AC оставляет map ближе к toArray).

Nuxt получает стабильный items[] и типизированный status без клиентского reduce. Пустой cart сериализуется как объект, скидки вынесены на позицию.
@Ibochkarev Ibochkarev added priority: medium Средний приоритет enhancement New feature or request labels Aug 18, 2026
@Ibochkarev
Ibochkarev requested a review from biz87 August 18, 2026 03:57
@biz87

biz87 commented Aug 18, 2026

Copy link
Copy Markdown
Member

Проверил: сам контракт сделан аккуратно — старый ключ cart сохранён как map ({} для пустой корзины), items добавлен рядом как всегда-массив. Ровно то, чего требовал RFC про {} vs [], обратная совместимость витрины не ломается. Конфликтов с beta нет.

Но нужен ребейз: после вливания #595 (journey suite) PHPUnit даёт 5 ошибок.

Error: Call to a member function normalize() on null
  at src/Controllers/Api/Web/CartController.php:276

Причина — гонка, а не баг в коде: CartController::transformResponse() резолвит ms3_cart_response_normalizer из DI, а тестовый контейнер journey (tests/Integration/WebApi/Support/*) о нём не знает — там регистрируются лексиконы и ms3_customer_order, нового сервиса нет, поэтому services->get() возвращает null.

В самом ядре регистрация на месте (ServiceRegistry:296, ServiceRegistryFactories:101), обычные тесты зелёные (smoke 90) — падает только journey.

Достаточно добавить ms3_cart_response_normalizer в харнесс journey (или подменить его стабом, если в suite не нужен полноценный нормализатор).

Заодно предупреждение на весь оставшийся пакет: #598 и #599 сейчас тоже конфликтуют с beta — все P1-PR пересекаются в ServiceRegistry/ServiceRegistryFactories и ProductController. Возможно, проще ребейзнуть их одной серией после каждого вливания, чем по одному.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: medium Средний приоритет

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Web API: нормализовать контракт ответа корзины (cart/get) для headless

2 participants