# API — качество и DX (OpenAPI, ошибки, корреляция) ## OpenAPI / Swagger - UI: **`GET /api/v1/docs`**, JSON-схема: **`GET /api/v1/docs-json`**. - В проде выключено по умолчанию; включить — `ENABLE_SWAGGER=true` (вне прод-режима включено). - Авторизация в UI — кнопкой Authorize (Bearer JWT), `persistAuthorization` включён. - Контроллеры размечены `@ApiTags` (группировка) и `@ApiBearerAuth` (защищённые). - Схемы DTO обогащаются плагином `@nestjs/swagger` (подключён в `nest-cli.json`). ## Единый формат ошибок Глобальный фильтр `common/filters/all-exceptions.filter.ts` отдаёт по всему API: ```json { "statusCode": 400, "error": "Bad Request", "message": "...", "path": "/api/v1/...", "method": "POST", "requestId": "uuid", "timestamp": "ISO-8601" } ``` 5xx логируются со стеком и `requestId`. ## Корреляция запросов (request-id) `common/middleware/request-id.middleware.ts`: входящий `X-Request-Id` (если валиден) или сгенерированный UUID кладётся в `req.id` и в заголовок ответа `X-Request-Id`; попадает в тело ошибки. ## Усиление валидации Глобальный `ValidationPipe` — `whitelist: true, forbidNonWhitelisted: true, transform: true` (неизвестные поля в теле запроса отклоняются → 400). ## Пробы здоровья - `GET /api/v1/health` — liveness (без БД, без лимита). - `GET /api/v1/health/ready` — readiness: `SELECT 1` к БД; 503 при недоступности. ## Пагинация и формат списков Единый помощник `common/pagination.ts`: `clampPage(limit, offset)` (limit ∈ [1,100], def 20; offset ≥ 0) и `paginated(items, total, limit, offset)`. Списковые эндпоинты возвращают единый конверт: ```json { "items": [ ... ], "total": 123, "limit": 20, "offset": 0 } ``` Приведены к формату: `GET /staff/applications` (+`unread`), `GET /staff/dorm-applications`, `GET /staff/tickets`, `GET /programs` (публичный каталог — теперь с пагинацией+total), `GET /admin/programs`. Фильтры (`status`, `level`, `language`, `active`) сохранены и комбинируются с `limit`/`offset`.