{"openapi":"3.1.0","info":{"title":"Rukki Equipment Service — PostgreSQL API v1","description":"Микросервис каталога спецтехники для платформы Rukki 5.0\n\n**Группа core-v1** — канонический REST API каталога спецтехники в **PostgreSQL** (Flyway, JPA).\n\n**REST API v1 (PostgreSQL, core-v1):**\n- `/api/v1/groups` — группы каталога (GET list/count/{id} без JWT)\n- `/api/v1/categories` — все категории (GET list/count/{id} без JWT)\n- `/api/v1/groups/{groupId}/categories` — категории в группе (GET list/count/{id} без JWT)\n- `/api/v1/params` — параметры каталога\n- `/api/v1/units` — единицы измерения\n- `/api/v1/tags` — теги поиска (GET list/count/{id} без JWT)\n- `/api/v1/types` — типы спецтехники (GET list/count/{id} без JWT)\n- `/api/v1/vehicles` — экземпляры техники (GET list/count/{id} без JWT)\n- `/api/v1/vehicles/semantic-search` — семантический поиск техники (POST, публично)\n- `/api/v1/vehicles/{vehicleId}/photos` — фото экземпляра (`fileId` → file-service; DELETE снимает ссылку, не S3)\n- `/api/v1/vehicles/{vehicleId}/docs` — документы экземпляра (`fileId` → file-service; DELETE снимает ссылку, не S3)\n- `/api/v1/vehicles/{vehicleId}/ratings` — рейтинг экземпляра (GET list/summary без JWT; POST — USER без EXECUTOR + orderId Done|Paid; PUT/DELETE `/me` — автор)\n\n\n**Пагинация и сортировка** (списки с `PagedResponse`):\n- Эндпоинты: `GET /api/v1/groups`, `GET /api/v1/categories`, `GET /api/v1/groups/{groupId}/categories`, `GET /api/v1/tags`, `GET /api/v1/types`, `GET /api/v1/vehicles`, `GET /api/v1/params`, `GET /api/v1/units`.\n- Query: `page`, `size`, `sort` (в Swagger — отдельные параметры).\n- **`page`** — номер страницы **с 1** (`page=1` — первая; `page=0` не используется).\n- **`size`** — элементов на странице (по умолчанию 50, максимум 100).\n- **`sort`** — `поле,направление` (например `name,asc`); недопустимое поле → **400**.\n- Ответ: `PagedResponse` — `content`, `currentPage` (с 1), `pageSize`, `totalElements`.\n\n**Допустимые поля `sort`:**\n\n| Список | Поля |\n|--------|------|\n| `GET /api/v1/groups` | `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/categories` | `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/groups/{groupId}/categories` | `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/tags` | `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/types` | `title`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/vehicles` | `brandName`, `modelName`, `equipmentType.id`, `ownerUserId`, `licensePlate`, `releaseYear`, `isActive`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/params` | `name`, `isRequired`, `isActive`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n| `GET /api/v1/units` | `code`, `label`, `unitSystem`, `isActive`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` |\n\n\n**Модель ролей (продуктовое решение):**\n- **CATALOG_WRITE** (ADMIN, SUPERADMIN) — мутации структуры витрины: groups, categories, params, units, tags.\n- **VEHICLE_WRITE** (USER, EXECUTOR, MANAGER, SUPERVISOR, ADMIN, SUPERADMIN) — types, vehicles.\n- **VEHICLE_STAFF_READ** (MANAGER, SUPERVISOR, OPERATOR, INTEGRATION, SERVICE, ADMIN, SUPERADMIN) —\n  `GET /vehicles/{id}` любой экземпляр (в т.ч. неактивный) — CRM / проверка владельца при отклике.\n- **RATING_WRITE** (USER без EXECUTOR) — только **создание** оценки (`POST .../ratings`).\n  Нужен `orderId` заказа в статусе **Done** или **Paid** (локальный entitlement из Kafka\n  `rukki.order.events.v1`: тот же customer и `vehicleId`). Владелец техники оценивать себя не может → **422**.\n  `PUT` / `DELETE .../ratings/me` — любому **автору** своей оценки (JWT), в т.ч. с ролью EXECUTOR.\n  `GET .../ratings` и `GET .../ratings/summary` — публично (без JWT).\n- **AUTHENTICATED** — защищённые мутации и owner-scoped операции.\n  `POST /api/v1/vehicles/semantic-search` — **публичный** (guest RAG / витрина;\n  embeddings только видимых сущностей из `vehicle_rag_source_v1`).\nТипы (`/types`) намеренно в **VEHICLE_WRITE**: их создают пользователи при публикации техники, а не только администраторы каталога.\n\n\n**Рейтинг техники** (`GET|POST /api/v1/vehicles/{vehicleId}/ratings`, `.../summary`, `.../me`):\n- Score **1.0–5.0**, шаг **0.5**; одна оценка на пару (техника, автор) и на `orderId`.\n- Агрегаты `ratingAvg` / `ratingCount` денормализованы на `Vehicle` (в ответе техники и в `/summary`).\n- Антифрод POST: entitlement `order_rating_entitlements` (Kafka order-service), статусы Done|Paid.\n- Фильтры списка техники: `minRatingAvg`, `minRatingCount`.\n\n\n**Семантический поиск** (`POST /api/v1/vehicles/semantic-search`):\n- JWT не обязателен (публичный guest RAG / витрина; embeddings только видимых сущностей).\n- Тело: `query` (обязателен), `topK` (1..50, default **10**), `filters` — equality AND по JSONB metadata.\n- Similarity search в `equipments.vehicle_rag_embedding` (Spring AI `PgVectorStore`, cosine, dim **1024**).\n- Пишет векторы **rukki-etl**; ai-service / mcp вызывают только этот HTTP (без JDBC к equipment_db).\n- Контракт: `docs/rag-embedding-contract.md`.\n\n\n**Kafka (не HTTP):**\n- **file.deleted** (`rukki.file.deleted.v1`): снятие ссылок `iconFileId` / `photoFileIds` / `docFileIds`\n  (`file_id` / `icon_file_id` в PostgreSQL) после удаления blob в file-service (`entityType=EQUIPMENT`);\n  DLQ `rukki.equipment.file.deleted.v1.dlq`; идемпотентность — `processed_integration_events`.\n- **order.events** (`rukki.order.events.v1`): upsert `order_rating_entitlements` для антифрода рейтинга\n  (поля: `orderId`, `customerId`, `vehicleId`, `status`, `eventTimestamp`); оценка разрешена при\n  статусе **Done** или **Paid**, совпадении заказчика и техники; DLQ `rukki.equipment.order.events.v1.dlq`.\n- **Consumer group:** `equipment-service-group` (`KAFKA_CONSUMER_GROUP`); ack-mode `record`.\n- **Ссылки на файлы в PostgreSQL:** только UUID — **не** S3 URL; nested DELETE `/photos/` и `/docs/`\n  снимает строку привязки, не объект в S3.\n- **REST create/update техники:** существование файла в file-service **не** проверяется.\n\n\n**Госномер (`licensePlate`):**\n- Допускаются номера **любых стран**: буквы любого Unicode-скрипта (кириллица, латиница и др.) и цифры.\n- При create/PUT/PATCH сервер приводит к **канону**: Unicode upper-case, без пробелов и разделителей\n  (`-`, `_`, `.`, `/`); формат конкретной страны **не** валидируется; латиница в кириллицу не транслитерируется.\n- Фильтр списка/count — подстрока после той же нормализации (регистр и разделители не важны).\n- Символ вне букв/цифр (после снятия разделителей) → **422**. Пустой/blank → `null` в БД.\n- Максимальная длина канона — 32 (`vehicles.license_plate`).\n\n\nЭкземпляры техники — `/api/v1/vehicles` (таблица `vehicles`); рейтинг — nested `/api/v1/vehicles/{vehicleId}/ratings`; семантический поиск — `/api/v1/vehicles/semantic-search`.\n\n**Настройки CORS:**\n- **Разрешенные домены (Origins):** `https://*.rukki.pro, https://rukki.pro, http://localhost:8087, http://127.0.0.1:8087`\n- **Разрешенные HTTP-методы:** `GET, POST, PUT, PATCH, DELETE, OPTIONS`\n- **Разрешенные заголовки:** `*`\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-08-02T07:55:29.467Z | **Artifact:** equipment-service | **Java Version:** 21.0.11 | **OS:** Linux (amd64)","version":"1.0.0-SNAPSHOT"},"servers":[{"url":"https://equipments.rukki.pro","description":"Production Server"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Equipment Types API V1","description":"Типы спецтехники (`/api/v1/types`).\nGET list/count/{id} — без JWT; POST/PUT/PATCH/DELETE — VEHICLE_WRITE (USER+; types — операционный контент, не admin taxonomy).\n`iconFileId` — file-service; очистка при удалении файла — Kafka `rukki.file.deleted.v1` (см. core-v1 info).\n"},{"name":"Equipment Groups API V1","description":"Группы каталога (`/api/v1/groups`).\nGET list/count/{id} — без JWT; POST/PUT/PATCH/DELETE — CATALOG_WRITE (ADMIN/SUPERADMIN; структура витрины).\n"},{"name":"Vehicles API V1","description":"Экземпляры техники в PostgreSQL (`vehicles`, `/api/v1/vehicles`).\nGET list/count/{id} — без JWT; POST/PUT/PATCH/DELETE — JWT и роль VEHICLE_WRITE.\n`photoFileIds` / `docFileIds` — UUID в file-service (0..20); при удалении файла строки\n`vehicles_photos` / `vehicles_docs` снимает Kafka `rukki.file.deleted.v1` (см. core-v1 info).\n`licensePlate` — госномер любой страны; канон на сервере (см. описание core-v1 / LicensePlateUtils).\n"},{"name":"Search Tags API V1","description":"Теги поиска каталога (`/api/v1/tags`).\nGET list/count/{id} — без JWT; POST/PUT/PATCH/DELETE — CATALOG_WRITE (ADMIN/SUPERADMIN; структура витрины).\n"},{"name":"Equipment Categories API V1","description":"Категории каталога PostgreSQL.\nGET `/api/v1/categories` и `/api/v1/groups/{groupId}/categories` — без JWT.\nPOST/PUT/PATCH/DELETE в группе — CATALOG_WRITE (ADMIN/SUPERADMIN; структура витрины).\nПоля `iconFileId` (UUID в file-service) и `tenantIds` (ограничение по тенантам; null — для всех).\nФильтр списка: query `tenantId`. При удалении файла ссылки снимает Kafka `rukki.file.deleted.v1` (см. core-v1 info).\n"},{"name":"Equipment Params API V1","description":"Управление определениями параметров каталога: CRUD справочника equipment_params."},{"name":"Param Units API V1","description":"Управление единицами измерения параметров спецтехники: создание, обновление, удаление, получение списка и просмотр деталей."},{"name":"Vehicle Docs API V1","description":"Документы экземпляра (`/api/v1/vehicles/{vehicleId}/docs`).\n`fileId` — UUID в file-service; загрузка: `entityType=EQUIPMENT`, `entityId`=id техники.\nGET — публично (как GET vehicle; без JWT только `isActive=true`);\nPATCH `isActive` / DELETE — VEHICLE_WRITE (DELETE снимает ссылку, не S3).\n"},{"name":"Vehicle Photos API V1","description":"Фото экземпляра (`/api/v1/vehicles/{vehicleId}/photos`).\n`fileId` — UUID в file-service; загрузка: `entityType=EQUIPMENT`, `entityId`=id техники.\nGET — публично (как GET vehicle; без JWT только `isActive=true`);\nPATCH `isActive` / DELETE — VEHICLE_WRITE (DELETE снимает ссылку, не S3).\n"},{"name":"Vehicle Ratings API V1","description":"Рейтинг экземпляра техники (`/api/v1/vehicles/{vehicleId}/ratings`).\n\n- Score **1.0–5.0**, шаг **0.5**; уникальность: один автор на технику, один `orderId`.\n- **GET** list / summary — публично (активная техника витрины).\n- **POST** — роль USER без EXECUTOR (`RATING_WRITE`); обязателен `orderId` заказа в статусе\n  **Done** или **Paid** (entitlement из Kafka `rukki.order.events.v1`); владелец техники → 422.\n- **GET/PUT/DELETE `/me`** — JWT; изменение/удаление — автор оценки (в т.ч. с EXECUTOR).\n"},{"name":"Vehicle Semantic Search API V1","description":"Семантический поиск техники (`/api/v1/vehicles/semantic-search`).\nEmbedding запроса + cosine similarity в `equipments.vehicle_rag_embedding`\n(Spring AI PgVectorStore). Фильтры — equality AND по JSONB metadata.\nPOST — публично, без JWT (guest RAG ai-service). Контракт: docs/rag-embedding-contract.md.\n"}],"paths":{"/api/v1/vehicles/{vehicleId}/ratings/me":{"get":{"tags":["Vehicle Ratings API V1"],"summary":"Своя оценка техники (v1)","description":"JWT обязателен. Оценка текущего пользователя (`sub`) для экземпляра; нет оценки → **404**.","operationId":"findMine","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Оценка найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleRatingResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["Vehicle Ratings API V1"],"summary":"Обновить свою оценку техники (v1)","description":"JWT обязателен. Полная замена `score` и `comment` (null/blank comment очищает отзыв).\nДоступно автору оценки, в т.ч. после получения роли EXECUTOR. Своей оценки нет → **404**.\n","operationId":"updateMine","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVehicleRatingRequestV1"}}},"required":true},"responses":{"200":{"description":"Оценка обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleRatingResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Vehicle Ratings API V1"],"summary":"Удалить свою оценку техники (v1)","description":"JWT обязателен. Удаляет оценку текущего пользователя; агрегаты на технике пересчитываются.\nДоступно автору, в т.ч. с ролью EXECUTOR. Своей оценки нет → **404**.\n","operationId":"deleteMine","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Оценка удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/{id}":{"get":{"tags":["Vehicles API V1"],"summary":"Получить технику по id (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nВозвращает экземпляр с полными `params`, `searchTags`, `photoFileIds` и `docFileIds`.\nБез JWT — только активная запись; с JWT не-ADMIN чужая или неактивная — 404.\n","operationId":"findById","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор экземпляра техники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Запись успешно получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"put":{"tags":["Vehicles API V1"],"summary":"Полное обновление техники (PUT, v1)","description":"Перезаписывает скалярные поля и M:N-связи.\nСкаляры: null не затирает значения (MapStructConfig).\n`licensePlate` — как при POST (любая страна, канон на сервере; недопустимый символ — 422).\n`params` / `searchTagIds` / `photoFileIds` / `docFileIds`: null или [] снимает все привязки;\nдля сохранения связей передайте полный актуальный список.\n`photoFileIds` / `docFileIds` — 0..20 UUID file-service, порядок сохраняется; дубликаты — 422.\n","operationId":"update","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор экземпляра техники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVehicleRequestV1"}}},"required":true},"responses":{"200":{"description":"Запись успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Vehicles API V1"],"summary":"Удалить технику (v1)","description":"Удаляет экземпляр по UUID. Чужая запись — 404. Отсутствующая или уже удалённая — 204.","operationId":"delete","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор экземпляра техники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Запись успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Vehicles API V1"],"summary":"Частично обновить технику (PATCH, v1)","description":"Частичное обновление (PATCH). См. описание тела запроса.\nСкаляры: отсутствие поля / null — не менять.\n`params` / `searchTagIds` / `photoFileIds` / `docFileIds`: null — не менять; [] — очистить все привязки.\n","operationId":"partialUpdate","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор экземпляра техники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"description":"Частичное обновление: в JSON передаются только изменяемые поля.\n\nСемантика скалярных полей:\n\n| Поле | отсутствует / null |\n|------|--------------------|\n| equipmentTypeId, licensePlate, brandName, modelName, releaseYear, isActive | не менять |\n\nСемантика M:N-полей:\n\n| Поле | отсутствует / null | пустой список [] |\n|------|--------------------|------------------|\n| params | не менять | очистить все параметры на экземпляре |\n| searchTagIds | не менять | очистить все теги поиска |\n| photoFileIds | не менять | очистить все фотографии |\n| docFileIds | не менять | очистить все документы |\n\n`ownerUserId` назначается из JWT (claim sub) и не передаётся.\nЭлемент params: `paramId` — id параметра каталога, `value` — фактическое значение на экземпляре.\nДопустимы только параметры, привязанные к типу экземпляра (`equipment_types_params`).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateVehicleRequestV1"},"examples":{"Только марка и модель":{"summary":"null у связей — без изменений","description":"Только марка и модель","value":{"brandName":"JCB","modelName":"3CX Super"}},"Активировать экземпляр":{"summary":"isActive: true","description":"Активировать экземпляр","value":{"isActive":true}},"Сменить тип":{"summary":"equipmentTypeId — новый UUID типа","description":"Сменить тип","value":{"equipmentTypeId":"2fa85f64-5717-4562-b3fc-2c963f66afa6"}},"Очистить теги поиска":{"summary":"searchTagIds: [] — сброс тегов","description":"Очистить теги поиска","value":{"searchTagIds":[]}},"Очистить фотографии":{"summary":"photoFileIds: [] — сброс галереи","description":"Очистить фотографии","value":{"photoFileIds":[]}},"Очистить документы":{"summary":"docFileIds: [] — сброс документов","description":"Очистить документы","value":{"docFileIds":[]}},"Очистить параметры":{"summary":"params: [] — сброс параметров","description":"Очистить параметры","value":{"params":[]}},"Мощность 75 л.с.":{"summary":"params с фактическим value","description":"Мощность 75 л.с.","value":{"params":[{"paramId":"6fa85f64-5717-4562-b3fc-2c963f66afa6","value":75}]}}}}},"required":true},"responses":{"200":{"description":"Запись успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/units/{id}":{"get":{"tags":["Param Units API V1"],"summary":"Получить единицу измерения по id","operationId":"findById_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор единицы измерения (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Единица успешно получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnitResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["Param Units API V1"],"summary":"Обновить единицу измерения полностью (v1)","description":"Перезаписывает поля единицы (PUT).","operationId":"update_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор единицы измерения (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateParamUnitRequestV1"}}},"required":true},"responses":{"200":{"description":"Единица успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnitResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Param Units API V1"],"summary":"Удалить единицу измерения (v1, admin)","description":"Удаляет единицу, если она не используется определениями параметров спецтехники. Иначе — 422. Доступно только ролям ADMIN и SUPERADMIN.","operationId":"delete_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор единицы измерения (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Единица успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Param Units API V1"],"summary":"Обновить единицу измерения частично (v1)","description":"Обновляет только переданные поля (PATCH).","operationId":"partialUpdate_1","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор единицы измерения (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"7fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateParamUnitRequestV1"}}},"required":true},"responses":{"200":{"description":"Единица успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnitResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/types/{id}":{"get":{"tags":["Equipment Types API V1"],"summary":"Получить тип спецтехники по id (v1, публично)","description":"**JWT не обязателен**. Без admin/superadmin неактивный тип — 404.\n","operationId":"findById_2","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор типа спецтехники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Тип спецтехники успешно получен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentTypeResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"put":{"tags":["Equipment Types API V1"],"summary":"Обновить тип спецтехники полностью (v1)","description":"Перезаписывает все поля и M:N-связи (категории, параметры, теги поиска).","operationId":"update_2","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор типа спецтехники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEquipmentTypeRequestV1"}}},"required":true},"responses":{"200":{"description":"Тип спецтехники успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentTypeResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Equipment Types API V1"],"summary":"Удалить тип спецтехники (v1)","description":"Удаляет тип по UUID. 422 — к типу привязана техника в vehicles. Повторный DELETE — 204.","operationId":"delete_2","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор типа спецтехники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Тип спецтехники успешно удалён"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Equipment Types API V1"],"summary":"Обновить тип спецтехники частично (v1)","description":"Частичное обновление (PATCH). См. семантику M:N-полей в описании тела запроса:\ncategoryIds[] не сбрасывает категории (422), searchTagIds[] и params[] — очищают связи.\n","operationId":"partialUpdate_2","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор типа спецтехники (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateEquipmentTypeRequestV1"}}},"required":true},"responses":{"200":{"description":"Тип спецтехники успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentTypeResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/tags/{id}":{"get":{"tags":["Search Tags API V1"],"summary":"Получить тег поиска по id (v1, публично)","description":"**JWT не обязателен**. Без admin/superadmin неактивный тег — 404.\n","operationId":"findById_3","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор тега (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Тег успешно получен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTagResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"put":{"tags":["Search Tags API V1"],"summary":"Обновить тег поиска полностью (v1, admin)","description":"Перезаписывает поля тега (PUT). Требуется CATALOG_WRITE (ADMIN/SUPERADMIN).","operationId":"update_3","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор тега (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSearchTagRequestV1"}}},"required":true},"responses":{"200":{"description":"Тег успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTagResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Search Tags API V1"],"summary":"Удалить тег поиска (v1, admin)","description":"Удаляет тег, если он не используется объявлениями спецтехники. Иначе — 422.\nТребуется CATALOG_WRITE (ADMIN/SUPERADMIN).\n","operationId":"delete_3","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор тега (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Тег успешно удалён"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Search Tags API V1"],"summary":"Обновить тег поиска частично (v1, admin)","description":"Обновляет только переданные поля (PATCH). Требуется CATALOG_WRITE (ADMIN/SUPERADMIN).","operationId":"partialUpdate_3","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор тега (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateSearchTagRequestV1"}}},"required":true},"responses":{"200":{"description":"Тег успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTagResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/params/{id}":{"get":{"tags":["Equipment Params API V1"],"summary":"Получить параметр по id","operationId":"findById_4","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор параметра (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Параметр успешно получен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParamResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"put":{"tags":["Equipment Params API V1"],"summary":"Обновить параметр полностью (v1, admin)","description":"Перезаписывает поля параметра (PUT).","operationId":"update_4","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор параметра (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateParamRequestV1"}}},"required":true},"responses":{"200":{"description":"Параметр успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParamResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Equipment Params API V1"],"summary":"Удалить параметр (v1, admin)","description":"Удаляет параметр, если он не используется объявлениями спецтехники. Иначе — 422. Доступно только ролям ADMIN и SUPERADMIN.","operationId":"delete_4","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор параметра (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Параметр успешно удалён"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Equipment Params API V1"],"summary":"Обновить параметр частично (v1, admin)","description":"Обновляет только переданные поля (PATCH).","operationId":"partialUpdate_4","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор параметра (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateParamRequestV1"}}},"required":true},"responses":{"200":{"description":"Параметр успешно обновлён","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParamResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/groups/{id}":{"get":{"tags":["Equipment Groups API V1"],"summary":"Получить группу каталога по id (v1, публично)","description":"**JWT не обязателен**. Без admin/superadmin неактивная группа — 404.\n","operationId":"findById_5","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Группа успешно получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentGroupResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"put":{"tags":["Equipment Groups API V1"],"summary":"Обновить группу каталога полностью (v1)","description":"Перезаписывает поля группы (PUT).","operationId":"update_5","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEquipmentGroupRequestV1"}}},"required":true},"responses":{"200":{"description":"Группа успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentGroupResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Equipment Groups API V1"],"summary":"Удалить группу каталога (v1, admin)","description":"Удаляет группу, если к ней не привязаны категории каталога. Иначе — 422. Доступно только ролям ADMIN и SUPERADMIN.","operationId":"delete_5","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Группа успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Equipment Groups API V1"],"summary":"Обновить группу каталога частично (v1)","description":"Обновляет только переданные поля (PATCH).","operationId":"partialUpdate_5","parameters":[{"name":"id","in":"path","description":"Уникальный идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateEquipmentGroupRequestV1"}}},"required":true},"responses":{"200":{"description":"Группа успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentGroupResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/groups/{groupId}/categories/{categoryId}":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить категорию группы по id (v1, публично)","description":"**JWT не обязателен**. Без admin/superadmin неактивная категория или группа — 404.\nВ ответе — `tenantIds` (null — категория без ограничения по тенантам).\n","operationId":"findByIdInGroup","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"categoryId","in":"path","description":"Идентификатор категории (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Категория успешно получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"put":{"tags":["Equipment Categories API V1"],"summary":"Обновить категорию полностью (PUT, v1, admin)","description":"Полная замена полей категории. `description`, `iconFileId`, `tenantIds`: null — сбросить;\nпустой `tenantIds` нормализуется в null.\n`groupId` в теле: null — оставить текущую группу; иначе перенос (уникальность name в целевой группе).\nПосле переноса актуальный `groupId` — в ответе; дальнейшие вызовы — с path groupId из ответа.\n","operationId":"update_6","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"categoryId","in":"path","description":"Идентификатор категории (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCategoryRequestV1"}}},"required":true},"responses":{"200":{"description":"Категория успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"delete":{"tags":["Equipment Categories API V1"],"summary":"Удалить категорию (v1, admin)","description":"Удаляет категорию в группе. 422 — к категории привязаны типы спецтехники. Повторный DELETE — 204.","operationId":"delete_6","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"categoryId","in":"path","description":"Идентификатор категории (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Категория успешно удалена"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Equipment Categories API V1"],"summary":"Обновить категорию частично (PATCH, v1, admin)","description":"Частичное обновление: null — поле не меняется.\n`groupId` — перенос в другую группу (уникальность name в целевой группе).\nПосле переноса актуальный `groupId` — в ответе; дальнейшие вызовы — с path groupId из ответа.\n`tenantIds`: null — не менять; [] — снять ограничение по тенантам.\n","operationId":"partialUpdate_6","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"categoryId","in":"path","description":"Идентификатор категории (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateCategoryRequestV1"}}},"required":true},"responses":{"200":{"description":"Категория успешно обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles":{"get":{"tags":["Vehicles API V1"],"summary":"Получить список техники (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nВозвращает страницу записей `vehicles` с фильтрацией и сортировкой.\nВ списке поля `params`, `searchTags`, `photoFileIds` и `docFileIds` всегда пустые ([]); полный набор — в GET /{id}.\nБез JWT — только активные записи (`isActive=true`, query `isActive` игнорируется).\nС JWT не-ADMIN — только своя техника; ADMIN/SUPERADMIN — все записи или фильтр ownerUserId.\nФильтр `licensePlate` — подстрока после нормализации (любая страна, см. core-v1 info).\nФильтр `searchTagIds` — один или несколько UUID (OR/IN: техника с любым из тегов).\nСортировка: sort=brandName|modelName|equipmentType.id|ownerUserId|licensePlate|releaseYear|isActive|createdAt|updatedAt|createdBy|updatedBy.\n","operationId":"all","parameters":[{"name":"brandName","in":"query","description":"Подстрока в марке (brandName), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"modelName","in":"query","description":"Подстрока в модели (modelName), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"equipmentTypeId","in":"query","description":"Точное совпадение типа спецтехники (equipmentTypeId)","required":false,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"ownerUserId","in":"query","description":"Фильтр по владельцу (UUID из JWT sub); только ADMIN/SUPERADMIN, иначе всегда текущий пользователь","required":false,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"licensePlate","in":"query","description":"Подстрока в госномере (любая страна): после нормализации (upper-case, без пробелов/разделителей) ищется как LIKE; буквы любого скрипта","required":false,"schema":{"type":"string"}},{"name":"searchTagIds","in":"query","description":"Идентификатор(ы) тегов поиска (UUID v4). Повторяйте параметр: searchTagIds=a&searchTagIds=b —\nэкземпляры с любым из указанных тегов (OR/IN).\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"releaseYear","in":"query","description":"Точное совпадение года выпуска (releaseYear)","required":false,"schema":{"type":"integer","format":"int32"},"example":2020},{"name":"isActive","in":"query","description":"Фильтр по признаку активности (isActive)","required":false,"schema":{"type":"boolean"}},{"name":"minRatingAvg","in":"query","description":"Минимальный средний рейтинг (ratingAvg >= value)","required":false,"schema":{"type":"number"},"example":4.0},{"name":"minRatingCount","in":"query","description":"Минимальное число оценок (ratingCount >= value)","required":false,"schema":{"type":"integer","format":"int32"},"example":3},{"name":"page","in":"query","description":"Номер страницы (с 1; первая страница — page=1)","required":false,"schema":{"type":"integer","default":1,"minimum":1},"example":"1"},{"name":"size","in":"query","description":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseVehicleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Vehicles API V1"],"summary":"Создать технику (v1)","description":"Создаёт экземпляр в `vehicles`. `ownerUserId` из JWT (claim sub).\n`licensePlate` — госномер любой страны; на сервере канон (Unicode upper-case, буквы любого\nскрипта и цифры, без пробелов/разделителей); формат страны не валидируется; недопустимый символ — 422.\n`params` — только параметры, привязанные к выбранному типу (`equipment_types_params`).\n`photoFileIds` / `docFileIds` — UUID файлов в file-service (0..20); null или [] — без файлов;\nпорядок в массиве сохраняется. Дубликаты и null в элементе массива — 422.\n","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVehicleRequestV1"}}},"required":true},"responses":{"201":{"description":"Запись успешно создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/{vehicleId}/ratings":{"get":{"tags":["Vehicle Ratings API V1"],"summary":"Список оценок техники (v1, публично)","description":"JWT не обязателен. Возвращает оценки экземпляра (новые сверху).\nТехника должна быть доступна как на публичной витрине (активная), иначе **404**.\n","operationId":"list","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Список получен","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VehicleRatingResponseV1"}}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Vehicle Ratings API V1"],"summary":"Создать оценку техники (v1)","description":"Только **USER** без **EXECUTOR** (`RATING_WRITE`). Тело: `score`, опционально `comment`,\nобязательный `orderId` заказа в статусе **Done** или **Paid** (проверка по локальному\nentitlement из Kafka). Заказчик = текущий USER, техника заказа = `vehicleId`.\nПовторная оценка тем же автором / тем же `orderId` → **422**. Владелец техники → **422**.\n","operationId":"create_1","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVehicleRatingRequestV1"}}},"required":true},"responses":{"201":{"description":"Оценка создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleRatingResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/semantic-search":{"post":{"tags":["Vehicle Semantic Search API V1"],"summary":"Семантический поиск техники (v1, публично)","description":"JWT не обязателен. Embedding текста запроса и similarity search в\n`equipments.vehicle_rag_embedding` (cosine). Опциональные `filters` —\nequality AND по JSONB metadata (например `entity_type=vehicle`).\n","operationId":"search","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleSemanticSearchRequestV1"}}},"required":true},"responses":{"200":{"description":"Список хитов получен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleSemanticSearchResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/units":{"get":{"tags":["Param Units API V1"],"summary":"Получить список единиц измерения","description":"Возвращает список единиц с поддержкой пагинации, сортировки и фильтрации","operationId":"all_1","parameters":[{"name":"code","in":"query","description":"Подстрока в коде (code), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"label","in":"query","description":"Подстрока в подписи (label), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"unitSystem","in":"query","description":"Система единиц (unit_system): SI, imperial, none","required":false,"schema":{"type":"string","enum":["SI","imperial","none"]}},{"name":"isActive","in":"query","description":"Признак активности (is_active)","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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseUnitResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"post":{"tags":["Param Units API V1"],"summary":"Создать единицу измерения (v1)","description":"Создаёт новую единицу измерения.","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParamUnitRequestV1"}}},"required":true},"responses":{"201":{"description":"Единица успешно создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnitResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/types":{"get":{"tags":["Equipment Types API V1"],"summary":"Получить список типов спецтехники (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nБез JWT — только активные типы (`isActive=true`, query `isActive` игнорируется).\nВозвращает список типов с пагинацией, сортировкой и фильтрацией.\nФильтры (AND): q, title, description, isActive, isPopular, searchTagIds (OR/IN), groupCode,\nunitCode (param_units.code), paramValueFrom/To (только вместе с unitCode),\nparamActualValueFrom/To,\ncreatedAtFrom/To, updatedAtFrom/To.\nСортировка: sort=title|createdAt|updatedAt|createdBy|updatedBy.\nПараметр q — общий поиск (OR по title, description, именам категорий, тегов и параметров).\nsearchTagIds — один или несколько UUID тегов (searchTagIds=a&searchTagIds=b): типы с любым из тегов.\ngroupCode — точное имя группы (group_l1); unitCode — код единицы измерения.\nparamValueFrom/To — схема каталога [min_value, max_value]; paramActualValueFrom/To — фактическое value на типе.\nВ q/title/description символы % и _ не являются wildcards.\nВ каждом элементе заполнены categories и searchTags; params всегда [] (детали — GET /{id}).\n","operationId":"all_2","parameters":[{"name":"q","in":"query","description":"Общий поиск: title, description, имена категорий, тегов и параметров (OR)","required":false,"schema":{"type":"string","maxLength":256,"minLength":0}},{"name":"title","in":"query","description":"Подстрока в заголовке (title), без учёта регистра","required":false,"schema":{"type":"string","maxLength":256,"minLength":0}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string","maxLength":2000,"minLength":0}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"searchTagIds","in":"query","description":"Идентификатор(ы) тегов поиска (UUID v4). Повторяйте параметр: searchTagIds=a&searchTagIds=b —\nтипы с любым из указанных тегов (OR/IN).\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"groupCode","in":"query","description":"Точное имя группы (group_l1, equipment_groups.name)","required":false,"schema":{"type":"string","maxLength":128,"minLength":0}},{"name":"unitCode","in":"query","description":"Точный код единицы измерения (param_units.code)","required":false,"schema":{"type":"string","maxLength":16,"minLength":0,"pattern":"^[a-z0-9_]+$"}},{"name":"paramValueFrom","in":"query","description":"Нижняя граница пересечения с [min_value, max_value] привязанного параметра (включительно); требуется unitCode","required":false,"schema":{"type":"number"}},{"name":"paramValueTo","in":"query","description":"Верхняя граница пересечения с [min_value, max_value] привязанного параметра (включительно); требуется unitCode","required":false,"schema":{"type":"number"}},{"name":"paramActualValueFrom","in":"query","description":"Нижняя граница фактического value на типе (включительно)","required":false,"schema":{"type":"number"}},{"name":"paramActualValueTo","in":"query","description":"Верхняя граница фактического value на типе (включительно)","required":false,"schema":{"type":"number"}},{"name":"createdAtFrom","in":"query","description":"Нижняя граница created_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"createdAtTo","in":"query","description":"Верхняя граница created_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updatedAtFrom","in":"query","description":"Нижняя граница updated_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updatedAtTo","in":"query","description":"Верхняя граница updated_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"page","in":"query","description":"Номер страницы (с 1; первая страница — page=1)","required":false,"schema":{"type":"integer","default":1,"minimum":1},"example":"1"},{"name":"size","in":"query","description":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseEquipmentTypeResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Equipment Types API V1"],"summary":"Создать тип спецтехники (v1)","description":"Создаёт новый тип с привязкой к одной или нескольким категориям, тегам и параметрам.","operationId":"create_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEquipmentTypeRequestV1"}}},"required":true},"responses":{"201":{"description":"Тип спецтехники успешно создан","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentTypeResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/tags":{"get":{"tags":["Search Tags API V1"],"summary":"Получить список тегов поиска (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nБез JWT — только активные теги (`isActive=true`, query `isActive` игнорируется).\n","operationId":"all_3","parameters":[{"name":"name","in":"query","description":"Подстрока в названии тега (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseSearchTagResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Search Tags API V1"],"summary":"Создать тег поиска (v1, admin)","description":"Создаёт тег поиска. Имя канонизируется на сервере (lower, ё→е, дефис→пробел).\nИдемпотентно по ключу без пробелов. Требуется CATALOG_WRITE (ADMIN/SUPERADMIN).\n","operationId":"create_4","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSearchTagRequestV1"}}},"required":true},"responses":{"201":{"description":"Тег успешно создан","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTagResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/params":{"get":{"tags":["Equipment Params API V1"],"summary":"Получить список параметров","description":"Возвращает список параметров с поддержкой пагинации, сортировки и фильтрации","operationId":"all_4","parameters":[{"name":"name","in":"query","description":"Подстрока в названии (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"unitCode","in":"query","description":"Подстрока в коде единицы измерения (param_units.code), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isRequired","in":"query","description":"Фильтр по is_required","required":false,"schema":{"type":"boolean"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseParamResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"post":{"tags":["Equipment Params API V1"],"summary":"Создать параметр каталога (v1, admin)","description":"Создаёт определение параметра в справочнике equipment_params.","operationId":"create_5","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParamRequestV1"}}},"required":true},"responses":{"201":{"description":"Параметр успешно создан или уже существует","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParamResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/groups":{"get":{"tags":["Equipment Groups API V1"],"summary":"Получить список групп каталога (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nБез JWT — только активные группы (`isActive=true`, query `isActive` игнорируется).\n","operationId":"all_5","parameters":[{"name":"name","in":"query","description":"Подстрока в названии группы (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseEquipmentGroupResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Equipment Groups API V1"],"summary":"Создать группу каталога (v1)","description":"Создаёт новую группу каталога.","operationId":"create_6","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEquipmentGroupRequestV1"}}},"required":true},"responses":{"201":{"description":"Группа успешно создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquipmentGroupResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/groups/{groupId}/categories":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить список категорий группы (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nБез JWT — только активные категории и активная группа; query `isActive` игнорируется.\nФильтр по тенанту — через query `tenantId` (категории без ограничения или с этим тенантом).\n","operationId":"allInGroup","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"name","in":"query","description":"Подстрока в названии категории, без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"tenantId","in":"query","description":"Идентификатор тенанта. Возвращает категории без ограничения (tenantIds=null)\nи категории, где tenantId входит в tenantIds.\n","required":false,"schema":{"type":"integer","format":"int32"},"example":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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseCategorySummaryResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"post":{"tags":["Equipment Categories API V1"],"summary":"Создать категорию в группе (v1, admin)","description":"Создаёт категорию в группе. Идемпотентен по `name` в рамках группы.\nОпционально: `iconFileId`, `tenantIds` (null/[] — без ограничения по тенантам).\n","operationId":"create_7","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCategoryRequestV1"}}},"required":true},"responses":{"201":{"description":"Категория успешно создана","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/{vehicleId}/photos/{fileId}":{"get":{"tags":["Vehicle Photos API V1"],"summary":"Фотография техники по fileId (v1, публично)","description":"Без JWT неактивная привязка → 404.","operationId":"findByFileId","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Привязка найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"delete":{"tags":["Vehicle Photos API V1"],"summary":"Удалить привязку фотографии по fileId (v1)","description":"Снимает строку `vehicles_photos`. **Не** удаляет файл в file-service/S3 —\nдля этого `DELETE /api/v1/files/{fileId}` (Kafka затем подчистит ссылки).\nПовторный DELETE при отсутствии строки — 204.\n","operationId":"delete_7","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Привязка снята или уже отсутствовала"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Vehicle Photos API V1"],"summary":"Частично обновить привязку фотографии (v1)","description":"Поля с `null` не меняются. Типичный кейс — `isActive` для скрытия из публичной галереи.","operationId":"partialUpdate_7","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateVehiclePhotoRequestV1"}}},"required":true},"responses":{"200":{"description":"Привязка обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/{vehicleId}/docs/{fileId}":{"get":{"tags":["Vehicle Docs API V1"],"summary":"Документ техники по fileId (v1, публично)","description":"Без JWT неактивная привязка → 404.","operationId":"findByFileId_1","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Привязка найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]},"delete":{"tags":["Vehicle Docs API V1"],"summary":"Удалить привязку документа по fileId (v1)","description":"Снимает строку `vehicles_docs`. **Не** удаляет файл в file-service/S3 —\nдля этого `DELETE /api/v1/files/{fileId}` (Kafka затем подчистит ссылки).\nПовторный DELETE при отсутствии строки — 204.\n","operationId":"delete_8","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"204":{"description":"Привязка снята или уже отсутствовала"},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}},"patch":{"tags":["Vehicle Docs API V1"],"summary":"Частично обновить привязку документа (v1)","description":"Поля с `null` не меняются. Типичный кейс — `isActive` для скрытия из публичного списка.","operationId":"partialUpdate_8","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"fileId","in":"path","description":"UUID файла в file-service","required":true,"schema":{"type":"string","format":"uuid"},"example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartialUpdateVehicleDocRequestV1"}}},"required":true},"responses":{"200":{"description":"Привязка обновлена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/vehicles/{vehicleId}/ratings/summary":{"get":{"tags":["Vehicle Ratings API V1"],"summary":"Сводка рейтинга техники (v1, публично)","description":"JWT не обязателен. Денормализованные `ratingAvg` (2 знака, null если оценок нет)\nи `ratingCount` с экземпляра техники. Видимость как у публичной витрины.\n","operationId":"summary","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Сводка получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleRatingSummaryResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/vehicles/{vehicleId}/photos":{"get":{"tags":["Vehicle Photos API V1"],"summary":"Список фотографий техники (v1, публично)","description":"**JWT не обязателен** (видимость как у GET /vehicles/{id}).\nБез JWT — только активные (`isActive=true`). С JWT и доступом к технике — все.\n","operationId":"list_1","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Список получен","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/vehicles/{vehicleId}/docs":{"get":{"tags":["Vehicle Docs API V1"],"summary":"Список документов техники (v1, публично)","description":"**JWT не обязателен** (видимость как у GET /vehicles/{id}).\nБез JWT — только активные (`isActive=true`). С JWT и доступом к технике — все.\n","operationId":"list_2","parameters":[{"name":"vehicleId","in":"path","description":"UUID экземпляра техники","required":true,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Список получен","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VehicleFileRefResponseV1"}}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/vehicles/count":{"get":{"tags":["Vehicles API V1"],"summary":"Получить количество техники (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nПодсчёт с теми же правилами видимости, что у GET /vehicles (без JWT — только `isActive=true`).\n","operationId":"count","parameters":[{"name":"brandName","in":"query","description":"Подстрока в марке (brandName), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"modelName","in":"query","description":"Подстрока в модели (modelName), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"equipmentTypeId","in":"query","description":"Точное совпадение типа спецтехники (equipmentTypeId)","required":false,"schema":{"type":"string","format":"uuid"},"example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"ownerUserId","in":"query","description":"Фильтр по владельцу (UUID из JWT sub); только ADMIN/SUPERADMIN, иначе всегда текущий пользователь","required":false,"schema":{"type":"string","format":"uuid"},"example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"licensePlate","in":"query","description":"Подстрока в госномере (любая страна): после нормализации (upper-case, без пробелов/разделителей) ищется как LIKE; буквы любого скрипта","required":false,"schema":{"type":"string"}},{"name":"searchTagIds","in":"query","description":"Идентификатор(ы) тегов поиска (UUID v4). Повторяйте параметр: searchTagIds=a&searchTagIds=b —\nэкземпляры с любым из указанных тегов (OR/IN).\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"releaseYear","in":"query","description":"Точное совпадение года выпуска (releaseYear)","required":false,"schema":{"type":"integer","format":"int32"},"example":2020},{"name":"isActive","in":"query","description":"Фильтр по признаку активности (isActive)","required":false,"schema":{"type":"boolean"}},{"name":"minRatingAvg","in":"query","description":"Минимальный средний рейтинг (ratingAvg >= value)","required":false,"schema":{"type":"number"},"example":4.0},{"name":"minRatingCount","in":"query","description":"Минимальное число оценок (ratingCount >= value)","required":false,"schema":{"type":"integer","format":"int32"},"example":3}],"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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/units/count":{"get":{"tags":["Param Units API V1"],"summary":"Получить количество единиц измерения","description":"Возвращает число единиц, удовлетворяющих фильтру","operationId":"count_1","parameters":[{"name":"code","in":"query","description":"Подстрока в коде (code), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"label","in":"query","description":"Подстрока в подписи (label), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"unitSystem","in":"query","description":"Система единиц (unit_system): SI, imperial, none","required":false,"schema":{"type":"string","enum":["SI","imperial","none"]}},{"name":"isActive","in":"query","description":"Признак активности (is_active)","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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/types/count":{"get":{"tags":["Equipment Types API V1"],"summary":"Получить количество типов спецтехники (v1, публично)","description":"**JWT не обязателен**. Подсчёт с теми же правилами видимости, что у GET /types.\n","operationId":"count_2","parameters":[{"name":"q","in":"query","description":"Общий поиск: title, description, имена категорий, тегов и параметров (OR)","required":false,"schema":{"type":"string","maxLength":256,"minLength":0}},{"name":"title","in":"query","description":"Подстрока в заголовке (title), без учёта регистра","required":false,"schema":{"type":"string","maxLength":256,"minLength":0}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string","maxLength":2000,"minLength":0}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"searchTagIds","in":"query","description":"Идентификатор(ы) тегов поиска (UUID v4). Повторяйте параметр: searchTagIds=a&searchTagIds=b —\nтипы с любым из указанных тегов (OR/IN).\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"groupCode","in":"query","description":"Точное имя группы (group_l1, equipment_groups.name)","required":false,"schema":{"type":"string","maxLength":128,"minLength":0}},{"name":"unitCode","in":"query","description":"Точный код единицы измерения (param_units.code)","required":false,"schema":{"type":"string","maxLength":16,"minLength":0,"pattern":"^[a-z0-9_]+$"}},{"name":"paramValueFrom","in":"query","description":"Нижняя граница пересечения с [min_value, max_value] привязанного параметра (включительно); требуется unitCode","required":false,"schema":{"type":"number"}},{"name":"paramValueTo","in":"query","description":"Верхняя граница пересечения с [min_value, max_value] привязанного параметра (включительно); требуется unitCode","required":false,"schema":{"type":"number"}},{"name":"paramActualValueFrom","in":"query","description":"Нижняя граница фактического value на типе (включительно)","required":false,"schema":{"type":"number"}},{"name":"paramActualValueTo","in":"query","description":"Верхняя граница фактического value на типе (включительно)","required":false,"schema":{"type":"number"}},{"name":"createdAtFrom","in":"query","description":"Нижняя граница created_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"createdAtTo","in":"query","description":"Верхняя граница created_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updatedAtFrom","in":"query","description":"Нижняя граница updated_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"updatedAtTo","in":"query","description":"Верхняя граница updated_at (ISO-8601, включительно)","required":false,"schema":{"type":"string","format":"date-time"}}],"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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/tags/count":{"get":{"tags":["Search Tags API V1"],"summary":"Получить количество тегов поиска (v1, публично)","description":"**JWT не обязателен**. Подсчёт с теми же правилами видимости, что у GET .../tags.\n","operationId":"count_3","parameters":[{"name":"name","in":"query","description":"Подстрока в названии тега (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/params/count":{"get":{"tags":["Equipment Params API V1"],"summary":"Получить количество параметров","description":"Возвращает число параметров, удовлетворяющих фильтру","operationId":"count_4","parameters":[{"name":"name","in":"query","description":"Подстрока в названии (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"unitCode","in":"query","description":"Подстрока в коде единицы измерения (param_units.code), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isRequired","in":"query","description":"Фильтр по is_required","required":false,"schema":{"type":"boolean"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","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/types","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/groups","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}}}},"/api/v1/groups/{groupId}/categories/count":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить количество категорий группы (v1, публично)","description":"**JWT не обязателен**. Подсчёт с теми же правилами видимости, что у GET .../groups/{groupId}/categories\n(включая фильтр `tenantId`).\n","operationId":"countInGroup","parameters":[{"name":"groupId","in":"path","description":"Идентификатор группы (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"name","in":"query","description":"Подстрока в названии категории, без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"tenantId","in":"query","description":"Идентификатор тенанта. Возвращает категории без ограничения (tenantIds=null)\nи категории, где tenantId входит в tenantIds.\n","required":false,"schema":{"type":"integer","format":"int32"},"example":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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/groups/count":{"get":{"tags":["Equipment Groups API V1"],"summary":"Получить количество групп каталога (v1, публично)","description":"**JWT не обязателен**. Подсчёт с теми же правилами видимости, что у GET /groups.\n","operationId":"count_5","parameters":[{"name":"name","in":"query","description":"Подстрока в названии группы (name), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/categories":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить список всех категорий каталога (v1, публично)","description":"**JWT не обязателен** (см. `SecurityConfig`).\nБез JWT — только активные категории; query `isActive` игнорируется.\nФильтр по группе — через query `groupId` (один или несколько: `groupId=a&groupId=b`).\nФильтр по тенанту — через query `tenantId` (категории без ограничения или с этим тенантом).\n","operationId":"all_6","parameters":[{"name":"groupId","in":"query","description":"Идентификатор(ы) группы каталога (UUID v4, только GET /api/v1/categories).\nПовторяйте параметр: groupId=a&groupId=b — категории из любой из групп.\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"name","in":"query","description":"Подстрока в названии категории, без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"tenantId","in":"query","description":"Идентификатор тенанта. Возвращает категории без ограничения (tenantIds=null)\nи категории, где tenantId входит в tenantIds.\n","required":false,"schema":{"type":"integer","format":"int32"},"example":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":"Размер страницы (по умолчанию 50, макс. 100)","required":false,"schema":{"type":"integer","default":50,"maximum":100,"minimum":1},"example":"50"},{"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/PagedResponseCategorySummaryResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/categories/{id}":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить категорию каталога по id (v1, публично)","description":"**JWT не обязателен**. Без admin/superadmin неактивная категория — 404.\nВ ответе — `tenantIds` (null — категория без ограничения по тенантам).\n","operationId":"findById_6","parameters":[{"name":"id","in":"path","description":"Идентификатор категории (UUID v4)","required":true,"schema":{"type":"string","format":"uuid"},"example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}],"responses":{"200":{"description":"Категория успешно получена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailResponseV1"}}}},"400":{"description":"Некорректный запрос (ошибка валидации параметров)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":400,"message":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}},"/api/v1/categories/count":{"get":{"tags":["Equipment Categories API V1"],"summary":"Получить количество всех категорий каталога (v1, публично)","description":"**JWT не обязателен**. Подсчёт с теми же правилами видимости, что у GET .../categories\n(включая фильтр `tenantId`).\n","operationId":"count_6","parameters":[{"name":"groupId","in":"query","description":"Идентификатор(ы) группы каталога (UUID v4, только GET /api/v1/categories).\nПовторяйте параметр: groupId=a&groupId=b — категории из любой из групп.\n","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},{"name":"name","in":"query","description":"Подстрока в названии категории, без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"description","in":"query","description":"Подстрока в описании (description), без учёта регистра","required":false,"schema":{"type":"string"}},{"name":"isActive","in":"query","description":"Фильтр по is_active","required":false,"schema":{"type":"boolean"}},{"name":"isPopular","in":"query","description":"Фильтр по is_popular","required":false,"schema":{"type":"boolean"}},{"name":"tenantId","in":"query","description":"Идентификатор тенанта. Возвращает категории без ограничения (tenantIds=null)\nи категории, где tenantId входит в tenantIds.\n","required":false,"schema":{"type":"integer","format":"int32"},"example":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":"Ошибка валидации","details":{"title":"не должно быть пустым"},"path":"/api/v1/types","timestamp":"2026-03-26T10:32:26.961Z"}}}},"404":{"description":"Ресурс не найден","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":404,"message":"Группа каталога не найдена: id=...","details":null,"path":"/api/v1/groups/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-03-26T10:32:26.961Z"}}}},"409":{"description":"Конфликт версий (оптимистичная блокировка) или ResponseStatusException","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":409,"message":"Данные были изменены другим пользователем. Обновите страницу и повторите попытку.","details":null,"path":"/api/v1/types/8fa85f64-5717-4562-b3fc-2c963f66afa6","timestamp":"2026-04-15T10:32:26.961Z"}}}},"422":{"description":"Нарушение бизнес-правил или неверное состояние сущности","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorDto"},"example":{"status":422,"message":"Нельзя удалить единицу измерения: она используется параметрами каталога","details":null,"path":"/api/v1/units/8fa85f64-5717-4562-b3fc-2c963f66afa6","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/types","timestamp":"2026-04-02T10:32:26.961Z"}}}}},"security":[]}}},"components":{"schemas":{"UpdateVehicleRatingRequestV1":{"type":"object","description":"Обновление своей оценки (PUT .../ratings/me).\nПолная замена score и comment; null/пустой comment очищает отзыв.\n","properties":{"score":{"type":"number","description":"Оценка 1.0–5.0 с шагом 0.5","example":5.0,"maximum":5.0,"minimum":1.0},"comment":{"type":"string","description":"Текстовый отзыв; null или пустая строка — очистить комментарий","example":"Всё супер","maxLength":1000,"minLength":0}},"required":["score"]},"ApiErrorDto":{"type":"object","description":"Структура ошибки API","properties":{"status":{"type":"integer","format":"int32","description":"HTTP статус ошибки","example":400},"message":{"type":"string","description":"Краткое сообщение об ошибке","example":"Ошибка валидации запроса"},"details":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Дополнительные детали (например, список ошибок валидации по каждому полю)"},"path":{"type":"string","description":"URI ресурса, на котором произошла ошибка","example":"/api/v1/types"},"timestamp":{"type":"string","format":"date-time","description":"Время возникновения ошибки"}}},"VehicleRatingResponseV1":{"type":"object","description":"Оценка экземпляра техники (одна запись vehicle_ratings)","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор оценки","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"vehicleId":{"type":"string","format":"uuid","description":"Идентификатор техники","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"authorUserId":{"type":"string","format":"uuid","description":"Автор оценки (JWT sub)","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"orderId":{"type":"string","format":"uuid","description":"UUID заказа (Done/Paid), по которому оставлена оценка","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"score":{"type":"number","description":"Оценка 1.0–5.0 с шагом 0.5","example":4.5},"comment":{"type":"string","description":"Текстовый отзыв; null если не указан"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания (UTC offset)"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления (UTC offset)"}}},"EquipmentTypeParamAssignmentRequestV1":{"type":"object","description":"Значение параметра на типе или экземпляре","properties":{"paramId":{"type":"string","format":"uuid","description":"Идентификатор параметра каталога (UUID v4)","example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"},"value":{"type":"number","description":"Числовое значение параметра","example":75},"textValues":{"type":"array","items":{"description":"Строка","maxLength":128},"maxItems":20,"minItems":0}},"required":["paramId"]},"UpdateVehicleRequestV1":{"type":"object","description":"Тело запроса с полным набором данных экземпляра","properties":{"equipmentTypeId":{"type":"string","format":"uuid","description":"Идентификатор типа спецтехники (UUID v4)","example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},"licensePlate":{"type":"string","description":"Государственный номер любой страны. Канон на сервере (как при POST); blank → null; недопустимый символ → 422. Макс. 32.","example":"А123ВС77","maxLength":32,"minLength":0},"brandName":{"type":"string","description":"Марка техники; null — не менять; пустая строка запрещена","example":"JCB","maxLength":128,"minLength":1},"modelName":{"type":"string","description":"Модель техники; null — не менять; пустая строка запрещена","example":"3CX","maxLength":128,"minLength":1},"params":{"type":"array","description":"Параметры с фактическими значениями на экземпляре (0 или несколько).\nnull или [] — снять все параметры. Допустимы только параметры выбранного типа.\n","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","description":"Идентификаторы тегов поиска (UUID v4); null или [] — без тегов","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"photoFileIds":{"type":"array","description":"Идентификаторы файлов фотографий в file-service (UUID v4, 0..20); null или [] — без фотографий; порядок в массиве сохраняется","items":{"format":"uuid"},"maxItems":20,"minItems":0},"docFileIds":{"type":"array","description":"Идентификаторы файлов документов в file-service (UUID v4, 0..20); null или [] — без документов; порядок в массиве сохраняется","items":{"format":"uuid"},"maxItems":20,"minItems":0},"geoData":{"type":"array","description":"Районы работ (гео-зоны, 0..20); null или [] — без зон","items":{"$ref":"#/components/schemas/VehicleGeoDataRequestV1"},"maxItems":20,"minItems":0},"releaseYear":{"type":"integer","format":"int32","description":"Год выпуска","example":2020,"maximum":2100,"minimum":1900},"isActive":{"type":"boolean","description":"Признак активности экземпляра","example":true}},"required":["equipmentTypeId"]},"VehicleGeoDataRequestV1":{"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":5000,"minimum":1}},"required":["latitude","longitude","radiusMeters"]},"EquipmentParamValueResponseV1":{"type":"object","description":"Значение параметра каталога (на типе или на экземпляре техники)","properties":{"param":{"$ref":"#/components/schemas/ParamResponseV1","description":"Определение параметра каталога"},"value":{"type":"number","description":"Числовое значение (param_value)"},"textValues":{"type":"array","items":{"description":"Код или подпись"}}}},"ParamResponseV1":{"type":"object","description":"Определение параметра (характеристики) категории каталога","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор параметра (UUID v4)","example":"6fa85f64-5717-4562-b3fc-2c963f66afa6"},"name":{"type":"string","description":"Название параметра"},"description":{"type":"string","description":"Описание параметра"},"label":{"type":"string","description":"Подпись единицы измерения для отображения"},"isRequired":{"type":"boolean","description":"Обязательность при создании типа"},"minValue":{"type":"number","description":"Минимальное значение"},"maxValue":{"type":"number","description":"Максимальное значение"},"isActive":{"type":"boolean","description":"Признак активности"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"SearchTagResponseV1":{"type":"object","description":"Тег полнотекстового поиска каталога","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор тега (UUID v4)","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"},"name":{"type":"string","description":"Название тега","example":"мульчер"},"description":{"type":"string","description":"Описание тега"},"isActive":{"type":"boolean","description":"Признак активности"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"VehicleGeoDataResponseV1":{"type":"object","description":"Гео-зона экземпляра техники (WGS-84). Круг обслуживания: центр + radiusMeters.\n","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":5000},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"VehicleResponseV1":{"type":"object","description":"Экземпляр техники владельца (таблица vehicles)","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор записи (UUID v4)","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"equipmentTypeId":{"type":"string","format":"uuid","description":"Идентификатор типа спецтехники","example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},"ownerUserId":{"type":"string","format":"uuid","description":"Идентификатор владельца (JWT claim sub)","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"licensePlate":{"type":"string","description":"Государственный номер любой страны в каноническом виде (Unicode upper-case, буквы любого скрипта и цифры, без пробелов/разделителей)","example":"А123ВС77"},"brandName":{"type":"string","description":"Марка техники","example":"JCB"},"modelName":{"type":"string","description":"Модель техники","example":"3CX"},"params":{"type":"array","description":"Значения параметров каталога на экземпляре (0 или несколько).\nВ GET /vehicles всегда []; полный набор — в GET /vehicles/{id} и после create/update.\n","items":{"$ref":"#/components/schemas/EquipmentParamValueResponseV1"}},"searchTags":{"type":"array","description":"Теги поиска на экземпляре (0 или несколько).\nВ GET /vehicles всегда []; полный набор — в GET /vehicles/{id} и после create/update.\n","items":{"$ref":"#/components/schemas/SearchTagResponseV1"}},"photoFileIds":{"type":"array","description":"Идентификаторы активных фотографий в file-service (0..20, is_active=true), порядок как в галерее. В GET /vehicles всегда []; полный набор активных — в GET /{id} и после create/update","items":{"format":"uuid"},"maxItems":20},"docFileIds":{"type":"array","description":"Идентификаторы активных документов в file-service (0..20, is_active=true), порядок как в списке. В GET /vehicles всегда []; полный набор активных — в GET /{id} и после create/update","items":{"format":"uuid"},"maxItems":20},"geoData":{"type":"array","description":"Районы работ (гео-зоны, 0..20). Круг: latitude + longitude + radiusMeters.\nВ GET /vehicles всегда []; полный набор — в GET /vehicles/{id} и после create/update.\n","items":{"$ref":"#/components/schemas/VehicleGeoDataResponseV1"},"maxItems":20},"releaseYear":{"type":"integer","format":"int32","description":"Год выпуска","example":2020},"isActive":{"type":"boolean","description":"Признак активности экземпляра"},"ratingAvg":{"type":"number","description":"Средний рейтинг 1.00–5.00 (null если оценок нет)","example":4.5},"ratingCount":{"type":"integer","format":"int32","description":"Число оценок","example":12}}},"UpdateParamUnitRequestV1":{"type":"object","description":"Тело запроса с новыми данными единицы","properties":{"code":{"type":"string","description":"Код единицы","example":"m3","maxLength":16,"minLength":0,"pattern":"^[a-z0-9_]+$"},"label":{"type":"string","description":"Подпись для отображения","example":"м³","maxLength":32,"minLength":0},"description":{"type":"string","description":"Описание единицы измерения","maxLength":2000,"minLength":0},"unitSystem":{"type":"string","description":"Система единиц","enum":["SI","imperial","none"],"example":"SI"},"isActive":{"type":"boolean","description":"Признак активности"}},"required":["code","label","unitSystem"]},"UnitResponseV1":{"type":"object","description":"Единица измерения параметра каталога","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор единицы измерения (UUID v4)","example":"7fa85f64-5717-4562-b3fc-2c963f66afa6"},"code":{"type":"string","description":"Код единицы","example":"m3"},"label":{"type":"string","description":"Подпись","example":"м³"},"description":{"type":"string","description":"Описание единицы измерения"},"unitSystem":{"type":"string","description":"Система единиц","enum":["SI","imperial","none"],"example":"SI"},"isActive":{"type":"boolean","description":"Признак активности","example":false},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"UpdateEquipmentTypeRequestV1":{"type":"object","description":"Тело запроса с полным набором данных типа","properties":{"categoryIds":{"type":"array","description":"Идентификаторы категорий каталога (UUID v4, 1 или несколько)","items":{"format":"uuid","example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}},"title":{"type":"string","description":"Заголовок типа спецтехники","example":"Мини-экскаватор JCB 3CX","maxLength":256,"minLength":0},"description":{"type":"string","description":"Описание типа спецтехники","maxLength":2000,"minLength":0},"params":{"type":"array","description":"Параметры с фактическими значениями (0 или несколько)","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","description":"Идентификаторы тегов поиска (UUID v4, 0 или несколько)","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"isActive":{"type":"boolean","description":"Признак активности","example":false},"isPopular":{"type":"boolean","description":"Признак популярности","example":false},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"}},"required":["categoryIds","title"]},"CategorySummaryResponseV1":{"type":"object","description":"Краткое представление категории каталога для списка (включая tenantIds)","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор категории (UUID v4)","example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"},"groupId":{"type":"string","format":"uuid","description":"Идентификатор группы каталога (UUID v4)","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"name":{"type":"string","description":"Название категории","example":"Мини-экскаватор"},"description":{"type":"string","description":"Описание категории"},"isActive":{"type":"boolean","description":"Признак активности"},"isPopular":{"type":"boolean","description":"Признак популярности"},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"tenantIds":{"type":"array","items":{"example":1}},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"EquipmentTypeResponseV1":{"type":"object","description":"Тип спецтехники в каталоге","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор типа (UUID v4)","example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},"categories":{"type":"array","description":"Категории каталога (1 или несколько)","items":{"$ref":"#/components/schemas/CategorySummaryResponseV1"}},"searchTags":{"type":"array","description":"Теги поиска (0 или несколько)","items":{"$ref":"#/components/schemas/SearchTagResponseV1"}},"title":{"type":"string","description":"Заголовок типа спецтехники"},"description":{"type":"string","description":"Описание типа"},"params":{"type":"array","description":"Параметры с фактическими значениями (0 или несколько). В GET /types всегда [];\nполный набор — в GET /types/{id} и после create/update.\n","items":{"$ref":"#/components/schemas/EquipmentParamValueResponseV1"}},"isActive":{"type":"boolean","description":"Признак активности"},"isPopular":{"type":"boolean","description":"Признак популярности"},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"UpdateSearchTagRequestV1":{"type":"object","description":"Тело запроса с новыми данными тега","properties":{"name":{"type":"string","description":"Название тега (канон на сервере: lower, ё→е, дефис→пробел)","maxLength":128,"minLength":2},"description":{"type":"string","description":"Описание тега","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"}},"required":["name"]},"UpdateParamRequestV1":{"type":"object","description":"Тело запроса с новыми данными параметра","properties":{"name":{"type":"string","description":"Название параметра","example":"Объём ковша","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание параметра","maxLength":2000,"minLength":0},"unitCode":{"type":"string","description":"Код единицы измерения","example":"m3","maxLength":16,"minLength":0},"required":{"type":"boolean","description":"Обязательность параметра при создании типа"},"minValue":{"type":"number","description":"Минимальное значение","example":0.1},"maxValue":{"type":"number","description":"Максимальное значение","example":2.0},"isActive":{"type":"boolean","description":"Признак активности","example":false}},"required":["name","unitCode"]},"UpdateEquipmentGroupRequestV1":{"type":"object","description":"Тело запроса с новыми данными группы","properties":{"name":{"type":"string","description":"Название группы","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание группы","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"}},"required":["name"]},"EquipmentGroupResponseV1":{"type":"object","description":"Группа каталога спецтехники (group_l1)","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор группы (UUID v4)","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"name":{"type":"string","description":"Название группы"},"description":{"type":"string","description":"Описание группы"},"isActive":{"type":"boolean","description":"Признак активности"},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"UpdateCategoryRequestV1":{"type":"object","description":"PUT категории каталога. Все поля тела перезаписываются.\ndescription, iconFileId и tenantIds: null — сбросить значение/ограничение по тенантам.\ngroupId: null — оставить текущую группу; иначе перенос (уникальность name в целевой группе).\n","properties":{"name":{"type":"string","description":"Название категории","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание категории","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"},"isPopular":{"type":"boolean","description":"Признак популярности"},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"groupId":{"type":"string","format":"uuid","description":"Целевая группа каталога (UUID v4); null — не менять группу"},"tenantIds":{"type":"array","items":{"example":1}}},"required":["name"]},"CategoryDetailResponseV1":{"type":"object","description":"Детальное представление категории каталога (включая tenantIds)","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор категории (UUID v4)","example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"},"groupId":{"type":"string","format":"uuid","description":"Идентификатор группы каталога (UUID v4)","example":"3fa85f64-5717-4562-b3fc-2c963f66afa6"},"name":{"type":"string","description":"Название категории"},"description":{"type":"string","description":"Описание категории"},"isActive":{"type":"boolean","description":"Признак активности"},"isPopular":{"type":"boolean","description":"Признак популярности"},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"tenantIds":{"type":"array","items":{"example":1}},"createdAt":{"type":"string","format":"date-time","description":"Дата создания"},"updatedAt":{"type":"string","format":"date-time","description":"Дата обновления"},"createdBy":{"type":"string","description":"Идентификатор создателя записи (JWT sub или ANONYMOUS)","example":"ANONYMOUS"},"updatedBy":{"type":"string","description":"Идентификатор последнего обновившего запись (JWT sub или ANONYMOUS)","example":"ANONYMOUS"}}},"CreateVehicleRequestV1":{"type":"object","description":"Тело запроса на создание экземпляра техники","properties":{"equipmentTypeId":{"type":"string","format":"uuid","description":"Идентификатор типа спецтехники (UUID v4)","example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},"licensePlate":{"type":"string","description":"Государственный номер любой страны. На сервере: Unicode upper-case, без пробелов и разделителей (- _ . /), буквы любого скрипта и цифры; формат страны не валидируется. Blank → null. Недопустимый символ → 422. Макс. 32.","example":"А123ВС77","maxLength":32,"minLength":0},"brandName":{"type":"string","description":"Марка техники (обязательно)","example":"JCB","maxLength":128,"minLength":0},"modelName":{"type":"string","description":"Модель техники (обязательно)","example":"3CX","maxLength":128,"minLength":0},"params":{"type":"array","description":"Параметры с фактическими значениями на экземпляре (0 или несколько).\nДопустимы только параметры, привязанные к выбранному типу (`equipment_types_params`).\n","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","description":"Идентификаторы тегов поиска (UUID v4, 0 или несколько)","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"photoFileIds":{"type":"array","description":"Идентификаторы файлов фотографий в file-service (UUID v4, 0..20); null или [] — без фотографий; порядок в массиве сохраняется","items":{"format":"uuid"},"maxItems":20,"minItems":0},"docFileIds":{"type":"array","description":"Идентификаторы файлов документов в file-service (UUID v4, 0..20); null или [] — без документов; порядок в массиве сохраняется","items":{"format":"uuid"},"maxItems":20,"minItems":0},"geoData":{"type":"array","description":"Районы работ (гео-зоны, 0..20); null или [] — без зон","items":{"$ref":"#/components/schemas/VehicleGeoDataRequestV1"},"maxItems":20,"minItems":0},"releaseYear":{"type":"integer","format":"int32","description":"Год выпуска","example":2020,"maximum":2100,"minimum":1900},"isActive":{"type":"boolean","description":"Признак активности экземпляра","example":true}},"required":["brandName","equipmentTypeId","modelName"]},"CreateVehicleRatingRequestV1":{"type":"object","description":"Создание оценки техники (POST .../ratings).\nТребуется роль USER без EXECUTOR; orderId обязателен (заказ Done или Paid).\n","properties":{"score":{"type":"number","description":"Оценка 1.0–5.0 с шагом 0.5","example":4.5,"maximum":5.0,"minimum":1.0},"comment":{"type":"string","description":"Текстовый отзыв (опционально)","example":"Техника в отличном состоянии","maxLength":1000,"minLength":0},"orderId":{"type":"string","format":"uuid","description":"UUID заказа в статусе Done или Paid. Заказчик = текущий USER (JWT sub);\nтехника заказа должна совпадать с vehicleId пути. Источник права — entitlement из Kafka.\n","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"}},"required":["orderId","score"]},"VehicleSemanticSearchRequestV1":{"type":"object","description":"Запрос семантического поиска техники (POST /api/v1/vehicles/semantic-search)","properties":{"query":{"type":"string","description":"Текстовый запрос","example":"нужен экскаватор 20 тонн","maxLength":2000,"minLength":0},"topK":{"type":"integer","format":"int32","default":"10","description":"Число ближайших хитов (default/max — app.semantic-search.*)","example":10,"maximum":50,"minimum":1},"filters":{"type":"object","additionalProperties":{"type":"object"},"description":"Фильтры по JSONB metadata (equality AND)","example":{"equipment_type_title":"Экскаватор"}}},"required":["query"]},"VehicleSemanticSearchItemResponseV1":{"type":"object","description":"Хит семантического поиска техники","properties":{"id":{"type":"string","format":"uuid","description":"Идентификатор экземпляра техники (UUID v4)","example":"8fa85f64-5717-4562-b3fc-2c963f66afa6"},"score":{"type":"number","format":"double","description":"Оценка сходства","example":0.87},"content":{"type":"string","description":"Канонический текст эмбеддинга"},"metadata":{"type":"object","additionalProperties":{"type":"object"},"description":"Metadata хита (entity_type и фильтры)"}}},"VehicleSemanticSearchResponseV1":{"type":"object","description":"Ответ семантического поиска техники","properties":{"items":{"type":"array","description":"Найденные хиты","items":{"$ref":"#/components/schemas/VehicleSemanticSearchItemResponseV1"}}}},"CreateParamUnitRequestV1":{"type":"object","description":"Модель новой единицы для создания","properties":{"code":{"type":"string","description":"Код единицы","example":"m3","maxLength":16,"minLength":0,"pattern":"^[a-z0-9_]+$"},"label":{"type":"string","description":"Подпись для отображения","example":"м³","maxLength":32,"minLength":0},"description":{"type":"string","description":"Описание единицы измерения","maxLength":2000,"minLength":0},"unitSystem":{"type":"string","description":"Система единиц","enum":["SI","imperial","none"],"example":"SI"},"isActive":{"type":"boolean","description":"Признак активности","example":false}},"required":["code","label"]},"CreateEquipmentTypeRequestV1":{"type":"object","description":"Тело запроса на создание типа","properties":{"categoryIds":{"type":"array","description":"Идентификаторы категорий каталога (UUID v4, 1 или несколько)","items":{"format":"uuid","example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"}},"title":{"type":"string","description":"Заголовок типа спецтехники","example":"Мини-экскаватор JCB 3CX","maxLength":256,"minLength":0},"description":{"type":"string","description":"Описание типа","maxLength":2000,"minLength":0},"params":{"type":"array","description":"Параметры с фактическими значениями (0 или несколько)","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","description":"Идентификаторы тегов поиска (UUID v4, 0 или несколько)","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"isActive":{"type":"boolean","description":"Признак активности","example":false},"isPopular":{"type":"boolean","description":"Признак популярности","example":false},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"}},"required":["categoryIds","title"]},"CreateSearchTagRequestV1":{"type":"object","description":"Модель нового тега для создания","properties":{"name":{"type":"string","description":"Название тега (канон на сервере: lower, ё→е, дефис→пробел)","example":"мульчер","maxLength":128,"minLength":2},"description":{"type":"string","description":"Описание тега","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности","example":false}},"required":["name"]},"CreateParamRequestV1":{"type":"object","description":"Модель нового параметра для создания","properties":{"name":{"type":"string","description":"Название параметра","example":"Объём ковша","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание параметра","maxLength":2000,"minLength":0},"unitCode":{"type":"string","description":"Код единицы измерения","example":"m3","maxLength":16,"minLength":0},"required":{"type":"boolean","description":"Обязательность параметра при создании типа"},"minValue":{"type":"number","description":"Минимальное значение","example":0.1},"maxValue":{"type":"number","description":"Максимальное значение","example":2.0},"isActive":{"type":"boolean","description":"Признак активности","example":false}},"required":["name","unitCode"]},"CreateEquipmentGroupRequestV1":{"type":"object","description":"Модель новой группы для создания","properties":{"name":{"type":"string","description":"Название группы","example":"Машины для земляных работ","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание группы","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности","example":false}},"required":["name"]},"CreateCategoryRequestV1":{"type":"object","description":"Тело запроса с данными новой категории","properties":{"name":{"type":"string","description":"Название категории","example":"Мини-экскаватор","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание категории","maxLength":2000,"minLength":0},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"tenantIds":{"type":"array","items":{"example":1}}},"required":["name"]},"PartialUpdateVehiclePhotoRequestV1":{"type":"object","description":"Частичное обновление привязки фото техники (null — не менять)","properties":{"isActive":{"type":"boolean","description":"Признак активности в публичной галерее"}}},"VehicleFileRefResponseV1":{"type":"object","description":"Ссылка на файл в file-service (фото или документ экземпляра техники)","properties":{"fileId":{"type":"string","format":"uuid","description":"UUID файла в file-service","example":"9fa85f64-5717-4562-b3fc-2c963f66afa6"},"sortOrder":{"type":"integer","format":"int32","description":"Порядок отображения (0 — первый)","example":0},"isActive":{"type":"boolean","description":"Признак активности в публичном списке","example":true}}},"PartialUpdateVehicleDocRequestV1":{"type":"object","description":"Частичное обновление привязки документа техники (null — не менять)","properties":{"isActive":{"type":"boolean","description":"Признак активности в публичном списке документов"}}},"PartialUpdateVehicleRequestV1":{"type":"object","description":"PATCH экземпляра техники.\nСкаляры: null — поле не меняется.\nparams / searchTagIds / photoFileIds / docFileIds / geoData: null — не менять; [] — очистить.\n","properties":{"equipmentTypeId":{"type":"string","format":"uuid","description":"Идентификатор типа спецтехники (UUID v4); null — не менять","example":"2fa85f64-5717-4562-b3fc-2c963f66afa6"},"licensePlate":{"type":"string","description":"Государственный номер любой страны; null — не менять. Канон на сервере (как при POST); blank → null; недопустимый символ → 422. Макс. 32.","example":"А123ВС77","maxLength":32,"minLength":0},"brandName":{"type":"string","description":"Марка техники; null — не менять; пустая строка запрещена","example":"JCB","maxLength":128,"minLength":1},"modelName":{"type":"string","description":"Модель техники; null — не менять; пустая строка запрещена","example":"3CX","maxLength":128,"minLength":1},"params":{"type":"array","description":"Параметры с фактическими значениями (0 или несколько).\nnull — не менять; [] — очистить все параметры на экземпляре.\n","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","description":"Идентификаторы тегов поиска; null — не менять, [] — очистить все теги","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"photoFileIds":{"type":"array","description":"Идентификаторы файлов фотографий (0..20); null — не менять, [] — очистить","items":{"format":"uuid"},"maxItems":20,"minItems":0},"docFileIds":{"type":"array","description":"Идентификаторы файлов документов (0..20); null — не менять, [] — очистить","items":{"format":"uuid"},"maxItems":20,"minItems":0},"geoData":{"type":"array","description":"Районы работ (гео-зоны, 0..20); null — не менять, [] — очистить","items":{"$ref":"#/components/schemas/VehicleGeoDataRequestV1"},"maxItems":20,"minItems":0},"releaseYear":{"type":"integer","format":"int32","description":"Год выпуска; null — не менять","example":2020,"maximum":2100,"minimum":1900},"isActive":{"type":"boolean","description":"Признак активности; null — не менять","example":true}}},"PartialUpdateParamUnitRequestV1":{"type":"object","description":"Тело запроса с обновляемыми данными единицы","properties":{"code":{"type":"string","description":"Код единицы","example":"m3","maxLength":16,"minLength":0,"pattern":"^[a-z0-9_]+$"},"label":{"type":"string","description":"Подпись для отображения","example":"м³","maxLength":32,"minLength":0},"description":{"type":"string","description":"Описание единицы измерения","maxLength":2000,"minLength":0},"unitSystem":{"type":"string","description":"Система единиц","enum":["SI","imperial","none"],"example":"SI"},"isActive":{"type":"boolean","description":"Признак активности","example":true}}},"PartialUpdateEquipmentTypeRequestV1":{"type":"object","description":"PATCH типа спецтехники. null — поле не меняется.\nДля categoryIds пустой [] возвращает 422;\nдля searchTagIds и params пустой [] очищает связи.\n","properties":{"title":{"type":"string","description":"Новый заголовок","example":"Мини-экскаватор JCB 3CX (обновлено)","maxLength":256,"minLength":0},"description":{"type":"string","description":"Новое описание","maxLength":2000,"minLength":0},"categoryIds":{"type":"array","items":{"format":"uuid","example":"4fa85f64-5717-4562-b3fc-2c963f66afa6"},"minItems":1},"params":{"type":"array","items":{"$ref":"#/components/schemas/EquipmentTypeParamAssignmentRequestV1"}},"searchTagIds":{"type":"array","items":{"format":"uuid","example":"5fa85f64-5717-4562-b3fc-2c963f66afa6"}},"isActive":{"type":"boolean","description":"Признак активности","example":true},"isPopular":{"type":"boolean","description":"Признак популярности","example":true},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"}}},"PartialUpdateSearchTagRequestV1":{"type":"object","description":"Тело запроса с обновляемыми данными тега","properties":{"name":{"type":"string","description":"Название тега (канон на сервере: lower, ё→е, дефис→пробел)","maxLength":128,"minLength":2},"description":{"type":"string","description":"Описание тега","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"}}},"PartialUpdateParamRequestV1":{"type":"object","description":"Тело запроса с обновляемыми данными параметра","properties":{"name":{"type":"string","description":"Название параметра","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание параметра","maxLength":2000,"minLength":0},"unitCode":{"type":"string","description":"Код единицы измерения","maxLength":16,"minLength":0},"required":{"type":"boolean","description":"Обязательность параметра"},"minValue":{"type":"number","description":"Минимальное значение"},"maxValue":{"type":"number","description":"Максимальное значение"},"isActive":{"type":"boolean","description":"Признак активности параметра"}}},"PartialUpdateEquipmentGroupRequestV1":{"type":"object","description":"Тело запроса с обновляемыми данными группы","properties":{"name":{"type":"string","description":"Название группы","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание группы","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"}}},"PartialUpdateCategoryRequestV1":{"type":"object","description":"Тело запроса с обновляемыми данными категории","properties":{"name":{"type":"string","description":"Название категории","maxLength":128,"minLength":0},"description":{"type":"string","description":"Описание категории","maxLength":2000,"minLength":0},"isActive":{"type":"boolean","description":"Признак активности"},"isPopular":{"type":"boolean","description":"Признак популярности"},"iconFileId":{"type":"string","format":"uuid","description":"Идентификатор файла иконки (file-service)"},"groupId":{"type":"string","format":"uuid","description":"Целевая группа каталога (UUID v4); null — не менять"},"tenantIds":{"type":"array","items":{"example":1}}}},"PagedResponseVehicleResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/VehicleResponseV1"}},"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}}},"VehicleRatingSummaryResponseV1":{"type":"object","description":"Сводка рейтинга: денормализованные ratingAvg / ratingCount с экземпляра техники","properties":{"ratingAvg":{"type":"number","description":"Средний рейтинг с 2 знаками после запятой; null если оценок нет","example":4.5},"ratingCount":{"type":"integer","format":"int32","description":"Число оценок (0 если оценок нет)","example":12}}},"PagedResponseUnitResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/UnitResponseV1"}},"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}}},"PagedResponseEquipmentTypeResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/EquipmentTypeResponseV1"}},"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}}},"PagedResponseSearchTagResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/SearchTagResponseV1"}},"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}}},"PagedResponseParamResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/ParamResponseV1"}},"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}}},"PagedResponseEquipmentGroupResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/EquipmentGroupResponseV1"}},"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}}},"PagedResponseCategorySummaryResponseV1":{"type":"object","description":"Постраничный ответ со списком элементов","properties":{"content":{"type":"array","description":"Элементы текущей страницы","items":{"$ref":"#/components/schemas/CategorySummaryResponseV1"}},"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}}}},"securitySchemes":{"bearerAuth":{"type":"http","description":"JWT access token. В Swagger UI вставьте только значение токена (префикс Bearer подставляется автоматически).","scheme":"bearer","bearerFormat":"JWT"}}}}