diff --git a/.claude/INDEX.md b/.claude/INDEX.md deleted file mode 100644 index 4ebbc4b..0000000 --- a/.claude/INDEX.md +++ /dev/null @@ -1,14 +0,0 @@ -# Pinecore Knowledge Base - -Детальная документация по реализации. См. также [CLAUDE.md](../CLAUDE.md) для базового обзора. - -## Разделы - -- [Архитектура и жизненный цикл запроса](kb/architecture.md) -- [Ядро, Config, Environment, ContainerFactory](kb/bootstrap.md) -- [HTTP слой](kb/http.md) -- [Worker и запуск](kb/worker.md) -- [Аутентификация (JWT)](kb/auth.md) -- [Логирование](kb/logging.md) -- [ORM (MongoDB)](kb/orm.md) -- [Console](kb/console.md) diff --git a/.claude/README.md b/.claude/README.md new file mode 100644 index 0000000..9dfe697 --- /dev/null +++ b/.claude/README.md @@ -0,0 +1,62 @@ +# Knowledge Base Index + +Полный индекс базы знаний проекта Pinecore. Все файлы в этой директории коммитятся в репозиторий. + +## Быстрая навигация + +| Что нужно | Файл | +|-----------|------| +| Я только что открыл проект | [`architecture/overview.md`](architecture/overview.md) | +| Как поднять worker / запустить? | [`development/commands.md`](development/commands.md) | +| Какой паттерн использовать? | [`development/patterns.md`](development/patterns.md) | +| Commit/branch/namespace conventions | [`development/conventions.md`](development/conventions.md) | +| Как отладить локально | [`development/testing.md`](development/testing.md) | +| Ядро, Config, Environment, ContainerFactory | [`architecture/bootstrap.md`](architecture/bootstrap.md) | +| HTTP: Request, Response, Router, Middleware | [`architecture/http.md`](architecture/http.md) | +| Worker и WorkerRunner | [`architecture/worker.md`](architecture/worker.md) | +| Auth (JWT, AuthMiddleware) | [`architecture/auth.md`](architecture/auth.md) | +| Логирование | [`architecture/logging.md`](architecture/logging.md) | +| ORM (MongoDB) | [`architecture/orm.md`](architecture/orm.md) | +| Console-команды | [`architecture/console.md`](architecture/console.md) | +| Почему архитектура именно такая | [`decisions/README.md`](decisions/README.md) | +| Контекст текущей задачи | [`tasks/active/`](tasks/active/) | + +## Структура директории + +``` +.claude/ +├── README.md # Этот файл — индекс +├── architecture/ # Стабильные архитектурные docs +│ ├── overview.md # Обзор системы и жизненный цикл запроса +│ ├── bootstrap.md # Kernel, Config, Environment, ContainerFactory +│ ├── http.md # HTTP слой: Request, Response, Router, Middleware +│ ├── worker.md # Worker entrypoint и WorkerRunner +│ ├── auth.md # Auth: JWT, AuthMiddleware +│ ├── logging.md # Логирование +│ ├── orm.md # ORM: MongoDB, entities, repositories +│ └── console.md # Console-команды +├── development/ # Практика разработки +│ ├── patterns.md # Переиспользуемые code patterns +│ ├── conventions.md # Соглашения: коммиты, ветки, неймспейсы +│ ├── commands.md # Команды запуска и утилиты +│ └── testing.md # Отладка и тестирование +├── decisions/ # Architecture Decision Records (ADR) +│ ├── README.md # Индекс ADR + как писать +│ └── ADR-NNN-*.md +└── tasks/ # Контекст задач (по одному файлу на ветку) + ├── _template.md # Шаблон для новой задачи + ├── active/ # Активные ветки + └── completed/ # Смерженные задачи +``` + +## Правила обновления + +**Во время разработки в feature-ветке:** +- Пиши только в `tasks/active/.md` (свой файл) +- Можешь добавить `decisions/ADR-NNN.md` (новый файл — нет конфликтов) +- НЕ трогай `architecture/` и `development/` — только в main + +**После мержа в main (интегратор):** +- Читает секцию "Merge Notes" в task-файле +- При необходимости обновляет `architecture/` и `development/` +- Перемещает: `tasks/active/.md` → `tasks/completed/.md` diff --git a/.claude/kb/auth.md b/.claude/architecture/auth.md similarity index 100% rename from .claude/kb/auth.md rename to .claude/architecture/auth.md diff --git a/.claude/kb/bootstrap.md b/.claude/architecture/bootstrap.md similarity index 100% rename from .claude/kb/bootstrap.md rename to .claude/architecture/bootstrap.md diff --git a/.claude/kb/console.md b/.claude/architecture/console.md similarity index 100% rename from .claude/kb/console.md rename to .claude/architecture/console.md diff --git a/.claude/kb/http.md b/.claude/architecture/http.md similarity index 100% rename from .claude/kb/http.md rename to .claude/architecture/http.md diff --git a/.claude/kb/logging.md b/.claude/architecture/logging.md similarity index 100% rename from .claude/kb/logging.md rename to .claude/architecture/logging.md diff --git a/.claude/kb/orm.md b/.claude/architecture/orm.md similarity index 100% rename from .claude/kb/orm.md rename to .claude/architecture/orm.md diff --git a/.claude/kb/architecture.md b/.claude/architecture/overview.md similarity index 100% rename from .claude/kb/architecture.md rename to .claude/architecture/overview.md diff --git a/.claude/kb/worker.md b/.claude/architecture/worker.md similarity index 100% rename from .claude/kb/worker.md rename to .claude/architecture/worker.md diff --git a/.claude/decisions/README.md b/.claude/decisions/README.md new file mode 100644 index 0000000..77a001f --- /dev/null +++ b/.claude/decisions/README.md @@ -0,0 +1,34 @@ +# Architecture Decision Records (ADR) + +Здесь хранятся записи об архитектурных решениях. Помогают понять **почему** код устроен именно так. + +## Индекс + +| ADR | Название | Статус | +|-----|----------|--------| +| — | Пока нет ADR | — | + +## Как писать ADR + +Создай новый файл `ADR-NNN-brief-title.md` (NNN = следующий номер) с таким шаблоном: + +```markdown +# ADR-NNN: Краткое название + +## Status +Accepted + +## Context +Какая проблема стояла. Какие альтернативы рассматривались. + +## Decision +Что решили. + +## Consequences +Что это даёт. Что ограничивает. +``` + +**Правила**: +- ADR — только **новые файлы**. Существующие ADR не правятся (только Status меняется на "Superseded by ADR-XXX"). +- Добавляй ADR прямо из feature-ветки — это не вызывает конфликтов. +- После мержа — обновить этот индекс (строка в таблице). diff --git a/.claude/development/commands.md b/.claude/development/commands.md new file mode 100644 index 0000000..9f0c7fc --- /dev/null +++ b/.claude/development/commands.md @@ -0,0 +1,56 @@ +# Commands Reference + +## Запуск worker + +FrankenPHP стартует PHP-воркеры через Caddyfile: + +```bash +frankenphp run --config Caddyfile +``` + +Воркер-скрипт приложения подключается к фреймворку через `WorkerRunner`: + +```php +// worker.php +$runner = new WorkerRunner($kernel); +$runner->run(); +``` + +--- + +## Console-команды + +```bash +php bin/console [options] +``` + +Команды регистрируются в контейнере как сервисы с тегом (см. `architecture/console.md`). + +--- + +## Composer + +```bash +composer install # Установить зависимости из lock +composer update # Обновить зависимости +composer dump-autoload # Пересоздать autoloader +``` + +--- + +## Docker (если используется в приложении) + +```bash +docker compose up -d # Запустить сервисы +docker compose build # Пересобрать образ +docker compose logs -f # Логи в реальном времени +``` + +--- + +## Git shortcuts + +```bash +# Создать task-файл для новой ветки +cp .claude/tasks/_template.md .claude/tasks/active/.md +``` diff --git a/.claude/development/conventions.md b/.claude/development/conventions.md new file mode 100644 index 0000000..f525600 --- /dev/null +++ b/.claude/development/conventions.md @@ -0,0 +1,75 @@ +# Conventions + +## Commit Messages + +``` +[type] Краткое описание в imperative form +``` + +Примеры: +- `Add autoload for routes and services` +- `Fix missing CORS config exception` +- `Refactor WorkerRunner startup sequence` + +--- + +## Branch Naming + +| Тип | Паттерн | Пример | +|-----|---------|--------| +| Feature | `feature/description` | `feature/jwt-refresh` | +| Fix | `fix/description` | `fix/cors-header` | +| Refactor | `refactor/description` | `refactor/kernel-bootstrap` | +| Knowledge base / tooling | `kebab-case` | `knowledge-base` | + +--- + +## PHP Namespaces + +| Компонент | Namespace | +|-----------|-----------| +| Core | `Pronchev\Pinecore\` | +| HTTP | `Pronchev\Pinecore\Http\` | +| Auth | `Pronchev\Pinecore\Auth\` | +| ORM | `Pronchev\Pinecore\Orm\` | +| Log | `Pronchev\Pinecore\Log\` | +| Console | `Pronchev\Pinecore\Console\` | +| Model | `Pronchev\Pinecore\Model\` | + +--- + +## File & Class Naming + +- PSR-4: файл = имя класса, PascalCase (`WorkerRunner.php` содержит `class WorkerRunner`) +- Атрибуты ORM: PascalCase (`#[Collection]`, `#[Field]`) +- Interfaces: суффикс `Interface` (`MiddlewareInterface`) + +--- + +## Работа с задачами (.claude/tasks/) + +При старте новой ветки: +```bash +cp .claude/tasks/_template.md .claude/tasks/active/.md +``` + +Правила: +1. Во время разработки — редактируй только свой task-файл +2. Можно добавить `decisions/ADR-NNN.md` (новый файл — нет конфликтов) +3. Не трогай `architecture/` и `development/` — только в main + +При мерже в main: +- Читай секцию "Merge Notes" в task-файле +- Обновляй стабильные docs если нужно +- Перемести: `tasks/active/.md` → `tasks/completed/.md` + +--- + +## Когда писать ADR + +Создай `decisions/ADR-NNN-title.md` когда: +- Вводится новый архитектурный паттерн +- Принято нетривиальное решение (и кто-то может спросить "почему так?") +- Отвергнута очевидная альтернатива + +ADR — только новые файлы, никогда не правь существующие. diff --git a/.claude/development/patterns.md b/.claude/development/patterns.md new file mode 100644 index 0000000..b7459fd --- /dev/null +++ b/.claude/development/patterns.md @@ -0,0 +1,111 @@ +# Code Patterns + +Переиспользуемые паттерны кодовой базы. Используй существующие — не изобретай новые без необходимости. + +--- + +## 1. Kernel — статический контейнер + +```php +// Инициализация (один раз при старте воркера) +Kernel::init($container); + +// Получение сервиса +$service = Kernel::getContainer()->get(MyService::class); +``` + +Kernel хранит единственный инстанс контейнера на весь процесс воркера. + +--- + +## 2. ContainerFactory — сборка контейнера + +```php +$factory = new ContainerFactory($config, $environment); +$container = $factory->build(); +``` + +Autoload: все файлы из `routes/` и `services/` подхватываются автоматически. +Не регистрируй маршруты и сервисы вручную в `index.php` — кладёт файлы в соответствующие директории. + +--- + +## 3. Router и RouteDefinition + +```php +// routes/api.php +return [ + new RouteDefinition('GET', '/users/{id}', UserController::class, 'show'), +]; +``` + +Router находит нужный маршрут по методу и пути, извлекает параметры и вызывает контроллер. + +--- + +## 4. Middleware — цепочка обработки запроса + +```php +class MyMiddleware implements MiddlewareInterface { + public function handle(Request $request, callable $next): Response { + // до + $response = $next($request); + // после + return $response; + } +} +``` + +Middleware регистрируются в контейнере и применяются ко всем запросам в воркере. + +--- + +## 5. ORM — атрибуты сущностей + +```php +#[Collection('users')] +class UserEntity { + #[Field('_id')] + public string $id; + + #[Field('name')] + public string $name; +} +``` + +Repository наследует базовый класс и получает методы `find`, `findOne`, `save`, `delete` из коробки. + +--- + +## 6. JWT Auth + +```php +// AuthMiddleware автоматически валидирует Bearer-токен +// В контроллере — получить текущего пользователя из request +$user = $request->getAttribute('user'); +``` + +`JwtService` отвечает за выпуск и верификацию токенов. Конфиг: секрет и TTL через `Config`. + +--- + +## 7. Config — конфигурация + +```php +$value = Config::get('key'); +$value = Config::get('section.key', $default); +``` + +Конфиг загружается из `environment.php` (или `.env`). Доступен глобально через статический метод. + +--- + +## 8. WorkerRunner — цикл обработки запросов + +```php +// Внутри worker.php +$runner = new WorkerRunner($kernel); +$runner->run(); // FrankenPHP loop: запрос → роутинг → middleware → контроллер → ответ +``` + +`WorkerRunner` перехватывает исключения и возвращает корректный HTTP-ответ даже при ошибке. diff --git a/.claude/development/testing.md b/.claude/development/testing.md new file mode 100644 index 0000000..5b94369 --- /dev/null +++ b/.claude/development/testing.md @@ -0,0 +1,61 @@ +# Testing & Debugging + +## Запуск воркера локально + +```bash +frankenphp run --config Caddyfile +``` + +Убедись, что переменные окружения заданы (`.env` или `environment.php`). + +--- + +## Отладка запросов + +Включи подробное логирование через конфиг: + +```php +Config::get('log.level') // DEBUG для максимального вывода +``` + +Логи пишутся через `LoggerInterface` (Monolog). Смотри `architecture/logging.md` для деталей. + +--- + +## Частые проблемы + +### Воркер не стартует + +- Проверь синтаксис `Caddyfile` и путь до `worker.php` +- FrankenPHP требует `FRANKENPHP_CONFIG` или явного указания воркер-скрипта +- Проверь, что `Kernel::init()` вызван до первого запроса + +### Маршрут не найден (404) + +- Убедись, что файл с `RouteDefinition` лежит в `routes/` (autoload подхватывает автоматически) +- Проверь HTTP-метод и путь: параметры вида `{id}` чувствительны к паттерну + +### JWT не валидируется + +- Проверь, что `Config::get('auth.secret')` не пустой +- Убедись, что `AuthMiddleware` зарегистрирован в контейнере +- Время жизни токена — `Config::get('auth.ttl')` + +### Ошибка CORS + +- `CorsMiddleware` требует явного конфига (список разрешённых origins) +- Если конфиг не задан — бросается `RuntimeException` при старте + +### MongoDB не подключается + +- Проверь DSN в конфиге: `Config::get('mongodb.dsn')` +- Проверь, что MongoDB-сервис запущен и доступен из воркера + +--- + +## Инспекция контейнера + +```php +// В dev-режиме: посмотреть все зарегистрированные сервисы +$ids = Kernel::getContainer()->getServiceIds(); +``` diff --git a/.claude/tasks/_template.md b/.claude/tasks/_template.md new file mode 100644 index 0000000..2d27d61 --- /dev/null +++ b/.claude/tasks/_template.md @@ -0,0 +1,42 @@ +# Task: Краткое название + +## Branch +`branch-name` + +## Status + +In Progress + +## Objective +Что и зачем делается. Один абзац: проблема, решение, ожидаемый результат. + +## Scope +- [ ] Компонент/файл A +- [ ] Компонент/файл B + +## Approach +Технические решения, принятые для этой задачи. +Ссылки на файлы архитектуры (например: `.claude/architecture/http.md`). + +## Files Changed + +- `src/...` — что изменено + +## Patterns Used / Introduced + + +- Использован: `WorkerRunner` (см. `.claude/development/patterns.md`) + +## Decisions & Gotchas + + + +## Testing Done + + +## Merge Notes + + +- [ ] Обновить `.claude/architecture/...` +- [ ] Обновить `.claude/development/...` +- [ ] Добавить `decisions/ADR-NNN.md` для [решения] diff --git a/.claude/tasks/active/knowledge-base.md b/.claude/tasks/active/knowledge-base.md new file mode 100644 index 0000000..2af9ebc --- /dev/null +++ b/.claude/tasks/active/knowledge-base.md @@ -0,0 +1,10 @@ +# Task: привести базу знаний к структуре из другого проекта. + +## Branch +`knowledge-base` + +## Status +In Progress + +## Objective +В репозитории /home/pronchev/source/bitbucket.pltrm.net/trends выработана система накопления базы знаний о проекте и механизм развития проекта с параллельным поддержание базы знаний в актуальном состоянии. Нужно перенести принципы работы и структуру базы знаний в текущий проект. diff --git a/.claude/tasks/completed/.gitkeep b/.claude/tasks/completed/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/CLAUDE.md b/CLAUDE.md index 895a477..801c5fe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,16 +12,16 @@ No lint or test commands configured yet. ## Knowledge base -Detailed implementation docs: [.claude/INDEX.md](.claude/INDEX.md) +Full index: [.claude/README.md](.claude/README.md) -- [Architecture & request lifecycle](.claude/kb/architecture.md) -- [Bootstrap: Kernel, Config, Environment, ContainerFactory](.claude/kb/bootstrap.md) -- [HTTP layer: Request, Response, Router, Middleware](.claude/kb/http.md) -- [Worker entrypoint & WorkerRunner](.claude/kb/worker.md) -- [Auth: JWT, AuthMiddleware](.claude/kb/auth.md) -- [Logging](.claude/kb/logging.md) -- [ORM: MongoDB, entities, repositories](.claude/kb/orm.md) -- [Console](.claude/kb/console.md) +- [Architecture & request lifecycle](.claude/architecture/overview.md) +- [Bootstrap: Kernel, Config, Environment, ContainerFactory](.claude/architecture/bootstrap.md) +- [HTTP layer: Request, Response, Router, Middleware](.claude/architecture/http.md) +- [Worker entrypoint & WorkerRunner](.claude/architecture/worker.md) +- [Auth: JWT, AuthMiddleware](.claude/architecture/auth.md) +- [Logging](.claude/architecture/logging.md) +- [ORM: MongoDB, entities, repositories](.claude/architecture/orm.md) +- [Console](.claude/architecture/console.md) ## Code Style