From 7f73343f3fff07f45a0f2dde2d88dd7c4b790e3e Mon Sep 17 00:00:00 2001 From: Nikita Kiselev Date: Tue, 30 Jun 2026 12:00:11 +0300 Subject: [PATCH] docs: replace cursor rules with CLAUDE.md Migrate project guidance from .cursor/ to a single CLAUDE.md covering architecture, backend/frontend conventions, commands and PHP 7.4 constraint. Co-Authored-By: Claude Opus 4.8 (1M context) --- .cursor/agents.md | 64 ---- .cursor/config.json | 44 --- .cursor/features/telecart-pulse-heartbeat.md | 38 -- .cursor/prompts/api-generation.md | 128 ------- .cursor/prompts/changelog.md | 106 ------ .cursor/prompts/documentation.md | 62 ---- .cursor/prompts/refactoring.md | 88 ----- .cursor/prompts/testing.md | 53 --- .cursor/rules/architecture.md | 201 ---------- .cursor/rules/form-builder.md | 70 ---- .cursor/rules/javascript.md | 332 ----------------- .cursor/rules/php.md | 243 ------------ .cursor/rules/vue.md | 370 ------------------- CLAUDE.md | 136 +++++++ 14 files changed, 136 insertions(+), 1799 deletions(-) delete mode 100644 .cursor/agents.md delete mode 100644 .cursor/config.json delete mode 100644 .cursor/features/telecart-pulse-heartbeat.md delete mode 100644 .cursor/prompts/api-generation.md delete mode 100644 .cursor/prompts/changelog.md delete mode 100644 .cursor/prompts/documentation.md delete mode 100644 .cursor/prompts/refactoring.md delete mode 100644 .cursor/prompts/testing.md delete mode 100644 .cursor/rules/architecture.md delete mode 100644 .cursor/rules/form-builder.md delete mode 100644 .cursor/rules/javascript.md delete mode 100644 .cursor/rules/php.md delete mode 100644 .cursor/rules/vue.md create mode 100644 CLAUDE.md diff --git a/.cursor/agents.md b/.cursor/agents.md deleted file mode 100644 index ce5bd81b..00000000 --- a/.cursor/agents.md +++ /dev/null @@ -1,64 +0,0 @@ -# Cursor AI Agents Configuration - -## Роли и правила поведения ИИ - -### Основная роль: Senior Full-Stack Developer - -Вы - опытный full-stack разработчик, специализирующийся на: - -- OpenCart модульной разработке -- Кастомных фреймворках (OpenCart Framework) -- PHP 7.4+ с современными практиками -- Vue.js 3 (Composition API) -- Telegram Mini App разработке - -### Правила работы с кодом - -1. **Всегда используй существующие паттерны проекта** -2. **Не создавай дубликаты - используй существующие утилиты** -3. **Следуй соглашениям именования проекта** -4. **Тестируй изменения перед коммитом** -5. **Документируй публичные API** -6. **Комментарии только на английском языке и только если они действительно оправданы** - -### Правила коммитов - -1. **Следование Conventional Commits** - - Используй префиксы: `feat:`, `fix:`, `chore:`, `refactor:`, `style:`, `test:`, `docs:` - - Формат: `: ` (первая строка до 72 символов) - - После пустой строки - подробное описание изменений - -2. **Язык коммитов** - - Все коммиты на **английском языке** - - Подробное описание изменений в теле коммита - - Перечисляй все измененные файлы и ключевые изменения - -3. **Примеры правильных коммитов** - ``` - feat: add setting to control category products button visibility - - - Add show_category_products_button field to StoreDTO - - Update SettingsSerializerService to support new field - - Add setting in admin panel on 'Store' tab with toggle - - Pass setting to SPA through SettingsHandler - - Button displays only for categories with child categories - - Add default value true to configuration - ``` - -### Запрещено - -- Хардкод значений (используй конфиги/настройки) -- Игнорирование обработки ошибок -- Создание циклических зависимостей - -Для разработки FrontEnd используй: - -- Vue.js 3 (Composition API) -- Старайся избегать функций watch там, где это возможно и где можно сделать более красиво. -- Для frontend/admin используй Tailwind 4 с префиксом `tw:`. -- Для frontend/spa используй Tailwind 4 без префикса. -- Для frontend/admin используй иконки от FontAwesome 4, потому что это уже встроено в OpenCart 3. -- Для frontend/admin используй компоненты VuePrime 4. -- Для frontend/spa используй Daisy UI. -- Чтобы получить название стандартной таблицы OpenCart, используй хелпер `db_table`, либо добавляй константу DB_PREFIX перед названием таблицы. Так ты получишь название таблицы с префиксом. -- Все таблицы моего модуля TeleCart начинаются с префикса `telecart_`. Примеры миграций лежат в `module/oc_telegram_shop/upload/oc_telegram_shop/database/migrations` diff --git a/.cursor/config.json b/.cursor/config.json deleted file mode 100644 index c7970c62..00000000 --- a/.cursor/config.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "rules": { - "preferCompositionAPI": true, - "strictTypes": true, - "noHardcodedValues": true, - "useDependencyInjection": true - }, - "paths": { - "telecart_module": "module/oc_telegram_shop/upload/oc_telegram_shop", - "frontendAdmin": "frontend/admin", - "telegramShopSpa": "frontend/spa", - "migrations": "module/oc_telegram_shop/upload/oc_telegram_shop/database/migrations", - "telecartHandlers": "module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers", - "adminHandlers": "module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers", - "models": "module/oc_telegram_shop/upload/oc_telegram_shop/src/Models", - "framework": "module/oc_telegram_shop/upload/oc_telegram_shop/framework" - }, - "naming": { - "classes": "PascalCase", - "methods": "camelCase", - "variables": "camelCase", - "constants": "UPPER_SNAKE_CASE", - "files": "PascalCase for classes, kebab-case for others", - "tables": "snake_case with telecart_ prefix" - }, - "php": { - "version": "7.4+", - "preferVersion": "7.4+", - "psr12": true - }, - "javascript": { - "version": "ES2020+", - "framework": "Vue 3 Composition API", - "stateManagement": "Pinia", - "uiLibrary": "PrimeVue (admin), Tailwind (spa)" - }, - "database": { - "queryBuilder": true, - "migrations": true, - "tablePrefix": "telecart_", - "noForeignKeys": true - } -} - diff --git a/.cursor/features/telecart-pulse-heartbeat.md b/.cursor/features/telecart-pulse-heartbeat.md deleted file mode 100644 index 05200676..00000000 --- a/.cursor/features/telecart-pulse-heartbeat.md +++ /dev/null @@ -1,38 +0,0 @@ -## TeleCart Pulse Heartbeat Telemetry - -### Цель -Раз в час отправлять телеметрию (heartbeat) на TeleCart Pulse, чтобы фиксировать состояние магазина и версии окружения без участия пользователя. - -### Backend (`module/oc_telegram_shop/upload/oc_telegram_shop`) -- `framework/TeleCartPulse/TeleCartPulseService.php` - - Новый метод `handleHeartbeat()` собирает данные: домен (через `Utils::getCurrentDomain()`), username бота (через `TelegramService::getMe()`), версии PHP, модуля (из `composer.json`), OpenCart (`VERSION` и `VERSION_CORE`), текущий UTC timestamp. - - Последний успешный пинг кешируется (ключ `telecart_pulse_heartbeat`, TTL 1 час) через существующий `CacheInterface`. - - Подпись heartbeat выполняется через отдельный `PayloadSigner`, который использует секрет `pulse.heartbeat_secret`/`PULSE_HEARTBEAT_SECRET`. Логируются предупреждения при ошибках кеша/бота/подписи. - - Отправка идет на эндпоинт `heartbeat` с таймаутом 2 секунды и заголовком `X-TELECART-VERSION`, взятым из `composer.json`. -- `framework/TeleCartPulse/TeleCartPulseServiceProvider.php` - - Регистрирует основной `PayloadSigner` (по `pulse.api_key`) и отдельный heartbeat signer (по `pulse.heartbeat_secret` или `PULSE_HEARTBEAT_SECRET`), инжектит `LoggerInterface`. -- `src/Handlers/TelemetryHandler.php` + `src/routes.php` - - Добавлен маршрут `heartbeat`, который вызывает `handleHeartbeat()` и возвращает `{ status: "ok" }`. Логгер пишет warning при проблемах. - -### Frontend (`frontend/spa`) -- `src/utils/ftch.js`: новая функция `heartbeat()` вызывает `api_action=heartbeat`. -- `src/stores/Pulse.js`: добавлен action `heartbeat`, использующий новую API-функцию и логирующий результат. -- `src/main.js`: после `pulse.ingest(...)` вызывается `pulse.heartbeat()` без блокировки цепочки. - -### Конфигурация / ENV -- `PULSE_API_HOST` — базовый URL TeleCart Pulse (используется и для events, и для heartbeat). -- `PULSE_TIMEOUT` — общий таймаут HTTP (для heartbeat принудительно 2 секунды). -- `PULSE_HEARTBEAT_SECRET` (или `pulse.heartbeat_secret` в настройках) — общий секрет для подписания heartbeat. Обязателен, иначе heartbeat не будет отправляться. -- `pulse.api_key` — прежний API ключ, используется только для event-инджеста. - -### Поведение -1. Frontend (SPA) вызывает `heartbeat` при инициализации приложения (fire-and-forget). -2. Backend проверяет кеш. Если часа еще не прошло, `handleHeartbeat()` возвращает без запросов. -3. При необходимости собираются данные, подписываются через heartbeat signer и отправляются POST-запросом на `/heartbeat`. -4. Любые сбои (bot info, подпись, HTTP) логируются как warning, чтобы не тревожить пользователей. - -### TODO / Возможные улучшения -- При необходимости вынести heartbeat запуск в крон/CLI, чтобы не зависеть от фронтенда. -- Добавить метрики успешности heartbeat в админку. - - diff --git a/.cursor/prompts/api-generation.md b/.cursor/prompts/api-generation.md deleted file mode 100644 index 68b9fab5..00000000 --- a/.cursor/prompts/api-generation.md +++ /dev/null @@ -1,128 +0,0 @@ -# Промпты для генерации API - -## Создание нового API endpoint - -``` -Создай новый API endpoint [ENDPOINT_NAME] для [DESCRIPTION]: - -1. Handler в [HANDLER_PATH]: - - Метод handle() принимает Request - - Валидация входных данных - - Использование Service для бизнес-логики - - Возврат JsonResponse с правильной структурой - - Обработка ошибок с логированием - -2. Service в [SERVICE_PATH]: - - Бизнес-логика - - Работа с Model - - Валидация данных - - Обработка исключений - -3. Model в [MODEL_PATH] (если нужен): - - Методы для работы с БД - - Использование Query Builder - - Типизация методов - -4. Route в routes.php: - - Добавь маршрут с правильным именем - -5. Миграция (если нужна новая таблица): - - Создай миграцию в database/migrations/ - - Используй фиксированный префикс telecart_ - - Добавь индексы где необходимо - -Следуй архитектуре MVC-L проекта и используй существующие паттерны. -``` - -## Создание CRUD API - -``` -Создай полный CRUD API для сущности [ENTITY_NAME]: - -1. Handler с методами: - - list() - список с пагинацией и фильтрацией - - get() - получение одной записи - - create() - создание - - update() - обновление - - delete() - удаление - -2. Service с бизнес-логикой для всех операций - -3. Model с методами: - - findAll() - список - - findById() - по ID - - create() - создание - - update() - обновление - - delete() - удаление - -4. DTO для валидации данных - -5. Миграция для таблицы [TABLE_NAME] - -6. Routes для всех endpoints - -Используй серверную пагинацию, фильтрацию и сортировку для list(). -``` - -## Создание Admin API endpoint - -``` -Создай Admin API endpoint [ENDPOINT_NAME] в bastion/Handlers/: - -1. Handler в bastion/Handlers/[HANDLER_NAME].php: - - Используй Request для получения параметров - - Валидация данных - - Работа через Service - - Возврат JsonResponse с структурой { data: { data: [...], totalRecords: ... } } - - Обработка ошибок - -2. Service в bastion/Services/ (если нужен): - - Бизнес-логика для админки - - Работа с Models - -3. Route в bastion/routes.php - -4. Frontend компонент (если нужен UI): - - Vue компонент в frontend/admin/src/views/ - - Используй PrimeVue компоненты - - Серверная пагинация/фильтрация - - Обработка ошибок с toast уведомлениями - -Следуй существующим паттернам проекта. -``` - -## Создание Frontend API клиента - -``` -Создай функцию для работы с API endpoint [ENDPOINT_NAME]: - -1. В frontend/[admin|spa]/src/utils/http.js: - - Функция api[Method] для вызова endpoint - - Правильная обработка ошибок - - Возврат структурированного ответа - -2. Использование: - - В компонентах через import - - Обработка loading states - - Toast уведомления для ошибок - -Следуй существующим паттернам в http.js. -``` - -## Создание миграции - -``` -Создай миграцию для таблицы [TABLE_NAME]: - -1. Файл: database/migrations/[TIMESTAMP]_[DESCRIPTION].php -2. Используй фиксированный префикс telecart_ для таблицы -3. Добавь все необходимые поля с правильными типами -4. Добавь индексы для часто используемых полей -5. Используй utf8mb4_unicode_ci collation -6. Используй InnoDB engine -7. Добавь created_at и updated_at timestamps -8. Не создавай foreign keys (используй только индексы) - -Следуй структуре существующих миграций. -``` - diff --git a/.cursor/prompts/changelog.md b/.cursor/prompts/changelog.md deleted file mode 100644 index a6daa4ae..00000000 --- a/.cursor/prompts/changelog.md +++ /dev/null @@ -1,106 +0,0 @@ -# Правила оформления Changelog для документации - -## Общие требования - -- **Формат**: Markdown -- **Структура**: Одна версия = одна страница -- **Стиль**: Профессиональный, лаконичный, без маркетинговых лозунгов -- **Язык**: Русский -- **Целевая аудитория**: Разработчики и владельцы магазинов -- **Содержимое**: Только ключевые изменения, без лишних технических деталей - -## Структура страницы - -### Вводный абзац -- Краткое описание релиза (1-2 предложения) -- Дополнить 1-2 предложениями о ключевых изменениях -- Упоминать основные фичи и улучшения - -### Разделы (строго в этом порядке) - -1. **🚀 Добавлено** - новые функции и возможности -2. **✨ Улучшено** - улучшения существующих функций -3. **🐞 Исправлено** - исправленные ошибки -4. **⚠️ Несовместимые изменения** - изменения без обратной совместимости -5. **🔧 Технические изменения** - технические изменения (отдельный раздел) - -### Правила для разделов - -- Раздел **НЕ** добавлять, если в нём нет пунктов -- Использовать маркдаун-списки, без нумерации -- Не добавлять ссылок, если они явно не указаны -- Не добавлять лишних пояснений, выводов и заключений -- Выводить только содержимое Markdown-файла, без комментариев - -## Разделение изменений - -### Бизнес-логика и процессы -Разделы "Добавлено", "Улучшено", "Исправлено", "Несовместимые изменения" содержат только изменения, связанные с: -- Бизнес-процессами магазина -- Пользовательским опытом -- Функциональностью для владельцев магазинов -- Продающими фичами - -### Технические изменения -Все технические изменения выносятся в отдельный раздел **🔧 Технические изменения**: -- Без подразделов, всё в одном списке -- Только самые ключевые технические изменения -- Не расписывать детали, которые не интересны пользователю - -## Стиль написания - -### Терминология -- Английские термины писать по-английски (например: "navbar", а не "навбар") -- Избегать технических терминов в бизнес-разделах (например: "customer_id" → "автоматическое связывание покупателей") - -### Описания - -**Для ключевых продающих фич:** -- Давать подробное описание с деталями -- Указывать возможности и преимущества -- Подчеркивать ценность для пользователя - -**Для технических изменений:** -- Кратко, только ключевое -- Без лишних деталей - -**Для обычных функций:** -- Лаконично, но информативно -- Фокус на пользе для пользователя - -## Порядок размещения - -### В разделе "Добавлено" -Ключевые продающие фичи размещать **первыми**: -1. Система конфигурации главной страницы через блоки -2. Конструктор форм на базе FormKit -3. Интеграция с Яндекс.Метрикой -4. Политика конфиденциальности -5. Поддержка купонов и подарочных сертификатов -6. Остальные функции - -## Примеры правильных формулировок - -### ✅ Хорошо -- "Автоматическое связывание покупателей Telegram с покупателями OpenCart: система автоматически находит и связывает покупателей из Telegram-магазина с существующими покупателями в OpenCart по email или номеру телефона, создавая единую базу клиентов" - -### ❌ Плохо -- "Сохранение customer_id вместе с заказом для связи с клиентами OpenCart: автоматическая связь заказов из Telegram с покупателями в OpenCart, единая база клиентов" - -### ✅ Хорошо -- "Navbar с логотипом и названием приложения" - -### ❌ Плохо -- "Навбар с логотипом и названием приложения" - -## Что не включать - -- Внутренние детали разработки (тесты, статический анализ, обфускация) -- Технические детали, не интересные пользователям -- Избыточные технические описания -- Маркетинговые лозунги и призывы - - - - - diff --git a/.cursor/prompts/documentation.md b/.cursor/prompts/documentation.md deleted file mode 100644 index 33a3c8d1..00000000 --- a/.cursor/prompts/documentation.md +++ /dev/null @@ -1,62 +0,0 @@ -# Промпты для документирования - -## Документирование класса - -``` -Добавь PHPDoc документацию для класса [CLASS_NAME]: -1. Описание класса и его назначения -2. @package тег -3. @author тег -4. Документация для всех публичных методов -5. Документация для публичных свойств -6. Примеры использования где уместно -``` - -## Документирование метода - -``` -Добавь PHPDoc для метода [METHOD_NAME]: -1. Описание метода -2. @param для всех параметров с типами -3. @return с типом возвращаемого значения -4. @throws для всех исключений -5. Примеры использования если сложная логика -``` - -## Документирование API endpoint - -``` -Создай документацию для API endpoint [ENDPOINT_NAME]: -1. Описание назначения -2. HTTP метод и путь -3. Параметры запроса (query/body) -4. Формат ответа (JSON структура) -5. Коды ошибок -6. Примеры запросов/ответов -7. Требования к авторизации -``` - -## Документирование Vue компонента - -``` -Добавь документацию для Vue компонента [COMPONENT_NAME]: -1. Описание компонента -2. Props с типами и описаниями -3. Emits с описаниями -4. Slots если есть -5. Примеры использования -6. Зависимости от других компонентов -``` - -## Создание README - -``` -Создай README.md для [MODULE/COMPONENT]: -1. Описание назначения -2. Установка/настройка -3. Использование с примерами -4. API документация -5. Конфигурация -6. Troubleshooting -``` - diff --git a/.cursor/prompts/refactoring.md b/.cursor/prompts/refactoring.md deleted file mode 100644 index 37f316a1..00000000 --- a/.cursor/prompts/refactoring.md +++ /dev/null @@ -1,88 +0,0 @@ -# Промпты для рефакторинга - -## Общий рефакторинг - -``` -Проанализируй код в файле [FILE_PATH] и выполни рефакторинг: -1. Убери дублирование кода -2. Улучши читаемость -3. Примени принципы SOLID -4. Добавь обработку ошибок где необходимо -5. Улучши типизацию -6. Добавь документацию для публичных методов -7. Убедись что код следует архитектуре MVC-L проекта -8. Используй существующие утилиты и сервисы проекта вместо создания новых -``` - -## Рефакторинг Handler - -``` -Рефакторинг Handler [HANDLER_NAME]: -1. Вынеси бизнес-логику в отдельный Service -2. Добавь валидацию входных данных -3. Улучши обработку ошибок с логированием -4. Используй DTO для передачи данных -5. Добавь PHPDoc комментарии -6. Убедись что используется Dependency Injection -7. Оптимизируй запросы к БД если необходимо -``` - -## Рефакторинг Model - -``` -Рефакторинг Model [MODEL_NAME]: -1. Убедись что все запросы используют Query Builder -2. Добавь методы для частых операций (findBy, findAll, create, update) -3. Добавь валидацию данных перед сохранением -4. Улучши типизацию методов -5. Добавь PHPDoc комментарии -6. Используй транзакции для сложных операций -``` - -## Рефакторинг Vue компонента - -``` -Рефакторинг Vue компонента [COMPONENT_NAME]: -1. Вынеси логику в composable функции -2. Улучши типизацию props и emits -3. Оптимизируй computed properties -4. Добавь обработку ошибок -5. Улучши структуру template -6. Добавь loading states -7. Используй существующие утилиты проекта -``` - -## Удаление дублирования - -``` -Найди и устрани дублирование кода в: -- [FILE_PATH_1] -- [FILE_PATH_2] -- [FILE_PATH_3] - -Создай общие утилиты/сервисы где необходимо, следуя архитектуре проекта. -``` - -## Улучшение производительности - -``` -Проанализируй производительность кода в [FILE_PATH]: -1. Оптимизируй запросы к БД (используй индексы, избегай N+1) -2. Добавь кэширование где уместно -3. Оптимизируй алгоритмы -4. Уменьши количество запросов к API -5. Используй ленивую загрузку на фронтенде -``` - -## Улучшение безопасности - -``` -Улучши безопасность кода в [FILE_PATH]: -1. Добавь валидацию всех входных данных -2. Используй prepared statements (Query Builder) -3. Добавь CSRF защиту где необходимо -4. Валидируй права доступа -5. Санитизируй выходные данные -6. Добавь rate limiting где необходимо -``` - diff --git a/.cursor/prompts/testing.md b/.cursor/prompts/testing.md deleted file mode 100644 index 87cb188d..00000000 --- a/.cursor/prompts/testing.md +++ /dev/null @@ -1,53 +0,0 @@ -# Промпты для тестирования - -## Создание unit теста - -``` -Создай unit тест для [CLASS_NAME] в tests/Unit/: - -1. Используй PHPUnit -2. Покрой все публичные методы -3. Тестируй успешные сценарии -4. Тестируй обработку ошибок -5. Используй моки для зависимостей -6. Следуй структуре существующих тестов -7. Используй TestCase базовый класс проекта -``` - -## Создание integration теста - -``` -Создай integration тест для [FEATURE_NAME] в tests/Integration/: - -1. Тестируй полный flow от запроса до ответа -2. Используй тестовую БД -3. Очищай данные после тестов -4. Тестируй реальные сценарии использования -5. Проверяй валидацию данных -6. Проверяй обработку ошибок -``` - -## Создание Vue компонент теста - -``` -Создай тест для Vue компонента [COMPONENT_NAME] в frontend/[admin|spa]/tests/: - -1. Используй Vitest -2. Тестируй рендеринг компонента -3. Тестируй props -4. Тестируй события (emits) -5. Тестируй пользовательские взаимодействия -6. Используй моки для API вызовов -7. Следуй структуре существующих тестов -``` - -## Покрытие тестами - -``` -Проанализируй покрытие тестами для [FILE_PATH]: -1. Определи какие методы не покрыты тестами -2. Создай тесты для критичных методов -3. Убедись что тестируются граничные случаи -4. Добавь тесты для обработки ошибок -``` - diff --git a/.cursor/rules/architecture.md b/.cursor/rules/architecture.md deleted file mode 100644 index 9464a3e5..00000000 --- a/.cursor/rules/architecture.md +++ /dev/null @@ -1,201 +0,0 @@ -# Архитектурные правила - -## OpenCart Framework Architecture - -### MVC-L Pattern - -Проект использует модифицированный паттерн MVC-L (Model-View-Controller-Language): - -- **Model**: Классы в `src/Models/` - работа с данными, доступ к БД -- **View**: Vue компоненты на фронтенде, JSON ответы на бэкенде -- **Controller**: Handlers в `src/Handlers/` и `bastion/Handlers/` -- **Language**: Переводчик в `framework/Translator/` - -### Dependency Injection - -Все зависимости внедряются через Container: - -```php -// ✅ Правильно -public function __construct( - private Builder $builder, - private TelegramCustomer $telegramCustomerModel -) {} - -// ❌ Неправильно -public function __construct() { - $this->builder = new Builder(...); -} -``` - -### Service Providers - -Регистрация сервисов через Service Providers: - -```php -class MyServiceProvider extends ServiceProvider -{ - public function register(): void - { - $this->app->singleton(MyService::class, function ($app) { - return new MyService($app->get(Dependency::class)); - }); - } -} -``` - -### Routes - -Маршруты определяются в `routes.php`: - -```php -return [ - 'actionName' => [HandlerClass::class, 'methodName'], -]; -``` - -### Handlers (Controllers) - -Handlers обрабатывают HTTP запросы: - -```php -class MyHandler -{ - public function handle(Request $request): JsonResponse - { - // Валидация - // Бизнес-логика через Services - // Возврат JsonResponse - } -} -``` - -### Models - -Models работают с данными: - -```php -class MyModel -{ - public function __construct( - private ConnectionInterface $database, - private Builder $builder - ) {} - - public function findById(int $id): ?array - { - return $this->builder->newQuery() - ->from($this->tableName) - ->where('id', '=', $id) - ->firstOrNull(); - } -} -``` - -### Services - -Services содержат бизнес-логику: - -```php -class MyService -{ - public function __construct( - private MyModel $model - ) {} - - public function doSomething(array $data): array - { - // Бизнес-логика - return $this->model->create($data); - } -} -``` - -### Migrations - -Миграции в `database/migrations/`: - -```php -return new class extends Migration { - public function up(): void - { - $this->database->statement('CREATE TABLE ...'); - } -}; -``` - -### Query Builder - -Всегда используй Query Builder вместо прямых SQL: - -```php -// ✅ Правильно -$query = $this->builder->newQuery() - ->select(['id', 'name']) - ->from('table_name') - ->where('status', '=', 'active') - ->get(); - -// ❌ Неправильно -$result = $this->database->query("SELECT * FROM table_name WHERE status = 'active'"); -``` - -### Frontend Architecture - -#### Admin Panel (Vue 3) - -- Composition API -- Pinia для state management -- PrimeVue для UI компонентов -- Axios для HTTP запросов -- Vue Router для навигации - -#### SPA (Telegram Mini App) - -- Composition API -- Pinia stores -- Tailwind CSS для стилей -- Telegram WebApp API -- Vue Router - -### Naming Conventions - -- **Classes**: PascalCase (`TelegramCustomerService`) -- **Methods**: camelCase (`getCustomers`) -- **Variables**: camelCase (`$customerData`) -- **Constants**: UPPER_SNAKE_CASE (`MAX_RETRIES`) -- **Files**: PascalCase для классов, kebab-case для остального -- **Tables**: snake_case с префиксом `telecart_` - -### Error Handling - -Всегда обрабатывай ошибки: - -```php -try { - $result = $this->service->doSomething(); -} catch (SpecificException $e) { - $this->logger->error('Error message', ['exception' => $e]); - throw new UserFriendlyException('User message'); -} -``` - -### Configuration - -Используй конфигурационные файлы в `configs/`: - -```php -$config = $this->app->getConfigValue('app.setting_name'); -``` - -### Caching - -Используй Cache Service для кэширования: - -```php -$cache = $this->app->get(CacheInterface::class); -$value = $cache->get('key', function() { - return expensiveOperation(); -}); -``` - diff --git a/.cursor/rules/form-builder.md b/.cursor/rules/form-builder.md deleted file mode 100644 index 31b13cf7..00000000 --- a/.cursor/rules/form-builder.md +++ /dev/null @@ -1,70 +0,0 @@ -# FormBuilder System Context - -## Architectural Overview -The FormBuilder ecosystem is a strictly typed Vue 3 application module designed to generate standard FormKit Schema JSON. It eschews internal DTOs in favor of direct schema manipulation. - -### Core Components -1. **FormBuilderView (`views/FormBuilderView.vue`)**: - * **Role**: Smart container / Data fetcher. - * **Responsibility**: Fetches form data from API (`GET /api/admin/forms/{alias}`), handles loading states, and passes data to `FormBuilder`. - * **Contract**: Expects API response `{ data: { schema: Array, is_custom: Boolean, ... } }`. - -2. **FormBuilder (`components/FormBuilder/FormBuilder.vue`)**: - * **Role**: Main Orchestrator / State Owner. - * **Responsibility**: Manages `v-model` (schema), mode switching (Visual/Code/Preview), and provides state to children. - * **State Management**: Uses `defineModel` for `formFields` (schema) and `isCustom` (mode flag). Uses `provide('formFields')` and `provide('selectedFieldId')` for deep dependency injection. - * **Modes**: - * **Visual**: Drag-and-drop interface using `vuedraggable`. - * **Code**: Direct JSON editing of the FormKit schema. Sets `isCustom = true`. - * **Preview**: Renders the current schema using `FormKit`. - -3. **FormCanvas (`components/FormBuilder/FormCanvas.vue`)**: - * **Role**: Visual Editor Surface. - * **Responsibility**: Renders the draggable list of fields. - * **Implementation**: Uses `vuedraggable` bound to `formFields`. - * **UX**: Implements "Ghost" and "Drag" classes for visual feedback. Handles selection logic. - -4. **FieldsPanel (`components/FormBuilder/FieldsPanel.vue`)**: - * **Role**: Component Palette. - * **Responsibility**: Source of truth for available field types. - * **Implementation**: Uses `vuedraggable` with `pull: 'clone', put: false` to spawn new fields. - -5. **FieldSettings (`components/FormBuilder/FieldSettings.vue`)**: - * **Role**: Property Editor. - * **Responsibility**: Edits properties of the `selectedFieldId`. - * **Constraint**: Must use PrimeVue components for all inputs. - -## Data Flow & Invariants -1. **Schema Authority**: The FormKit Schema JSON is the single source of truth. There is no "internal model" separate from the schema. -2. **Reactivity**: - * `formFields` is an Array of Objects. - * Mutations must preserve reactivity. When using `v-model` or `provide/inject`, ensure array methods (splice, push, filter) are used correctly or replace the entire array reference if needed to trigger watchers. - * **Immutability**: `useFormFields` composable uses immutable patterns (returning new array references) to ensure `defineModel` in parent detects changes. -3. **Mode Logic**: - * Switching to **Code** mode sets `isCustom = true`. - * Switching to **Visual** mode sets `isCustom = false`. - * **Safety**: Switching modes triggers JSON validation. Invalid JSON prevents mode switch. -4. **Drag and Drop**: - * Powered by `vuedraggable` (Sortable.js). - * **Clone Logic**: `FieldsPanel` clones from `availableFields`. `FormCanvas` receives the clone. - * **ID Generation**: Unique IDs are generated upon cloning/addition to ensure key stability. - -## Naming & Conventions -* **Tailwind**: Use `tw:` prefix for all utility classes (e.g., `tw:flex`, `tw:p-4`). -* **Components**: PrimeVue components are the standard UI kit (Button, Panel, InputText, etc.). -* **Icons**: FontAwesome (`fa fa-*`). -* **Files**: PascalCase for components (`FormBuilder.vue`), camelCase for logic (`useFormFields.js`). - -## Integration Rules -* **Backend**: The backend stores the JSON blob directly. `FormBuilder` does not transform data before save; it emits the raw schema. -* **API**: `useFormsStore` handles API communication. - -## Pitfalls & Warnings -* **vuedraggable vs @formkit/drag-and-drop**: We strictly use `vuedraggable`. Do not re-introduce `@formkit/drag-and-drop`. -* **Watchers**: Avoid `watch` where `computed` or event handlers suffice, to prevent infinite loops in bidirectional data flow. -* **Tailwind Config**: Do not use `@apply` with `tw:` prefixed classes in ` -``` - -## Component Naming - -```vue - - - - - - - -``` - -## Props - -```vue - -``` - -## Emits - -```vue - -``` - -## Reactive State - -```vue - -``` - -## Computed Properties - -```vue - -``` - -## Event Handlers - -```vue - - - -``` - -## Conditional Rendering - -```vue - -``` - -## Lists - -```vue - -``` - -## Form Handling - -```vue -