{"openapi":"3.1.0","info":{"title":"Rukki Identity Service — core PostgreSQL API v1","description":"Микросервис аутентификации и авторизации через SMS.ru и Firebase для платформы Rukki 5.0, а также создание и обновление JWT-токенов (access/refresh)\n\n**Группа core-v1** — канонический REST API identity-service: пользователи и роли в **PostgreSQL**, локальная выдача JWT, Firebase-идентичности, JWKS.\n\n**REST API v1 (PostgreSQL, core-v1):**\n- `/api/v1/users` — пользователи (GET list/count/{id}, `/me` — self-service)\n- `/api/v1/roles` — справочник ролей (GET list/count/{id})\n- `/api/v1/auth` — аутентификация (Call Flow, Telegram, OAuth2 refresh, logout)\n- `/api/v1/identities` — Firebase-идентичности и устройства\n- `/.well-known/jwks.json` — публичный JWKS; `/api/v1/auth/keys/rotate`, `/api/v1/auth/tokens/revoke` — админ-операции с ключами и отзывом JWT\n\n\n**1. Аутентификация по звонку (Call Flow STOMP) (основная):** Главным методом входа в **Rukki 5.0** является бесплатный звонок-сброс (Call Auth) через интеграцию с SMS.RU.\n\n**Как это работает:**\n1. Клиент запрашивает сессию звонка (`POST /api/v1/auth/call`), передавая номер в поле `phone` (10–15 цифр, префикс `+` необязателен: `+79991234567` или `79991234567`).\n2. Сервер возвращает сервисный номер телефона `call_phone` (на который нужно позвонить) и уникальный ID сессии `checkId`.\n3. Клиент подписывается на WebSocket STOMP канал `/topic/auth-status/core/{checkId}` и ждет.\n4. Пользователь совершает бесплатный гудок-сброс на предоставленный номер `call_phone`.\n5. SMS.RU принимает звонок и присылает Webhook на скрытый эндпоинт.\n6. Наш бэкенд мгновенно проверяет статус, генерирует пару JWT (`access_token`, `refresh_token`, `rukki_id`, …) и пушит `TokenResponseV1` в WebSocket (STOMP) клиенту.\n\nДля наглядного (интерфейсного) тестирования этого потока через WebSockets, перейдите на специальную страницу: **[ws-login.html](/ws-login.html)**.\n\n**2. Аутентификация через Telegram (Social Login):** Платформа поддерживает вход и регистрацию через официальный виджет Telegram Login.\nДля авторизации передайте данные виджета с криптографической подписью (ID, auth_date, hash) в эндпоинт `POST /api/v1/auth/telegram`. Если пользователь заходит впервые, система автоматически создаст ему профиль и выдаст пару JWT токенов. Для уже авторизованных пользователей (базово по телефону) доступна привязка профиля командой `POST /api/v1/auth/telegram/link`, которая устраняет проблему дублирования аккаунтов.\nДля наглядного тестирования Telegram-авторизации перейдите на страницу: **[tg-login.html](/tg-login.html)**.\n\n\n**3. Локальные JWT (access / refresh) — Call Flow, Telegram, Web/микросервисы:**\n\nПара токенов выдаётся после успешного входа (**STOMP Call Flow**, `POST /api/v1/auth/telegram`) в формате OAuth2 token response (`TokenResponseV1`).\n\n| Токен | Назначение | Где передавать |\n|---|---|---|\n| **access** (`access_token`) | Авторизация API-запросов | Заголовок `Authorization: Bearer <access_token>` |\n| **refresh** (`refresh_token`) | Обновление пары без повторного логина | Только на token endpoint (`/api/v1/auth/token` или `/api/v1/auth/refresh`), **не** в Bearer |\n\n**Access JWT** — короткоживущий (TTL: `expires_in`, сек.), claim `token_type=access`, роли в `realm_access.roles`, идентификатор пользователя в `sub` (UUID) и `rukki_id` в теле ответа при выдаче.\n\n**Refresh JWT** — долгоживущий (`refresh_expires_in`), claim `token_type=refresh`, только для обмена на новую пару. При успешном refresh старый refresh **отзывается (rotation)** — повторное использование того же refresh вернёт `invalid_grant`.\n\n**Обновление пары:**\n- Keycloak/OAuth2: `POST /api/v1/auth/token` (`application/x-www-form-urlencoded`): `grant_type=refresh_token`, `refresh_token`, опционально `client_id`.\n- JSON-алиас: `POST /api/v1/auth/refresh` — тело `{\"refreshToken\":\"...\"}` или `{\"refresh_token\":\"...\"}`, опционально `client_id`.\n\n**Logout:** `POST /api/v1/auth/logout` с Bearer **access** JWT — отзыв текущего access по `jti` (blacklist в Redis до `exp`). В теле можно передать `refreshToken` / `refresh_token` той же сессии — тогда отзывается и refresh. Для полного выхода из Firebase-контура — `POST /api/v1/identities/auth/logout`.\n\n**Валидация токенов сторонними сервисами:** публичный JWKS — `GET /.well-known/jwks.json` (RS256, `kid` в header JWT). Отозванные access/refresh отклоняются по blacklist `jti` на стороне identity-service; другие микросервисы проверяют подпись и claims локально.\n\n**Ошибки token endpoint** — OAuth2-формат: `{\"error\":\"...\", \"error_description\":\"...\"}` (`invalid_grant`, `invalid_client`, `unsupported_grant_type`, `invalid_request`).\n\n\n**4. Интеграция с file-service (Kafka `file.deleted.v1`):**\n- **Назначение:** после удаления файла в file-service снять ссылки в PostgreSQL: `user.avatar_file_id`.\n- **REST:** ссылка задаётся полем `avatarFileId`; проверка существования файла в file-service при create/update **не выполняется**.\n- **Consumer group:** `identity-service-group` (по умолчанию).\n- **Идемпотентность:** таблица `processed_integration_events` по `eventId`. Повторная доставка — no-op.\n\n\n**5. Гео-данные профиля (`geoData` в `GET/PATCH /api/v1/users/{id}`, `PUT/PATCH /api/v1/users/me`):**\n- **Назначение:** 0..N зон обслуживания пользователя — `latitude`, `longitude` (WGS-84, градусы), `radiusMeters` (метры, `BIGINT`, сотни км и более).\n- **Хранение:** PostgreSQL `user_geo_data` — `DOUBLE PRECISION` + расширения `cube`/`earthdistance` (миграция `V16`), **без PostGIS**.\n- **Spatial search:** `nearLatitude`/`nearLongitude`, `coverPoint=true` (зона покрывает точку) или `coverPoint=false` + `maxDistanceMeters` (близость центра); GiST на `ll_to_earth(latitude, longitude)`.\n- **REST:** чтение в `UserResponseV1.geoData`; запись через `PUT /me` (полная замена) или `PATCH` (замена при явной передаче `geoData`); не более 20 зон на пользователя.\n- **Outbox** `USER_PROFILE_UPDATED`: payload включает `geoData` (тот же формат, что REST).\n- **Фильтрация списка** (`GET /api/v1/users`, `GET /api/v1/users/count`): `hasGeoData` (`false` — только без зон, без других гео-параметров), `minRadiusMeters`/`maxRadiusMeters`, bounding box, `nearLatitude`/`nearLongitude`, `coverPoint`, `maxDistanceMeters`.\n\n\n**Авторизация (JWT, локальный issuer identity-service):**\n- Заголовок `Authorization: Bearer <access_token>`.\n- В Swagger UI нажмите **Authorize** и вставьте **только значение токена** (префикс `Bearer` подставляется автоматически).\n  Получить пару токенов: Call Flow ([ws-login.html](/ws-login.html)), Telegram ([tg-login.html](/tg-login.html))\n  или OAuth2 refresh (`POST /api/v1/auth/token`, `/api/v1/auth/refresh`).\n- Роли — claim `realm_access.roles` (см. `/api/v1/roles` и тег **Role API V1**).\n- Идентификатор пользователя — claim `sub` (UUID v4).\n- JWKS: `GET /.well-known/jwks.json` (RS256, `kid` в header JWT); отзыв access — blacklist `jti` в Redis.\n\n\n**Пагинация и сортировка** (`GET /api/v1/users`, `GET /api/v1/roles` и другие списки с `PagedResponse`):\n- Query: `page`, `size`, `sort` (в Swagger — отдельные параметры).\n- **`page`** — номер страницы **с 1** (`page=1` — первая; `page=0` не используется).\n- **`size`** — элементов на странице (по умолчанию из `spring.data.web.pageable.default-page-size`, максимум 100).\n- **`sort`** — `поле,направление` (например `createdAt,desc`); недопустимое поле → **400**.\n- Ответ: `PagedResponse` — `content`, `currentPage` (с 1), `pageSize`, `totalElements`.\n\n| Список | Допустимые поля `sort` |\n|--------|-------------------------|\n| users | `phoneAuth`, `firstName`, `lastName`, `email`, `status`, `createdAt`, `updatedAt` |\n| roles | `name`, `description`, `createdAt`, `updatedAt` |\n\n\n**Модель ролей (JWT):**\n- Справочник — `/api/v1/roles` (PostgreSQL); системные роли защищены от удаления и изменения.\n- **USER** — self-service (`/api/v1/users/me`), базовые операции профиля.\n- **MANAGER, ADMIN, SUPERADMIN** — административное чтение пользователей; мутации — **ADMIN**, **SUPERADMIN**.\n- Назначение ролей — `/api/v1/users/{id}/roles` (Identity API).\n\n\n**Настройки CORS:** Настройки CORS микросервиса загружаются из конфигурации профиля:\n- **Разрешенные домены (Origins):** `https://*.rukki.pro, https://rukki.pro`\n- **Разрешенные HTTP-методы:** `GET, POST, PUT, PATCH, DELETE, OPTIONS`\n- **Разрешенные заголовки:** `*`\n\nSwagger UI автоматически использует текущий домен для выполнения запросов. При развертывании в **Dokploy** параметры (`CORS_ALLOWED_ORIGINS`, `CORS_ALLOWED_METHODS`) задаются в секции **Environment** (значения через запятую, без пробелов).\n\n**Профиль запуска:** prod <br><br><span style=\"color:red\"><b>ВНИМАНИЕ (PROD):</b> В production Swagger должен быть закрыт: установите <i>springdoc.swagger-ui.enabled=false</i> и <i>springdoc.api-docs.enabled=false</i>.</span>\n\n**Build Time:** 2026-06-12T13:31:59.951Z | **Artifact:** identity-service | **Java Version:** 21.0.11 | **OS:** Linux (amd64)","version":"1.0.0-SNAPSHOT"},"servers":[{"url":"https://auth.rukki.pro","description":"Production Server"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Identity API V1","description":"Firebase-идентичности, устройства и административные операции с учётными записями (`/api/v1/identities`).\nПолный logout из Firebase-контура — `POST /api/v1/identities/auth/logout`."},{"name":"JWT API V1","description":"JWKS (`/.well-known/jwks.json`) и администрирование ключей подписи JWT.\nРотация ключа и точечный отзыв — **ADMIN**, **SUPERADMIN**."},{"name":"Role API V1","description":"Управление справочником ролей приложения (`/api/v1/roles`).\nСистемные роли (SUPERADMIN, ADMIN, MANAGER, USER, CUSTOMER, EXECUTOR и др.) защищены от удаления и изменения."},{"name":"User API V1","description":"**Канонический REST API пользователей** под префиксом **`/api/v1/users`** (PostgreSQL).\n\nПоддерживает self-service сценарии (`/me`: просмотр, обновление, удаление учетной записи, управление каналами/категориями уведомлений)\nи административные операции (список пользователей, поиск, изменения по `id`, ban/unban).\n\n**Доступ и роли.** Endpoints `/me/**` доступны любому аутентифицированному пользователю (валидный Bearer access JWT).\nАдминистративное чтение (список, count, GET по id) — **ADMIN**, **SUPERADMIN**, **MANAGER**; мутации — **ADMIN**, **SUPERADMIN**.\n\nПоле `avatarFileId` (UUID в file-service); при удалении файла ссылки снимает Kafka `file.deleted.v1` (см. core-v1 info).\nГео-данные (`geoData`): 0..N точек с координатами и `radiusMeters`; управление через PUT/PATCH профиля."},{"name":"Auth API V1","description":"Аутентификация (Call Flow, Telegram), выдача пары **access/refresh JWT**, обновление токенов и logout.\nAccess передаётся в `Authorization: Bearer`; refresh — только на `POST /token` или `POST /refresh`.\nПодробный сценарий — в описании группы **core-v1** (раздел «Локальные JWT»)."}],"paths":{"/api/v1/auth/webhook/smsru":{"get":{"tags":["Auth API V1"],"summary":"Обработка вебхука от SMS.RU","description":"Принимает асинхронные события от SMS.RU при успешном подтверждении номера (CallCheck). Всегда возвращает строку '100'.","operationId":"handleSmsRuCallWebhook","parameters":[{"name":"payload","in":"query","required":true,"schema":{"type":"object","additionalProperties":{"type":"string"}}}],"responses":{"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Auth API V1"],"summary":"Обработка вебхука от SMS.RU","description":"Принимает асинхронные события от SMS.RU при успешном подтверждении номера (CallCheck). Всегда возвращает строку '100'.","operationId":"handleSmsRuCallWebhook_1","parameters":[{"name":"payload","in":"query","required":true,"schema":{"type":"object","additionalProperties":{"type":"string"}}}],"responses":{"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/users/{id}":{"get":{"tags":["User API V1"],"summary":"Получить детали пользователя по ID","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Возвращает полную информацию о пользователе по его уникальному идентификатору (UUID),\nвключая `avatarFileId` (UUID файла в file-service или отсутствует).","operationId":"findById","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Успешное получение данных пользователя","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["User API V1"],"summary":"Полное обновление пользователя по ID","description":"Доступно: **ADMIN**, **SUPERADMIN**. Полностью перезаписывает персональные данные указанного пользователя\n(имя, фамилия, email, ИНН, телефоны, УКЭП, каналы и категории уведомлений, `avatarFileId`, `geoData`).\n`avatarFileId` — UUID файла в file-service; `null` снимает аватар; `geoData` — `null` или `[]` удаляет все зоны.","operationId":"update","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequestV1"}}},"required":true},"responses":{"200":{"description":"Данные пользователя успешно обновлены","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["User API V1"],"summary":"Частично изменить пользователя по ID","description":"Доступно: **ADMIN**, **SUPERADMIN**. Частично обновляет личную информацию указанного пользователя.\nПоля со значением `null` не меняются. `avatarFileId` (UUID в file-service) устанавливается только при явной передаче UUID;\nснять аватар через PATCH нельзя — используйте PUT с `avatarFileId: null`.","operationId":"partialUpdate","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateUserRequestV1"}}},"required":true},"responses":{"200":{"description":"Данные пользователя успешно обновлены","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/me":{"get":{"tags":["User API V1"],"summary":"Получить данные текущего пользователя","description":"Доступно: Любому авторизованному пользователю. Возвращает полную информацию о текущем авторизованном пользователе\n(UUID из JWT), включая `avatarFileId` (UUID файла в file-service или отсутствует).","operationId":"getMe","responses":{"200":{"description":"Успешное получение данных пользователя","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["User API V1"],"summary":"Полное обновление данных пользователя","description":"Доступно: Любому авторизованному пользователю. Полностью перезаписывает персональные данные текущего пользователя\n(имя, фамилия, email, ИНН, телефон СБП, телефон MAX, ID УКЭП, каналы и категории уведомлений, `avatarFileId`).\n`avatarFileId` — UUID файла в file-service; `null` снимает аватар.","operationId":"updateMe","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequestV1"}}},"required":true},"responses":{"200":{"description":"Данные пользователя успешно обновлены","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["User API V1"],"summary":"Удаление собственной учетной записи","description":"Доступно: Любому авторизованному пользователю. Выполняет безопасное (мягкое) удаление и анонимизацию собственной учетной записи, а также генерирует системное событие USER_DELETED (Outbox) для очистки данных пользователя во всех остальных микросервисах платформы.","operationId":"deleteMe","responses":{"204":{"description":"Учетная запись успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["User API V1"],"summary":"Частичное обновление данных пользователя","description":"Доступно: Любому авторизованному пользователю. Частично обновляет персональные данные пользователя.\nПоля со значением `null` не меняются. `avatarFileId` устанавливается только при явной передаче UUID;\nснять аватар через PATCH нельзя — используйте PUT с `avatarFileId: null`.","operationId":"partialUpdateMe","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateUserRequestV1"}}},"required":true},"responses":{"200":{"description":"Данные пользователя успешно обновлены","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/roles/{id}":{"get":{"tags":["Role API V1"],"summary":"Получить детали роли по ID","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Возвращает полную информацию об указанной роли по её уникальному идентификатору.","operationId":"findById_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор роли","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Успешное получение данных роли","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["Role API V1"],"summary":"Полное редактирование существующей роли","description":"Доступно: ADMIN, SUPERADMIN. Полноценно обновляет название и/или описание существующей роли (PUT). Если поле description не передано, оно затирается.","operationId":"update_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор обновляемой роли","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleRequestV1"}}},"required":true},"responses":{"200":{"description":"Роль успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Role API V1"],"summary":"Удалить существующую роль","description":"Доступно: ADMIN, SUPERADMIN. Удаляет существующую роль из справочника.","operationId":"deleteById","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор удаляемой роли","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Роль успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Role API V1"],"summary":"Частично редактировать существующую роль","description":"Доступно: ADMIN, SUPERADMIN. Частично обновляет название и/или описание существующей роли. Поля, переданные со значением null, игнорируются.","operationId":"partialUpdate_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор обновляемой роли","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateRoleRequestV1"}}},"required":true},"responses":{"200":{"description":"Роль успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/admin/users/{id}/phone-auth":{"put":{"tags":["Identity API V1"],"summary":"Принудительная смена номера телефона","description":"Доступно: ADMIN, SUPERADMIN. Административный эндпоинт. Позволяет принудительно изменить номер телефона (логин) пользователя по RUKKI-ID. Автоматически обновляет номер в базе данных и синхронизирует изменения с провайдером аутентификации.","operationId":"updatePhoneAuth","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePhoneRequestV1"}}},"required":true},"responses":{"200":{"description":"Номер телефона успешно изменен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePhoneAuthResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/{id}/unban":{"post":{"tags":["User API V1"],"summary":"Разблокировка учетной записи пользователя","description":"Доступно: **ADMIN**, **SUPERADMIN**. Разблокирует доступ учетной записи.","operationId":"unbanUser","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Учетная запись успешно разблокирована","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/{id}/ban":{"post":{"tags":["User API V1"],"summary":"Блокировка учетной записи пользователя","description":"Доступно: **ADMIN**, **SUPERADMIN**. Блокирует доступ учетной записи пользователя.","operationId":"banUser","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Учетная запись пользователя успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/me/notification-categories/{category}":{"post":{"tags":["User API V1"],"summary":"Добавить категорию уведомлений","description":"Доступно: любому авторизованному пользователю. Идемпотентно добавляет категорию в конец списка.","operationId":"addNotificationCategoryMe","parameters":[{"name":"category","in":"path","description":"Код категории, например ORDER_CREATED","required":true,"schema":{"type":"string","enum":["ORDER_CREATED"]}}],"responses":{"200":{"description":"Категория добавлена (или уже была в списке)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["User API V1"],"summary":"Удалить категорию уведомлений","description":"Доступно: любому авторизованному пользователю. Идемпотентно удаляет категорию из списка.","operationId":"removeNotificationCategoryMe","parameters":[{"name":"category","in":"path","description":"Код категории","required":true,"schema":{"type":"string","enum":["ORDER_CREATED"]}}],"responses":{"200":{"description":"Категория удалена (или отсутствовала)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/me/channels/{channel}":{"post":{"tags":["User API V1"],"summary":"Добавить канал уведомлений","description":"Доступно: любому авторизованному пользователю. Идемпотентно добавляет канал в конец списка; дубликат не создаётся.","operationId":"addNotificationChannelMe","parameters":[{"name":"channel","in":"path","description":"Канал: EMAIL, SMS, WHATSAPP, MAX, TELEGRAM","required":true,"schema":{"type":"string","enum":["EMAIL","SMS","WHATSAPP","MAX","TELEGRAM"]}}],"responses":{"200":{"description":"Канал добавлен (или уже был в списке)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["User API V1"],"summary":"Удалить канал уведомлений","description":"Доступно: любому авторизованному пользователю. Идемпотентно удаляет канал из списка; отсутствие канала не считается ошибкой.","operationId":"removeNotificationChannelMe","parameters":[{"name":"channel","in":"path","description":"Канал: EMAIL, SMS, WHATSAPP, MAX, TELEGRAM","required":true,"schema":{"type":"string","enum":["EMAIL","SMS","WHATSAPP","MAX","TELEGRAM"]}}],"responses":{"200":{"description":"Канал удалён (или отсутствовал)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/roles":{"get":{"tags":["Role API V1"],"summary":"Получить список ролей (Справочник)","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Возвращает список всех ролей с поддержкой пагинации, сортировки и гибкой фильтрации по полям сущности.","operationId":"all","parameters":[{"name":"name","in":"query","description":"Поиск по подстроке в названии роли (без учета регистра)","required":false,"schema":{"type":"string"}},{"name":"updatable","in":"query","description":"Фильтрация по флагу возможности редактирования","required":false,"schema":{"type":"boolean"}},{"name":"deletable","in":"query","description":"Фильтрация по флагу возможности удаления","required":false,"schema":{"type":"boolean"}},{"name":"page","in":"query","description":"Номер страницы (с 1; первая страница — page=1)","required":false,"schema":{"type":"integer","default":1,"minimum":1},"example":"1"},{"name":"size","in":"query","description":"Размер страницы (по умолчанию 20, макс. 100)","required":false,"schema":{"type":"integer","default":20,"maximum":100,"minimum":1},"example":"20"},{"name":"sort","in":"query","description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","required":false,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"Успешное получение списка ролей","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponseRoleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"post":{"tags":["Role API V1"],"summary":"Создать новую роль","description":"Доступно: ADMIN, SUPERADMIN. Создает новую роль в справочнике. Название роли должно быть уникальным.","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleRequestV1"}}},"required":true},"responses":{"201":{"description":"Роль успешно создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities":{"post":{"tags":["Identity API V1"],"summary":"Создать нового пользователя","description":"Используется для создания пользователя (например, при импорте из CRM или регистрации). Генерирует уникальный RUKKI-ID, сохраняет пользователя в локальную БД и запускает синхронизацию с провайдером аутентификации.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequestV1"}}},"required":true},"responses":{"201":{"description":"Пользователь успешно создан","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/{id}/roles/revoke":{"post":{"tags":["Identity API V1"],"summary":"Отозвать роли у пользователя","description":"Доступно: ADMIN, SUPERADMIN. Массовый отзыв ролей у пользователя (базовую роль USER отозвать нельзя)","operationId":"revokeRoles","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя (RUKKI-ID)","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentRequestV1"}}},"required":true},"responses":{"201":{"description":"Роль успешно отозвана"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/{id}/roles/assign":{"post":{"tags":["Identity API V1"],"summary":"Назначить роли пользователю","description":"Доступно: ADMIN, SUPERADMIN. Массовое назначение ролей пользователю","operationId":"assignRoles","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор пользователя (RUKKI-ID)","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleAssignmentRequestV1"}}},"required":true},"responses":{"201":{"description":"Роли успешно назначены"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/me/phone-change/init":{"post":{"tags":["Identity API V1"],"summary":"Инициация самостоятельной смены номера","description":"Первый шаг процесса смены номера самим пользователем. Подготавливает систему к привязке нового номера телефона.","operationId":"initPhoneChange","responses":{"201":{"description":"Успешно инициировано","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/me/phone-change/confirm":{"post":{"tags":["Identity API V1"],"summary":"Подтверждение смены номера","description":"Второй шаг процесса смены номера. Учитывает новый OTP-токен, проверяет его валидность и переназначает телефон авторизации для пользователя.","operationId":"confirmPhoneChange","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmPhoneChangeRequestV1"}}},"required":true},"responses":{"200":{"description":"Успешная смена номера"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/me/devices":{"post":{"tags":["Identity API V1"],"summary":"Привязка FCM-токена устройства","description":"Добавляет новый FCM-токен в список авторизованных устройств текущего пользователя. Это необходимо для отправки таргетных push-уведомлений.","operationId":"addDeviceToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDeviceTokenRequestV1"}}},"required":true},"responses":{"201":{"description":"Устройство успешно привязано"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Identity API V1"],"summary":"Отвязка FCM-токена устройства","description":"Удаляет указанный токен FCM из списка устройств пользователя. Push-уведомления на это устройство больше не будут доставляться.","operationId":"removeDeviceToken","parameters":[{"name":"fcm_token","in":"query","required":true,"schema":{"type":"string","minLength":1}}],"responses":{"204":{"description":"Токен устройства успешно отвязан/удален"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/auth/verify":{"post":{"tags":["Identity API V1"],"summary":"Верификация токена (Вход в систему)","description":"Основная точка входа. Получает idToken после успешного OTP, проверяет подпись, вшивает Custom Claims (RUKKI-ID и Role). Бэкенд свои JWT не генерирует.","operationId":"verifyAuth","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyAuthRequestV1"}}},"required":true},"responses":{"201":{"description":"Успешный вход","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyAuthResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/auth/logout":{"post":{"tags":["Identity API V1"],"summary":"Полный logout (access + Firebase sessions + FCM)","description":"Выполняет полный выход пользователя: очищает FCM-токены устройств, отзывает refresh-сессии в Firebase,\nотзывает текущий access JWT. Если в теле передан `refreshToken` / `refresh_token` локальной сессии identity-service —\nотзывается и он по `jti`.\nЛёгкий logout без Firebase/FCM — `POST /api/v1/auth/logout`.","operationId":"logout","parameters":[{"name":"tokenValue","in":"query","required":false,"schema":{"type":"string"}},{"name":"issuedAt","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"expiresAt","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutRequestV1"}}}},"responses":{"204":{"description":"Полный logout выполнен"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/admin/users/{id}/unban":{"post":{"tags":["Identity API V1"],"summary":"Разблокировка учетной записи пользователя","description":"Доступно только пользователям с ролями ADMIN и SUPERADMIN. Возвращает статус ACTIVE для профиля и снимает блокировку с учетной записи.","operationId":"unbanUser_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Учетная запись успешно разблокирована"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/admin/users/{id}/ban":{"post":{"tags":["Identity API V1"],"summary":"Блокировка учетной записи пользователя","description":"Доступно только пользователям с ролями ADMIN и SUPERADMIN. Переводит профиль в статус BANNED в локальной БД и отключает учетную запись. Доступ в систему будет немедленно закрыт.","operationId":"banUser_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"201":{"description":"Учетная запись успешно заблокирована"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/auth/tokens/revoke":{"post":{"tags":["JWT API V1"],"summary":"Точечный отзыв JWT по jti","description":"Доступно: **ADMIN**, **SUPERADMIN**. Добавляет jti в Redis blacklist до времени exp.","operationId":"revokeToken","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeTokenRequestV1"}}},"required":true},"responses":{"200":{"description":"Токен успешно отозван","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeTokenResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/auth/token":{"post":{"tags":["Auth API V1"],"summary":"OAuth2 token endpoint (refresh_token grant)","description":"Keycloak-совместимый обмен refresh JWT на новую пару. Публичный endpoint (Bearer не требуется).\nИспользованный refresh отзывается (rotation); параллельный повтор того же refresh вернёт `invalid_grant`.\nОтвет с `Cache-Control: no-store`.","operationId":"refreshTokenGrant","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","description":"Тип grant, поддерживается только `refresh_token`"},"refresh_token":{"type":"string","description":"Компактная строка refresh JWT"},"client_id":{"type":"string","description":"OAuth2 client_id; если не передан — значение из конфигурации JWT"}},"required":["grant_type","refresh_token"]}}}},"responses":{"200":{"description":"Новая пара JWT выдана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"429":{"description":"Rate limit exceeded (`slow_down`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth2TokenErrorResponseV1"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/auth/telegram":{"post":{"tags":["Auth API V1"],"summary":"Авторизация через Telegram","description":"Проверяет данные Telegram Login Widget (HMAC-SHA256) и выдаёт пару JWT (`TokenResponseV1`):\n`access_token`, `refresh_token`, `rukki_id`, `expires_in`, `refresh_expires_in`, `token_type=Bearer`.\nAccess используйте в Bearer; refresh храните securely и обновляйте через `POST /auth/token` или `/auth/refresh`.","operationId":"loginTelegram","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramAuthRequestV1"}}},"required":true},"responses":{"201":{"description":"Успешная авторизация, выдана пара JWT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/auth/telegram/link":{"post":{"tags":["Auth API V1"],"summary":"Привязка Telegram к существующему аккаунту","description":"Позволяет авторизованному пользователю привязать свой профиль Telegram.","operationId":"linkTelegram","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramAuthRequestV1"}}},"required":true},"responses":{"201":{"description":"Успешная привязка"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/auth/refresh":{"post":{"tags":["Auth API V1"],"summary":"Обновление пары JWT (JSON-алиас refresh_token grant)","description":"Эквивалент `POST /api/v1/auth/token` с `grant_type=refresh_token`, но тело в JSON (`RefreshTokenRequestV1`).\nПоля: `refreshToken` или `refresh_token`, опционально `client_id`. Публичный endpoint.","operationId":"refreshTokens","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshTokenRequestV1"}}},"required":true},"responses":{"200":{"description":"Новая пара JWT выдана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"429":{"description":"Rate limit exceeded (`slow_down`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuth2TokenErrorResponseV1"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/auth/logout":{"post":{"tags":["Auth API V1"],"summary":"Легкий logout (отзыв access JWT и опционально refresh)","description":"Требует Bearer **access** JWT (не refresh). Отзывает текущий access по `jti` (Redis blacklist до `exp`).\nЕсли в теле передан `refreshToken` / `refresh_token` той же сессии — отзывается и refresh по его `jti`.\nFCM и Firebase-сессии не затрагиваются; полный выход — `POST /api/v1/identities/auth/logout`.","operationId":"logout_1","parameters":[{"name":"tokenValue","in":"query","required":false,"schema":{"type":"string"}},{"name":"issuedAt","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"expiresAt","in":"query","required":false,"schema":{"type":"string","format":"date-time"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutRequestV1"}}}},"responses":{"204":{"description":"Легкий logout выполнен"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/auth/keys/rotate":{"post":{"tags":["JWT API V1"],"summary":"Принудительная ротация JWT signing key","description":"Доступно: **ADMIN**, **SUPERADMIN**. Немедленно переключает активный RSA-ключ подписи и обновляет kid.","operationId":"rotateJwtSigningKey","responses":{"200":{"description":"Ключ успешно ротирован","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateSigningKeyResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/auth/call":{"post":{"tags":["Auth API V1"],"summary":"Запрос авторизации по звонку (Call Flow)","description":"Возвращает номер телефона, на который пользователь должен позвонить для авторизации (бесплатно для звонящего). В теле поле `phone`: 10–15 цифр, префикс `+` необязателен (например `+79991234567` или `79991234567`).","operationId":"startCallAuth","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallAuthRequestV1"}}},"required":true},"responses":{"201":{"description":"Авторизация успешно инициализирована","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallAuthResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/users":{"get":{"tags":["User API V1"],"summary":"Получить список пользователей","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Возвращает список всех пользователей с поддержкой пагинации, сортировки и гибкой фильтрации по полям сущности.\nКаждый элемент `content` — полный `UserResponseV1`, включая `avatarFileId` и `geoData`.\n**Гео-фильтры** (PostgreSQL earthdistance): `hasGeoData=false` — только пользователи без зон (остальные гео-параметры → 400);\n`minRadiusMeters`/`maxRadiusMeters`, bounding box, `nearLatitude`/`nearLongitude` + `coverPoint` (default `true`) или `maxDistanceMeters` при `coverPoint=false`.\nВсе гео-условия (кроме `hasGeoData=false`) относятся к одной зоне (EXISTS).","operationId":"all_1","parameters":[{"name":"phone","in":"query","description":"Часть номера телефона","required":false,"schema":{"type":"string"}},{"name":"firstName","in":"query","description":"Часть имени","required":false,"schema":{"type":"string"}},{"name":"lastName","in":"query","description":"Часть фамилии","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","description":"Часть email","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Статус пользователя","required":false,"schema":{"type":"string","enum":["LEAD","ACTIVE","BANNED","DELETED"]}},{"name":"hasGeoData","in":"query","description":"Наличие гео-зон: true — есть; false — нет (без других гео-параметров)","required":false,"schema":{"type":"boolean"}},{"name":"minRadiusMeters","in":"query","description":"Минимальный radiusMeters хотя бы у одной зоны","required":false,"schema":{"type":"integer","format":"int64","minimum":1}},{"name":"maxRadiusMeters","in":"query","description":"Максимальный radiusMeters хотя бы у одной зоны","required":false,"schema":{"type":"integer","format":"int64","minimum":1}},{"name":"geoLatitudeMin","in":"query","description":"Минимальная широта центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"geoLatitudeMax","in":"query","description":"Максимальная широта центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"geoLongitudeMin","in":"query","description":"Минимальная долгота центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"geoLongitudeMax","in":"query","description":"Максимальная долгота центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"nearLatitude","in":"query","description":"Широта точки поиска (WGS-84); пара с nearLongitude","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"nearLongitude","in":"query","description":"Долгота точки поиска (WGS-84); пара с nearLatitude","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"coverPoint","in":"query","description":"true — зона покрывает точку (default); false — центр зоны в maxDistanceMeters","required":false,"schema":{"type":"string"},"example":true},{"name":"maxDistanceMeters","in":"query","description":"При coverPoint=false — макс. расстояние до центра зоны (метры)","required":false,"schema":{"type":"integer","format":"int64","minimum":1}},{"name":"page","in":"query","description":"Номер страницы (с 1; первая страница — page=1)","required":false,"schema":{"type":"integer","default":1,"minimum":1},"example":"1"},{"name":"size","in":"query","description":"Размер страницы (по умолчанию 20, макс. 100)","required":false,"schema":{"type":"integer","default":20,"maximum":100,"minimum":1},"example":"20"},{"name":"sort","in":"query","description":"Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","required":false,"schema":{"type":"array","items":{"type":"string"}}}],"responses":{"200":{"description":"Успешное получение списка пользователей","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponseUserResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/users/count":{"get":{"tags":["User API V1"],"summary":"Получить количество пользователей","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Подсчитывает пользователей с учётом фильтра (логика совпадает с методом списка).","operationId":"count","parameters":[{"name":"phone","in":"query","description":"Часть номера телефона","required":false,"schema":{"type":"string"}},{"name":"firstName","in":"query","description":"Часть имени","required":false,"schema":{"type":"string"}},{"name":"lastName","in":"query","description":"Часть фамилии","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","description":"Часть email","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","description":"Статус пользователя","required":false,"schema":{"type":"string","enum":["LEAD","ACTIVE","BANNED","DELETED"]}},{"name":"hasGeoData","in":"query","description":"Наличие гео-зон: true — есть; false — нет (без других гео-параметров)","required":false,"schema":{"type":"boolean"}},{"name":"minRadiusMeters","in":"query","description":"Минимальный radiusMeters хотя бы у одной зоны","required":false,"schema":{"type":"integer","format":"int64","minimum":1}},{"name":"maxRadiusMeters","in":"query","description":"Максимальный radiusMeters хотя бы у одной зоны","required":false,"schema":{"type":"integer","format":"int64","minimum":1}},{"name":"geoLatitudeMin","in":"query","description":"Минимальная широта центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"geoLatitudeMax","in":"query","description":"Максимальная широта центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"geoLongitudeMin","in":"query","description":"Минимальная долгота центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"geoLongitudeMax","in":"query","description":"Максимальная долгота центра гео-зоны (WGS-84)","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"nearLatitude","in":"query","description":"Широта точки поиска (WGS-84); пара с nearLongitude","required":false,"schema":{"type":"number","format":"double","maximum":90.0,"minimum":-90.0}},{"name":"nearLongitude","in":"query","description":"Долгота точки поиска (WGS-84); пара с nearLatitude","required":false,"schema":{"type":"number","format":"double","maximum":180.0,"minimum":-180.0}},{"name":"coverPoint","in":"query","description":"true — зона покрывает точку (default); false — центр зоны в maxDistanceMeters","required":false,"schema":{"type":"string"},"example":true},{"name":"maxDistanceMeters","in":"query","description":"При coverPoint=false — макс. расстояние до центра зоны (метры)","required":false,"schema":{"type":"integer","format":"int64","minimum":1}}],"responses":{"200":{"description":"Количество успешно получено","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/roles/count":{"get":{"tags":["Role API V1"],"summary":"Получить количество ролей","description":"Доступно: **ADMIN**, **SUPERADMIN**, **MANAGER**. Подсчитывает роли с учётом фильтра (логика совпадает с методом списка).","operationId":"count_1","parameters":[{"name":"name","in":"query","description":"Поиск по подстроке в названии роли (без учета регистра)","required":false,"schema":{"type":"string"}},{"name":"updatable","in":"query","description":"Фильтрация по флагу возможности редактирования","required":false,"schema":{"type":"boolean"}},{"name":"deletable","in":"query","description":"Фильтрация по флагу возможности удаления","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Количество успешно получено","content":{"application/json":{"schema":{"type":"integer","format":"int64"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/{id}/roles":{"get":{"tags":["Identity API V1"],"summary":"Получить список ролей пользователя","description":"Доступно: ADMIN, SUPERADMIN. Возвращает массив назначенных пользователю ролей","operationId":"getUserRoles","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Роли успешно получены","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"uniqueItems":true}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/identities/search":{"get":{"tags":["Identity API V1"],"summary":"Многопрофильный поиск пользователей","description":"Доступно только пользователям с ролями ADMIN и SUPERADMIN. Позволяет находить профили по номеру телефона (полное или частичное совпадение) или RUKKI-ID для нужд технической поддержки.","operationId":"searchUsers","parameters":[{"name":"phoneQuery","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Успешный поиск пользователей","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchUsersResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/.well-known/jwks.json":{"get":{"tags":["JWT API V1"],"summary":"Получить публичный ключ (JWKS)","description":"Отдает публичный RSA-ключ в стандартизованном формате JWKS (keys[]), совместимом с OAuth2/OpenID Connect клиентами. Доступен публично, не требует авторизации.","operationId":"getJwks","responses":{"200":{"description":"Успешное получение публичного ключа","content":{"application/json":{"example":{"keys":[{"kty":"RSA","kid":"ab12cd34ef56ab78","use":"sig","alg":"RS256","n":"...","e":"AQAB"}]}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Validation error","details":{"phone":"Некорректный формат телефона"},"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"401":{"description":"Отсутствует или недействителен токен авторизации (JWT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":401,"message":"Full authentication is required to access this resource","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"403":{"description":"Недостаточно прав для выполнения операции (отсутствует нужная роль)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":403,"message":"Access Denied","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Пользователь не найден","details":null,"path":"/api/v1/identities","timestamp":"2026-03-26T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-архитектуры или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Номер телефона уже занят","details":null,"path":"/api/v1/identities/admin/users/123/phone-auth","timestamp":"2026-04-02T10:32:26.961Z"}}}},"500":{"description":"Внутренняя ошибка сервера","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":500,"message":"Internal Server Error","details":null,"path":"/api/v1/identities","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}}},"components":{"schemas":{"ApiErrorDto":{"type":"object","properties":{"status":{"type":"integer","format":"int32"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"type":"string"}},"path":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"UpdateUserRequestV1":{"type":"object","properties":{"firstName":{"type":"string","maxLength":50,"minLength":0},"lastName":{"type":"string","maxLength":50,"minLength":0},"email":{"type":"string","format":"email","maxLength":255,"minLength":0},"inn":{"type":"string","pattern":"^\\d{10}(\\d{2})?$"},"sbpPhone":{"type":"string","pattern":"^\\+?[1-9]\\d{1,14}$"},"maxPhone":{"type":"string","pattern":"^\\+?[1-9]\\d{1,14}$"},"ukepId":{"type":"string","maxLength":1024,"minLength":0},"channels":{"type":"array","description":"Каналы уведомлений; null или [] сбрасывают выбор","items":{"type":"string","enum":["EMAIL","SMS","WHATSAPP","MAX","TELEGRAM"]}},"notificationCategories":{"type":"array","description":"Категории уведомлений; null или [] сбрасывают выбор","items":{"type":"string","enum":["ORDER_CREATED"]}},"avatarFileId":{"type":"string","format":"uuid","description":"Идентификатор файла аватара (file-service)"},"geoData":{"type":"array","description":"Гео-точки; null или [] удаляют все существующие","items":{"$ref":"#/components/schemas/UserGeoDataRequestV1"},"maxItems":20,"minItems":0}},"required":["firstName"]},"UserGeoDataRequestV1":{"type":"object","description":"Гео-точка: координаты и радиус","properties":{"latitude":{"type":"number","format":"double","description":"Широта (WGS-84)","example":55.7558,"maximum":90.0,"minimum":-90.0},"longitude":{"type":"number","format":"double","description":"Долгота (WGS-84)","example":37.6173,"maximum":180.0,"minimum":-180.0},"radiusMeters":{"type":"integer","format":"int64","description":"Радиус зоны в метрах (BIGINT, допускает сотни км)","example":500000,"minimum":1}},"required":["latitude","longitude","radiusMeters"]},"UserGeoDataResponseV1":{"type":"object","description":"Гео-зона профиля (WGS-84). Круг обслуживания: центр + radiusMeters.\nSpatial search — PostgreSQL earthdistance в identity-service.","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор гео-точки"},"latitude":{"type":"number","format":"double","description":"Широта (WGS-84)","example":55.7558},"longitude":{"type":"number","format":"double","description":"Долгота (WGS-84)","example":37.6173},"radiusMeters":{"type":"integer","format":"int64","description":"Радиус зоны в метрах","example":500000}}},"UserResponseV1":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Уникальный RUKKI-ID пользователя"},"phoneAuth":{"type":"string","description":"Номер телефона пользователя (E.164)"},"firstName":{"type":"string","description":"Имя пользователя"},"lastName":{"type":"string","description":"Фамилия пользователя"},"email":{"type":"string","description":"Электронная почта пользователя"},"inn":{"type":"string","description":"ИНН пользователя"},"sbpPhone":{"type":"string","description":"Телефон для СБП переводов (E.164)"},"maxPhone":{"type":"string","description":"Дополнительный телефон (E.164)"},"ukepId":{"type":"string","description":"Идентификатор УКЭП"},"status":{"type":"string","description":"Текущий статус учетной записи","enum":["LEAD","ACTIVE","BANNED","DELETED"]},"channels":{"type":"array","description":"Каналы уведомлений (порядок может использоваться клиентом)","example":["WHATSAPP","TELEGRAM","EMAIL"],"items":{"type":"string","enum":["EMAIL","SMS","WHATSAPP","MAX","TELEGRAM"]}},"notificationCategories":{"type":"array","description":"Категории уведомлений (порядок может использоваться клиентом)","example":["ORDER_CREATED"],"items":{"type":"string","enum":["ORDER_CREATED"]}},"avatarFileId":{"type":"string","format":"uuid","description":"Идентификатор файла аватара (file-service)"},"geoData":{"type":"array","description":"Гео-данные пользователя (координаты и радиус); пустой список — нет точек","items":{"$ref":"#/components/schemas/UserGeoDataResponseV1"}},"createdAt":{"type":"string","format":"date-time","description":"Дата и время создания пользователя"},"updatedAt":{"type":"string","format":"date-time","description":"Дата и время последнего обновления пользователя"}}},"UpdateRoleRequestV1":{"type":"object","description":"DTO запроса для полной замены (редактирования) существующей роли","properties":{"name":{"type":"string","description":"Новое название роли","example":"SUPER_USER","maxLength":50,"minLength":2},"description":{"type":"string","description":"Обновленное описание для роли","example":"Пользователь с расширенным доступом","maxLength":255,"minLength":0}},"required":["name"]},"RoleResponseV1":{"type":"object","description":"DTO ответа, содержащее полную информацию о роли в системе","properties":{"id":{"type":"string","description":"Уникальный строковый идентификатор роли","example":"role_user"},"name":{"type":"string","description":"Название роли","example":"USER"},"description":{"type":"string","description":"Подробное описание назначения роли","example":"Обычный пользователь платформы"},"updatable":{"type":"boolean","description":"Разрешено ли изменение данной роли","example":true},"deletable":{"type":"boolean","description":"Разрешено ли удаление данной роли","example":true},"createdAt":{"type":"string","format":"date-time","description":"Дата и время создания роли"},"updatedAt":{"type":"string","format":"date-time","description":"Дата и время последнего изменения роли"}}},"UpdatePhoneRequestV1":{"type":"object","properties":{"newPhone":{"type":"string","minLength":1,"pattern":"^\\+?\\d{10,15}$"},"reason":{"type":"string","minLength":1},"clientRequestRef":{"type":"string"}},"required":["newPhone","reason"]},"UpdatePhoneAuthResponseV1":{"type":"object","properties":{"rukki_id":{"type":"string"},"new_phone":{"type":"string"},"firebase_synced":{"type":"boolean"}}},"CreateRoleRequestV1":{"type":"object","description":"DTO запроса для создания новой роли","properties":{"name":{"type":"string","description":"Название новой роли","example":"USER","maxLength":50,"minLength":2},"description":{"type":"string","description":"Краткое описание прав доступа роли","example":"Гостевой доступ (только чтение)","maxLength":255,"minLength":0}},"required":["name"]},"CreateUserRequestV1":{"type":"object","properties":{"countryCode":{"type":"string","minLength":1,"pattern":"^[A-Za-z]{2}$"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phoneAuth":{"type":"string","minLength":1,"pattern":"^\\+?\\d{10,15}$"},"orgId":{"type":"string"},"managerId":{"type":"string","format":"uuid"},"draftId":{"type":"string"}},"required":["countryCode","phoneAuth"]},"CreateUserResponseV1":{"type":"object","properties":{"rukki_id":{"type":"string","format":"uuid"},"firebase_status":{"type":"string","enum":["PENDING","CREATED","ACTIVATED"]},"sms_sent":{"type":"boolean"}}},"RoleAssignmentRequestV1":{"type":"object","description":"Запрос на назначение или отзыв ролей","properties":{"roles":{"type":"array","description":"Список ролей для назначения или отзыва","example":["ADMIN","MANAGER"],"items":{"type":"string"},"minItems":1,"uniqueItems":true}},"required":["roles"]},"StatusResponseV1":{"type":"object","properties":{"status":{"type":"string"}}},"ConfirmPhoneChangeRequestV1":{"type":"object","properties":{"newIdToken":{"type":"string","minLength":1}},"required":["newIdToken"]},"AddDeviceTokenRequestV1":{"type":"object","properties":{"fcm_token":{"type":"string","minLength":1}},"required":["fcm_token"]},"VerifyAuthRequestV1":{"type":"object","properties":{"idToken":{"type":"string","minLength":1}},"required":["idToken"]},"VerifyAuthResponseV1":{"type":"object","properties":{"rukki_id":{"type":"string","format":"uuid"},"status":{"type":"string"}}},"LogoutRequestV1":{"type":"object","description":"Опциональное тело logout: отзыв refresh JWT вместе с access","properties":{"refreshToken":{"type":"string","description":"Refresh JWT для отзыва при logout (camelCase или OAuth2 snake_case)","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}}},"RevokeTokenRequestV1":{"type":"object","description":"Запрос на ручной отзыв JWT по jti (ADMIN)","properties":{"jti":{"type":"string","description":"Идентификатор токена (claim jti)","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","minLength":1},"expiresAt":{"type":"string","format":"date-time","description":"Время истечения токена (claim exp)","example":"2030-01-01T00:00:00Z"}},"required":["expiresAt","jti"]},"RevokeTokenResponseV1":{"type":"object","description":"Результат ручного отзыва JWT по jti","properties":{"status":{"type":"string","description":"Статус операции","example":"revoked"},"jti":{"type":"string","description":"Идентификатор отозванного токена (claim jti)","example":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"},"expires_at":{"type":"string","description":"Время истечения токена (claim exp)","example":"2030-01-01T00:00:00.000Z"}}},"TokenResponseV1":{"type":"object","description":"OAuth2 token response: пара access/refresh JWT после логина или refresh","properties":{"access_token":{"type":"string","description":"JWT access-токен для заголовка Authorization: Bearer","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."},"refresh_token":{"type":"string","description":"JWT refresh-токен для обмена на новую пару (POST /auth/token или /auth/refresh)","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."},"rukki_id":{"type":"string","description":"UUID пользователя в платформе (дубликат claim sub)","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"expires_in":{"type":"integer","format":"int64","description":"TTL access-токена в секундах","example":900},"refresh_expires_in":{"type":"integer","format":"int64","description":"TTL refresh-токена в секундах","example":2592000},"token_type":{"type":"string","description":"Тип токена в заголовке Authorization","example":"Bearer"}}},"OAuth2TokenErrorResponseV1":{"type":"object","description":"OAuth2 ошибка token endpoint (refresh grant)","properties":{"error":{"type":"string","description":"Код ошибки RFC 6749","enum":["invalid_grant","invalid_client","unsupported_grant_type","invalid_request","slow_down"],"example":"invalid_grant"},"error_description":{"type":"string","description":"Описание ошибки для клиента","example":"Invalid refresh token"}}},"TelegramAuthRequestV1":{"type":"object","description":"Полезная нагрузка от виджета Telegram Login","properties":{"id":{"type":"integer","format":"int64","description":"Уникальный идентификатор пользователя Telegram","example":123456789},"first_name":{"type":"string","description":"Имя пользователя","example":"Иван"},"last_name":{"type":"string","description":"Фамилия пользователя (опционально)","example":"Иванов"},"username":{"type":"string","description":"Юзернейм пользователя (опционально)","example":"ivan_ivanov"},"photo_url":{"type":"string","description":"Ссылка на аватарку (опционально)","example":"https://t.me/i/userpic/320/ivan.jpg"},"auth_date":{"type":"integer","format":"int64","description":"Unix-timestamp времени авторизации на сервере Telegram","example":1672531200},"hash":{"type":"string","description":"Криптографический HMAC-SHA256 хеш для проверки подлинности данных","example":"e0ac...","minLength":1}},"required":["auth_date","hash","id"]},"RefreshTokenRequestV1":{"type":"object","description":"JSON-запрос обмена refresh JWT на новую пару access/refresh","properties":{"refreshToken":{"type":"string","description":"Refresh JWT, выданный при логине или предыдущем обмене","example":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...","minLength":1},"client_id":{"type":"string","description":"OAuth2 client_id (опционально); должен совпадать с claim azp refresh-токена","example":"identity-service"}},"required":["refreshToken"]},"RotateSigningKeyResponseV1":{"type":"object","description":"Результат принудительной ротации JWT signing key","properties":{"old_kid":{"type":"string","description":"Предыдущий kid","example":"ab12cd34ef56ab78"},"new_kid":{"type":"string","description":"Новый активный kid","example":"fe98dc76ba54fe21"}}},"CallAuthRequestV1":{"type":"object","properties":{"phone":{"type":"string","description":"Номер телефона: 10–15 цифр, префикс «+» в начале необязателен (например +79991234567 или 79991234567)","example":79991234567,"minLength":1,"pattern":"^\\+?\\d{10,15}$"}},"required":["phone"]},"CallAuthResponseV1":{"type":"object","description":"Ответ на запрос авторизации по звонку","properties":{"status":{"type":"string","description":"Статус запроса","example":"OK"},"status_code":{"type":"integer","format":"int32","description":"Код статуса","example":100},"check_id":{"type":"string","description":"Идентификатор проверки","example":"201737-542"},"call_phone":{"type":"string","description":"Номер телефона, на который должен позвонить пользователь","example":78005008275},"call_phone_pretty":{"type":"string","description":"Номер телефона в красивом формате","example":"+7 (800) 500-8275"}}},"PartialUpdateUserRequestV1":{"type":"object","properties":{"firstName":{"type":"string","description":"Имя пользователя","maxLength":50,"minLength":0,"pattern":"^(?!\\s*$).+"},"lastName":{"type":"string","description":"Фамилия пользователя","maxLength":50,"minLength":0},"email":{"type":"string","format":"email","maxLength":255,"minLength":0},"inn":{"type":"string","pattern":"^\\d{10}(\\d{2})?$"},"sbpPhone":{"type":"string","pattern":"^\\+?[1-9]\\d{1,14}$"},"maxPhone":{"type":"string","pattern":"^\\+?[1-9]\\d{1,14}$"},"ukepId":{"type":"string","maxLength":1024,"minLength":0},"channels":{"type":"array","description":"Каналы уведомлений; при передаче полностью заменяют текущий список","items":{"type":"string","enum":["EMAIL","SMS","WHATSAPP","MAX","TELEGRAM"]}},"notificationCategories":{"type":"array","description":"Категории уведомлений; при передаче полностью заменяют текущий список","items":{"type":"string","enum":["ORDER_CREATED"]}},"avatarFileId":{"type":"string","format":"uuid","description":"Идентификатор файла аватара (file-service)"},"geoData":{"type":"array","description":"Гео-точки; при передаче полностью заменяют текущий список","items":{"$ref":"#/components/schemas/UserGeoDataRequestV1"},"maxItems":20,"minItems":0}}},"PartialUpdateRoleRequestV1":{"type":"object","description":"DTO запроса для обновления (редактирования) существующей роли","properties":{"name":{"type":"string","description":"Новое название роли","example":"SUPER_USER","maxLength":100,"minLength":0,"pattern":".*\\S.*"},"description":{"type":"string","description":"Обновленное описание для роли","example":"Пользователь с расширенным доступом","maxLength":255,"minLength":0}}},"PagedResponseUserResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/UserResponseV1"}},"currentPage":{"type":"integer","format":"int32","description":"Номер текущей страницы (с 1)","example":1},"pageSize":{"type":"integer","format":"int32","description":"Размер страницы","example":20},"totalElements":{"type":"integer","format":"int64","description":"Общее количество элементов","example":100}}},"PagedResponseRoleResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/RoleResponseV1"}},"currentPage":{"type":"integer","format":"int32","description":"Номер текущей страницы (с 1)","example":1},"pageSize":{"type":"integer","format":"int32","description":"Размер страницы","example":20},"totalElements":{"type":"integer","format":"int64","description":"Общее количество элементов","example":100}}},"SearchUsersResponseV1":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/UserResponseV1"}}}}},"securitySchemes":{"bearerAuth":{"type":"http","description":"JWT access token identity-service.\nВ Swagger UI вставьте только значение токена (префикс Bearer подставляется автоматически).\nРоли: claim realm_access.roles (USER, MANAGER, ADMIN, SUPERADMIN и др.).\n","scheme":"bearer","bearerFormat":"JWT"}}}}