Introduce docs/features/ with an index (conventions + feature registry), a per-feature template, and a filled cart example. Reference the structure from the root CLAUDE.md so context can be restored per feature on demand. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
3.9 KiB
Markdown
60 lines
3.9 KiB
Markdown
# Cart — корзина
|
||
|
||
## Назначение
|
||
|
||
Корзина покупателя в SPA (Telegram Mini App): отдаёт текущее содержимое корзины с
|
||
посчитанными ценами/итогами, принимает набор позиций из SPA и наполняет ими корзину
|
||
OpenCart перед оформлением заказа. Создание самого заказа — за пределами фичи (см.
|
||
[order](../order/CLAUDE.md), если описан).
|
||
|
||
## Точки входа
|
||
|
||
| action | Метод | Где объявлен |
|
||
|------------|-------------------------|------------------|
|
||
| `getCart` | `CartHandler::index` | `src/routes.php` |
|
||
| `checkout` | `CartHandler::checkout` | `src/routes.php` |
|
||
|
||
> `storeOrder` (`OrderHandler::store`) относится к оформлению заказа, не к корзине.
|
||
|
||
## Ключевые файлы по слоям
|
||
|
||
- **Handler:** `module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/CartHandler.php`
|
||
— `index()` возвращает содержимое корзины, `checkout()` принимает позиции из SPA
|
||
(`productId`, `quantity`, `options`) и кладёт их в корзину через `Cart\Cart::add()`.
|
||
- **Service:** `module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/CartService.php`
|
||
— `getCart()` собирает данные через OpenCart-реестр (`OcRegistryDecorator`): язык
|
||
`checkout/cart`, проверки стока, веса, цен, форматирование через `Cart\Currency`.
|
||
- **OpenCart-зависимости:** `Cart\Cart`, `Cart\Currency` — нативные классы OpenCart,
|
||
внедряются через DI.
|
||
- **Фронтенд (SPA):**
|
||
- `frontend/spa/src/stores/CartStore.js` — Pinia-стор корзины.
|
||
- `frontend/spa/src/ShoppingCart.js` — клиентская логика корзины.
|
||
- `frontend/spa/src/views/Cart.vue` — экран корзины.
|
||
- `frontend/spa/src/components/CartButton.vue` — кнопка/индикатор.
|
||
|
||
## Поток данных
|
||
|
||
**Просмотр:** SPA → `action=getCart` → `CartHandler::index` → `CartService::getCart()`
|
||
читает корзину из OpenCart-реестра → ответ оборачивается `Utf8Cleaner::clean()` →
|
||
`JsonResponse { data }`.
|
||
|
||
**Передача в оформление:** SPA отправляет массив позиций → `action=checkout` →
|
||
`CartHandler::checkout` маппит `options` (берёт `product_option_value_id`) и для каждой
|
||
позиции вызывает `$cart->add(productId, quantity, options)` → возвращает очищенные позиции.
|
||
|
||
## Связанные фичи
|
||
|
||
- Оформление заказа (`OrderHandler::store` / `OrderCreateService`).
|
||
- Настройки (`SettingsService`) влияют на отображение цен/стока в `getCart`.
|
||
|
||
## Нюансы и подводные камни
|
||
|
||
- **PHP 7.4.** Без синтаксиса 8.0+ (см. корневой `CLAUDE.md`).
|
||
- **Весь вывод чистится `App\Support\Utf8Cleaner::clean()`** перед отдачей — невалидный
|
||
UTF-8 из товаров OpenCart ломает `json_encode`.
|
||
- **`getCart` зависит от состояния OpenCart-сессии и реестра** (сток, валюта, логин
|
||
покупателя, язык `checkout/cart`) — это не чистая функция, результат меняется от конфига
|
||
магазина (`config_stock_checkout`, `config_customer_price`, `config_cart_weight` и т.д.).
|
||
- **`checkout` мутирует корзину OpenCart** (`Cart\Cart::add`), а не локальное состояние —
|
||
он переносит выбор из SPA в нативную корзину OpenCart.
|