docs: add docs/features scaffold for feature documentation

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>
This commit is contained in:
2026-06-30 13:33:37 +03:00
parent ed9d2c1b1f
commit d621baae45
4 changed files with 151 additions and 0 deletions

View File

@@ -14,6 +14,17 @@ TeleCart — коммерческий модуль для OpenCart, превра
`src/` в корне — это распакованная установка OpenCart (генерируется скриптами, **не редактировать**; код модуля `src/` в корне — это распакованная установка OpenCart (генерируется скриптами, **не редактировать**; код модуля
«линкуется» в неё через `make link`). «линкуется» в неё через `make link`).
## Документация по фичам (`docs/features/`)
Контекстная документация хранится в `docs/features/` — по одной поддиректории на фичу, внутри индексный
`CLAUDE.md`. Вложенные `CLAUDE.md` Claude Code подхватывает автоматически при чтении файлов из их директории,
поэтому индекс фичи читается «по требованию», когда работа касается этой фичи.
Перед тем как трогать незнакомую часть системы — загляни в её папку в `docs/features/`. Конвенции, шаблон новой
фичи и **реестр всех фич с прямыми путями** — в [`docs/features/CLAUDE.md`](docs/features/CLAUDE.md). Шаблон для
новой фичи — `docs/features/_TEMPLATE.md`. При изменении фичи поддерживай её доку в актуальном состоянии (код —
источник истины; при расхождении правь доку).
## Где живёт код модуля ## Где живёт код модуля
Сердце проекта — `module/oc_telegram_shop/upload/oc_telegram_shop/` (далее «корень модуля»). Его структура: Сердце проекта — `module/oc_telegram_shop/upload/oc_telegram_shop/` (далее «корень модуля»). Его структура:

43
docs/features/CLAUDE.md Normal file
View File

@@ -0,0 +1,43 @@
# docs/features — документация по фичам
Эта директория хранит описания **фич** проекта TeleCart: по одной поддиректории на фичу.
Цель — дать агенту (и человеку) возможность быстро восстановить контекст по конкретной
части системы, не перечитывая весь код: что фича делает, через какие точки входит, какие
файлы за неё отвечают и как данные текут по слоям.
Вложенные `CLAUDE.md` подхватываются Claude Code автоматически при чтении файлов из их
директории — поэтому индекс фичи читается «по требованию», когда работа касается этой фичи.
## Структура
```
docs/features/
├── CLAUDE.md # этот файл: конвенции + реестр фич
├── _TEMPLATE.md # шаблон для новой фичи (копировать при описании)
└── <feature-slug>/
└── CLAUDE.md # индексный файл конкретной фичи
```
## Конвенции
- **Имя папки** — `kebab-case`, по сути фичи: `cart`, `telegram-webhook`, `form-builder`.
- **Один индекс на фичу** — `<feature-slug>/CLAUDE.md`, заполняется по `_TEMPLATE.md`.
- **Ссылки на код — обязательны.** Указывай реальные пути (`module/.../src/Handlers/CartHandler.php`)
и `action` из карт маршрутов. Код — источник истины; документация лишь навигирует к нему.
- **Не дублируй код.** Описывай назначение, поток и нюансы, а не построчный пересказ — он устареет.
- **Связывай фичи** через ссылки на их папки (например `[checkout](../checkout/CLAUDE.md)`).
- Если описанное в доке расходится с кодом — прав код; обнови доку.
## Как добавить фичу
1. `cp _TEMPLATE.md <feature-slug>/CLAUDE.md` (создав папку).
2. Заполни секции шаблона, опираясь на реальный код.
3. Добавь строку в реестр ниже.
## Реестр фич
| Фича | Путь | Краткое описание |
|------|----------------------------------|-------------------------------------------------------------|
| cart | [cart/CLAUDE.md](cart/CLAUDE.md) | Корзина: наполнение, просмотр, передача в оформление заказа |
<!-- Новые фичи добавляй строкой в таблицу выше, по алфавиту. -->

View File

@@ -0,0 +1,38 @@
# <Название фичи>
> Скопируй этот файл в `docs/features/<feature-slug>/CLAUDE.md` и заполни секции.
> Удали подсказки в кавычках после заполнения. Не оставляй пустых «TODO».
## Назначение
> 13 предложения: какую задачу решает фича и для кого (SPA-покупатель / админ / системное).
## Точки входа
> `action` из карт маршрутов и где они объявлены. Таблица:
| action | Метод | Где объявлен |
|-----------------|-------------------|-------------------------------------------|
| `exampleAction` | `Handler::method` | `src/routes.php` или `bastion/routes.php` |
## Ключевые файлы по слоям
> Путь от корня репозитория. Только то, что реально относится к фиче.
- **Handler:** `module/.../src/Handlers/XxxHandler.php` — валидация, вызов сервиса, `JsonResponse`.
- **Service:** `module/.../src/Services/XxxService.php` — бизнес-логика.
- **Model / данные:** `module/.../src/Models/Xxx.php` или таблицы БД.
- **Фронтенд:** `frontend/spa/...` или `frontend/admin/...` (store, view, компоненты).
- **Регистрация в DI:** `src/ServiceProviders/...` (если есть нестандартная привязка).
## Поток данных
> Кратко: запрос → слои → ответ. Можно списком шагов или стрелками.
## Связанные фичи
> Ссылки на соседние папки: `[checkout](../checkout/CLAUDE.md)`.
## Нюансы и подводные камни
> Неочевидное: ограничения PHP 7.4, особенности OpenCart-реестра, кэш, edge-cases, известные баги.

View File

@@ -0,0 +1,59 @@
# 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.