# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

TeleCart — коммерческий модуль для OpenCart, превращающий магазин в Telegram Mini App. Это монорепозиторий из трёх
частей:

- **PHP-модуль OpenCart** — `module/oc_telegram_shop/upload/` (вся бизнес-логика и собственный фреймворк).
- **SPA** — `frontend/spa/` (Telegram Mini App, витрина для покупателей).
- **Admin** — `frontend/admin/` (панель управления настройками модуля).

`src/` в корне — это распакованная установка OpenCart (генерируется скриптами, **не редактировать**; код модуля
«линкуется» в неё через `make link`).

## Где живёт код модуля

Сердце проекта — `module/oc_telegram_shop/upload/oc_telegram_shop/` (далее «корень модуля»). Его структура:

| Каталог                | Namespace                     | Назначение                                                                                                                  |
|------------------------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| `framework/`           | `Openguru\OpenCartFramework\` | Собственный Laravel-подобный фреймворк: Container (DI), Router, QueryBuilder, Cache, Migrations, Telegram, Http, Translator |
| `src/`                 | `App\`                        | API витрины/SPA (catalog). Handlers, Services, Models, DTO, Filters, ServiceProviders                                       |
| `bastion/`             | `Bastion\`                    | API админ-панели. Handlers, Services, Tasks, ScheduledTasks                                                                 |
| `console/`             | `Console\`                    | CLI-команды (Symfony Console), точка входа `upload/cli.php`                                                                 |
| `database/migrations/` | —                             | Миграции БД                                                                                                                 |
| `configs/`             | —                             | `app.php`, `maintenance.php`, `schedule.php`                                                                                |
| `tests/`               | `Tests\`                      | `Unit/`, `Integration/`, `Telegram/`                                                                                        |

**Маршрутизация.** Запросы приходят через action-параметр и резолвятся по двум картам:

- `src/routes.php` — действия SPA (`products`, `getCart`, `checkout`, `webhook`, …)
- `bastion/routes.php` — действия админки (`getSettingsForm`, `getTelegramCustomers`, `getDashboardStats`, …)

Каждая запись — `'actionName' => [HandlerClass::class, 'method']`.

**Точки входа OpenCart** (тонкие обёртки, грузят autoload и поднимают `App\ApplicationFactory`):

- `module/.../upload/catalog/controller/extension/tgshop/handle.php` — SPA API
- `module/.../upload/admin/controller/extension/module/tgshop.php` — админка

В продакшене модуль собирается в `oc_telegram_shop.phar` и подключается из `system/library/oc_telegram_shop/`; в dev —
из исходников через `vendor/autoload.php`.

## Архитектурные правила (бэкенд)

Паттерн — MVC-L поверх собственного фреймворка. Соблюдай строго:

- **Совместимость с PHP 7.4.** Минимальные требования OpenCart и модуля — PHP 7.4 (`composer.json`: `^7.4`). Не используй синтаксис и функции PHP 8.0+ (named arguments, `match`, constructor property promotion, `enum`, `readonly`, nullsafe `?->`, union types и т.п.).
- **Dependency Injection через конструктор.** Никогда не создавай зависимости через `new` внутри классов — внедряй их.
  Регистрация сервисов идёт в Service Providers (`src/ServiceProviders/`) через `$this->app->singleton(...)`.
- **Query Builder вместо сырого SQL.** Используй `$this->builder->newQuery()->from(...)->where(...)->get()`. Прямой
  SQL — только в крайних случаях; никогда не конкатенируй значения в запрос (SQL injection).
- **Слои:** Handler (валидация + вызов сервиса + `JsonResponse`) → Service (бизнес-логика) → Model (доступ к данным). Не
  смешивай.
- **Строгая типизация:** `declare(strict_types=1)`, типы аргументов и возвращаемых значений, nullable где нужно. PSR-12.
- **Безопасный доступ к массивам:** `Arr::get($data, 'key', $default)` вместо `$data['key']`.
- **Таблицы:** префикс OpenCart (`oc_`) + собственные таблицы модуля.

## Архитектура фронтенда

Оба приложения — Vue 3, **только `<script setup>` + Composition API**, Pinia (setup-stores), Vue Router.

- **SPA** (`frontend/spa/`): Tailwind CSS, FormKit, Swiper, `ofetch`. Сборка →
  `module/.../upload/image/catalog/tgshopspa/`. Тесты — Vitest.
- **Admin** (`frontend/admin/`): PrimeVue (основной UI-кит), Tailwind/DaisyUI, axios, CodeMirror, `vuedraggable`.
  Сборка → `module/.../upload/admin/view/javascript/telecart/`.

Конвенции: компоненты — PascalCase, файлы логики — camelCase; обработчики событий с префиксом `handle`; `computed` для
производных значений; `??` (не `||`) для дефолтов чисел/булевых; сложную логику выносить в composables. Ошибки API
ловить и показывать через toast (admin: `useToast` из PrimeVue).

**FormBuilder** (admin) — отдельная подсистема визуального конструктора форм. Единственный источник истины — FormKit
Schema JSON (без промежуточных DTO). Drag-and-drop строго на `vuedraggable` (не `@formkit/drag-and-drop`).
Tailwind-классы там идут с префиксом `tw:`.

## Команды

Все `make`-цели выполняются **внутри Docker-контейнера `web`** — нужен запущенный `docker compose`.

**Старт / окружение:**

```bash
make setup      # первичная установка: скачать OpenCart, установить, поднять, link
make start      # поднять контейнеры
make dev        # link + параллельно vite dev для SPA и Admin
make dev-spa    # только SPA (vite)
make dev-admin  # только Admin (vite)
make link       # «слинковать» код модуля в установку OpenCart (после правок структуры)
make ssh        # шелл в контейнер в каталоге модуля
```

**Тесты (PHP, PHPUnit в контейнере):**

```bash
make test               # все тесты (--testdox)
make test-unit          # tests/Unit
make test-integration   # tests/Integration
make test-telegram      # tests/Telegram
make test-coverage      # HTML-покрытие в coverage/
```

Запуск одного теста — через ssh в контейнер:

```bash
make ssh
./vendor/bin/phpunit --filter testMethodName tests/Unit/SomeTest.php
```

**Тесты фронтенда (SPA):** `cd frontend/spa && npm run test` (Vitest), `npm run test:run` для однократного прогона.

**Линтеры / статический анализ:**

```bash
make lint     # PHPStan (level 1) по src, bastion, framework, console
make phpcs    # PHP_CodeSniffer PSR-12 (проверка)
make phpcbf   # PHP_CodeSniffer PSR-12 (автофикс)
```

Admin-фронтенд: `cd frontend/admin && npm run lint` (oxlint + eslint), `npm run format` (prettier).

**Сборка / релиз:**

```bash
make phar       # собрать oc_telegram_shop.phar (через docker/build.dockerfile)
make ocmod      # применить OCMOD-модификации
make cli ARGS="..."  # запустить console-команду модуля
make changelog  # сгенерировать CHANGELOG из conventional commits
make release    # changelog + commit релиза
```

## Коммиты

Используются **Conventional Commits** (`feat:`, `fix:`, `chore:`, `build(deps):` …) — CHANGELOG и версии генерируются
автоматически. **Не делать `git commit`/`git push` без явного указания пользователя.**
