Files
pinecore/.claude/kb/architecture.md
2026-04-06 15:43:45 +03:00

60 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Архитектура и жизненный цикл запроса
## Общая схема
```
HTTP → Caddy (:80) → /worker.php → FrankenPHP worker loop
Kernel::boot($basePath) [один раз при старте]
→ Environment::detect() // читает APP_ENV, дефолт 'dev'
→ Config::load($configDir) // config/*.php + config/env/{env}.php + config/env/local.php
→ ContainerFactory::build() // PHP-DI, в prod компилируется в var/cache/prod/
loop (WorkerRunner::run()):
frankenphp_handle_request(fn() =>
HttpApplication::handleRequest($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER)
→ Request::fromGlobals() // парсит метод, путь, заголовки, JSON body
→ OPTIONS? → CORS headers + 204 // preflight, без роутинга
→ Router::match(method, path) // regex-компиляция {param} → именованные группы
→ 404 / 405+Allow / RouteMatch
→ MiddlewarePipeline::run() // каждый middleware меняет Request через withContext()
→ $controller($request): Response // DI-resolved invokable
→ $response->withHeaders(corsHeaders())->emit()
)
→ HttpApplication::terminate() // хук для закрытия ресурсов (сейчас пустой)
→ gc_collect_cycles()
→ если !$keepRunning или достигнут MAX_REQUESTS — выход из цикла
```
## Карта компонентов
| Файл | Класс | Роль |
|---|---|---|
| `src/Kernel.php` | `Kernel` | Статический bootstrap, хранит контейнер |
| `src/Environment.php` | `Environment` | Читает `APP_ENV`, метод `isProd()` |
| `src/Config.php` | `Config` | Загружает `config/*.php`, deep-merge с env-оверрайдами; `get('a.b.c')` |
| `src/ContainerFactory.php` | `ContainerFactory` | Строит PHP-DI контейнер; в prod включает compilation |
| `src/Http/WorkerRunner.php` | `WorkerRunner` | Цикл FrankenPHP, MAX_REQUESTS, gc |
| `src/Http/HttpApplication.php` | `HttpApplication` | CORS, роутинг, dispatch, обработка исключений |
| `src/Http/Request.php` | `Request` | Иммутабельный; `body()`, `get(key)`, `withContext()` |
| `src/Http/Response.php` | `Response` | `json()`, `error()`, `withHeader()`, `emit()` |
| `src/Http/Router.php` | `Router` | Regex-компиляция маршрутов, возвращает `RouteMatch` |
| `src/Http/MiddlewarePipeline.php` | `MiddlewarePipeline` | Последовательно прогоняет middleware через DI |
| `src/Http/RouteDefinition.php` | `RouteDefinition` | method, path, controller, middleware[] |
| `src/Http/HttpException.php` | `HttpException` | Выбрасывается из любого места → Response::error |
| `src/Auth/AuthMiddleware.php` | `AuthMiddleware` | Bearer JWT → AuthContext в request |
| `src/Auth/JwtService.php` | `JwtService` | HS256, issue/verify, lcobucci/jwt |
| `src/Log/StdoutLogger.php` | `StdoutLogger` | JSON → stdout, PSR-3 |
| `src/Log/FileLogger.php` | `FileLogger` | JSON → файл (если LOG_FILE задан) |
| `src/Orm/AbstractMongoRepository.php` | `AbstractMongoRepository` | persist/findById/delete/findOneWhere |
| `src/Orm/MongoHydrator.php` | `MongoHydrator` | hydrate/dehydrate, поддержка Embedded/EmbeddedList |
| `src/ExceptionHandler.php` | `ExceptionHandler` | Ловит Throwable вне dispatch (critical лог) |
## Обработка исключений в dispatch
В `HttpApplication::dispatch()` ловятся:
- `AuthException` → 401
- `HttpException` → код из исключения
- `\JsonException` → 400 (невалидный JSON body)
- `\Throwable` → логируется, 500
Исключения, вылетающие **за пределы** `handleRequest()` (т.е. до/после dispatch), ловит `ExceptionHandler` в `WorkerRunner`.