openapi: 3.0.3 info: title: BIM Backend v2 API version: "2.0.0" description: | REST API сервиса **bim-backend-v2** (`platform/bim-backend-v2`) — работа с BIM-моделями, их элементами, свойствами, моделями статусов и метаданными. Сервис написан на Go. HTTP-сервер собирается в `internal/app/http/httpserver.go` (роутер `gorilla/mux` поверх `pkg/gotools/rest`). Роутинг состоит из трёх групп: - публичный API v1 — префикс `/api/v1` (`internal/controller/http/v1`); - публичный API v2 — префикс `/api/v2`, работа с BIM v3 (`internal/controller/http/v2`); - внутренний API v1 — префикс `/internal/v1` (`internal/controller/http/v1/bim_internal` и часть роутов `bim`), предназначен для вызовов внутри кластера (через ingress не публикуется, доступ ограничивается Istio `AuthorizationPolicy` по namespace). Health-check доступен по `GET /ping` (без префикса и без аутентификации), профилировщик `net/http/pprof` — на отдельном порту `:8081`. ### Аутентификация Публичные эндпоинты (`/api/v1/*`, `/api/v2/*`) требуют JWT. Токен передаётся заголовком `Authorization: Bearer ` либо query-параметром `auth_jwt` (`pkg/gotools/auth.JWTToCtx`). Затем `pkg/auth` (`JWTUserExtractorFromCtx`) извлекает `user_id`: 1. если передан заголовок `Identity` — id берётся из Zitadel-токена (claim `urn:zitadel:iam:user:metadata`, поле `user_id`, base64url); 2. иначе — из числового claim `user_id` основного JWT. Подпись токена приложением **не проверяется** (проверка выполняется на уровне Istio по claim `token_type=access`). При отсутствии/непарсинге токена возвращается `401` с пустым телом. Изменение моделей статусов дополнительно требует прав администратора (проверка через Django, см. `ENDPOINTS.md`); при их отсутствии — `403`. Внутренние эндпоинты (`/internal/v1/*`) аутентификации на уровне приложения не требуют — доступ ограничен сетевым слоем (Istio, namespace). ### Идентификаторы Все path-параметры (`bim_id`, `project_id`, `company_id`, `sarex_id` и т.п.) парсятся как `uint64`; неверный формат → `400`. ### Формат ошибок Ошибки из обработчиков возвращаются как `{ "error": "<сообщение>" }` (`pkg/gotools/httperror`). Исключения: `401` от middleware (пустое тело), а также `404`/`405` от роутера (текст `404 route not found` / `405 method not allowed`). servers: - url: https://api.sarex.io/bimv2 description: production (через api-gateway, префикс api_host_prefix) - url: https://stage-api.sarex.io/bimv2 description: stage - url: http://localhost:5555 description: локальный запуск tags: - name: bim-v1 description: BIM, элементы, свойства, статусы (API v1) - name: metadata description: Метаданные BIM (API v1) - name: company-status-model description: Модели статусов компании (API v1) - name: internal-v1 description: Внутренние эндпоинты (только внутри кластера) - name: bim-v2 description: BIM v3 (API v2) - name: service description: Служебные эндпоинты security: - bearerAuth: [] paths: /ping: get: tags: [service] summary: Health-check security: [] responses: "200": description: Сервис работоспособен /api/v1/projects/{project_id}/bims: get: tags: [bim-v1] summary: Список BIM проекта parameters: - $ref: '#/components/parameters/ProjectId' responses: "200": description: OK content: application/json: schema: type: object properties: bims: type: array items: { $ref: '#/components/schemas/Bim' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims: get: tags: [bim-v1] summary: Список BIM по набору id parameters: - name: bim_id in: query required: true description: Список id BIM через запятую (напр. `1,2,3`) schema: { type: string } responses: "200": description: OK content: application/json: schema: type: array items: { $ref: '#/components/schemas/Bim' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}: get: tags: [bim-v1] summary: BIM по id parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/Bim' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/sarexid/{sarex_id}: get: tags: [bim-v1] summary: Элементы BIM по sarex_id (из пути) parameters: - $ref: '#/components/parameters/BimId' - name: sarex_id in: path required: true description: Список sarex_id через запятую schema: { type: string } - $ref: '#/components/parameters/WithHierarchy' responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/BIMElementsResult' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/sarexid: post: tags: [bim-v1] summary: Элементы BIM по sarex_id (из тела) parameters: - $ref: '#/components/parameters/BimId' - $ref: '#/components/parameters/WithHierarchy' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/GetBimElementsRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/BIMElementsResult' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/changes: get: tags: [bim-v1] summary: История изменений статусов элементов BIM parameters: - $ref: '#/components/parameters/BimId' - { name: offset, in: query, required: false, schema: { type: integer, format: int64, default: 0 } } - { name: limit, in: query, required: false, schema: { type: integer, format: int64, default: 20 } } - { name: status_type, in: query, required: false, description: 'Типы статусов через запятую', schema: { type: string } } - { name: sarex_ids, in: query, required: false, description: 'sarex_id через запятую', schema: { type: string } } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/PaginatedChangesResponse' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } post: tags: [bim-v1] summary: Установить статус элементам BIM parameters: - $ref: '#/components/parameters/BimId' - $ref: '#/components/parameters/WithHierarchy' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/SetStatusBodyRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/SetStatusResponse' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/elements: get: tags: [bim-v1] summary: Дерево элементов BIM parameters: - $ref: '#/components/parameters/BimId' - { name: depth, in: query, required: false, schema: { type: integer, format: int64, default: 5 } } - { name: root, in: query, required: false, schema: { type: integer, format: int64 } } - name: statuses in: query required: false description: 'Повторяемый параметр вида `type:value`' schema: { type: array, items: { type: string } } - { name: format, in: query, required: false, schema: { type: string, enum: [full, tiny], default: full } } responses: "200": description: 'При `format=full` элементы полные, при `format=tiny` — усечённые' content: application/json: schema: type: object properties: results: type: array items: oneOf: - { $ref: '#/components/schemas/BIMElement' } - { $ref: '#/components/schemas/BIMElementTiny' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } post: tags: [bim-v1] summary: Отфильтрованные элементы BIM parameters: - $ref: '#/components/parameters/BimId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/GetFilteredElementsRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/BIMElementsResult' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/statuses_color: get: tags: [bim-v1] summary: Цвета статусов BIM parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: 'Ключ — имя модели статусов' content: application/json: schema: type: object additionalProperties: type: array items: { $ref: '#/components/schemas/StatusColorRequest' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/status_models: get: tags: [bim-v1] summary: Модели статусов BIM parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: OK content: application/json: schema: type: array items: { $ref: '#/components/schemas/StatusCategory' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/status_model: post: tags: [bim-v1] summary: Создать модель статусов BIM (требует прав администратора) parameters: - $ref: '#/components/parameters/BimId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StatusCategory' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/OkResponse' } "400": { $ref: '#/components/responses/BadRequest' } "403": { $ref: '#/components/responses/Forbidden' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/delete_status_model: delete: tags: [bim-v1] summary: Удалить модель статусов BIM (требует прав администратора) parameters: - $ref: '#/components/parameters/BimId' - name: status_type in: query required: true description: 'Имя модели статусов. Значение по умолчанию (`building`) удалить нельзя' schema: { type: string } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/OkResponse' } "400": { $ref: '#/components/responses/BadRequest' } "403": { $ref: '#/components/responses/Forbidden' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/filter_fields: get: tags: [bim-v1] summary: Поля для фильтрации элементов BIM parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: 'Категория → свойство → дескриптор фильтра (multiselector/slider/checkbox)' content: application/json: schema: type: object additionalProperties: type: object additionalProperties: oneOf: - { $ref: '#/components/schemas/StringsType' } - { $ref: '#/components/schemas/MinMaxType' } - { $ref: '#/components/schemas/BooleansType' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/properties: get: tags: [bim-v1] summary: Свойства всех элементов BIM parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: 'sarex_id → категория → свойство → значение. Пустой объект, если таблица свойств отсутствует' content: application/json: schema: type: object additionalProperties: type: object additionalProperties: type: object additionalProperties: true "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/elements/{sarex_id}/properties: get: tags: [bim-v1] summary: Свойства одного элемента BIM parameters: - $ref: '#/components/parameters/BimId' - { name: sarex_id, in: path, required: true, schema: { type: integer, format: int64 } } responses: "200": description: 'категория → свойство → значение' content: application/json: schema: type: object additionalProperties: type: object additionalProperties: true "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/statuses: get: tags: [bim-v1] summary: Статусы элементов BIM parameters: - $ref: '#/components/parameters/BimId' - name: statuses in: query required: false description: 'Повторяемый параметр вида `type:value`' schema: { type: array, items: { type: string } } responses: "200": description: OK content: application/json: schema: type: object properties: results: type: array items: { $ref: '#/components/schemas/BIMElementStatuses' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/filter_by_statuses: get: tags: [bim-v1] summary: sarex_id элементов, сгруппированные по статусам parameters: - $ref: '#/components/parameters/BimId' - name: statuses in: query required: false description: 'Повторяемый параметр вида `type:value`' schema: { type: array, items: { type: string } } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/FilterElementsByStatusResponse' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/csv_properties: post: tags: [bim-v1] summary: CSV-отчёт по свойствам элементов BIM parameters: - $ref: '#/components/parameters/BimId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/GetCSVPropertiesReportRequest' } responses: "200": description: 'CSV-файл (разделитель `;`). Заголовки Content-Disposition: attachment; filename=.csv' content: text/csv: schema: { type: string, format: binary } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/metadata: get: tags: [metadata] summary: Метаданные BIM parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/GetMetadataResponse' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/bims/{bim_id}/metadata/transform: patch: tags: [metadata] summary: Обновить матрицу трансформации BIM parameters: - $ref: '#/components/parameters/BimId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/SetMetadataTransformRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/OkResponse' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v1/companies/{company_id}/status_model: post: tags: [company-status-model] summary: Создать модель статусов компании (требует прав администратора) parameters: - $ref: '#/components/parameters/CompanyId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/StatusCategory' } responses: "200": description: OK content: application/json: schema: type: object properties: result: { $ref: '#/components/schemas/CompanyStatusModel' } "400": { $ref: '#/components/responses/BadRequest' } "403": { $ref: '#/components/responses/Forbidden' } "500": { $ref: '#/components/responses/InternalError' } get: tags: [company-status-model] summary: Модель статусов компании parameters: - $ref: '#/components/parameters/CompanyId' responses: "200": description: OK content: application/json: schema: type: object properties: result: { $ref: '#/components/schemas/CompanyStatusModel' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } delete: tags: [company-status-model] summary: Удалить модель статусов компании (требует прав администратора) parameters: - $ref: '#/components/parameters/CompanyId' responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/OkResponse' } "400": { $ref: '#/components/responses/BadRequest' } "403": { $ref: '#/components/responses/Forbidden' } "500": { $ref: '#/components/responses/InternalError' } /internal/v1/bims/{bim_id}/sarexid: post: tags: [internal-v1] summary: Элементы BIM по sarex_id (внутренний, без аутентификации приложения) security: [] parameters: - $ref: '#/components/parameters/BimId' - $ref: '#/components/parameters/WithHierarchy' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/GetBimElementsRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/BIMElementsResult' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /internal/v1/projects/{project_id}/bims: post: tags: [internal-v1] summary: Создать BIM в проекте (внутренний) security: [] parameters: - $ref: '#/components/parameters/ProjectId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/CreateBimRequest' } responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/Bim' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /internal/v1/bims/{bim_id}/filter_elements_by_status: post: tags: [internal-v1] summary: Отфильтровать sarex_id по статусам (внутренний) security: [] parameters: - $ref: '#/components/parameters/BimId' requestBody: required: true content: application/json: schema: { $ref: '#/components/schemas/GetFilteredSarexIDsByStatusRequest' } responses: "200": description: OK content: application/json: schema: type: object properties: sarex_ids: type: array items: { type: integer, format: int64 } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /internal/v1/bims/guid_sarex_id: get: tags: [internal-v1] summary: Сопоставление GUID → sarex_id (внутренний) security: [] parameters: - name: bim_ids in: query required: true description: 'Список id BIM через запятую' schema: { type: string } responses: "200": description: 'Ключ — GUID элемента' content: application/json: schema: type: object additionalProperties: { $ref: '#/components/schemas/BimIDSarexID' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v2/bims: get: tags: [bim-v2] summary: Список BIM v3 parameters: - { name: company_id, in: query, required: false, schema: { type: integer, format: int64 } } - { name: bundle_id, in: query, required: false, schema: { type: string, format: uuid } } - { name: document_id, in: query, required: false, schema: { type: integer, format: int64 } } - { name: bim_type, in: query, required: false, schema: { type: integer, format: int64 } } responses: "200": description: OK content: application/json: schema: type: array items: { $ref: '#/components/schemas/BIMV3' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v2/bims/{bim_id}: get: tags: [bim-v2] summary: BIM v3 по id parameters: - $ref: '#/components/parameters/BimId' responses: "200": description: OK content: application/json: schema: { $ref: '#/components/schemas/BIMV3' } "400": { $ref: '#/components/responses/BadRequest' } "404": { $ref: '#/components/responses/NotFound' } "500": { $ref: '#/components/responses/InternalError' } /api/v2/bims/{bim_id}/elements: post: tags: [bim-v2] summary: Список элементов BIM v3 (с фильтрами по атрибутам) parameters: - $ref: '#/components/parameters/BimId' requestBody: required: false content: application/json: schema: { $ref: '#/components/schemas/ListBIMElementsRequest' } responses: "200": description: OK content: application/json: schema: type: array items: { $ref: '#/components/schemas/BIMV3Element' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } /api/v2/bims/{bim_id}/elements/{sarex_id}: get: tags: [bim-v2] summary: Элемент(ы) BIM v3 по sarex_id parameters: - $ref: '#/components/parameters/BimId' - { name: sarex_id, in: path, required: true, schema: { type: integer, format: int64 } } responses: "200": description: OK content: application/json: schema: type: array items: { $ref: '#/components/schemas/BIMV3Element' } "400": { $ref: '#/components/responses/BadRequest' } "500": { $ref: '#/components/responses/InternalError' } components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: | `Authorization: Bearer ` (или query-параметр `auth_jwt`). Дополнительно может передаваться заголовок `Identity` для Zitadel-токена. parameters: BimId: name: bim_id in: path required: true schema: { type: integer, format: int64 } ProjectId: name: project_id in: path required: true schema: { type: integer, format: int64 } CompanyId: name: company_id in: path required: true schema: { type: integer, format: int64 } WithHierarchy: name: with_hierarchy in: query required: false schema: { type: boolean, default: false } responses: BadRequest: description: Некорректный запрос content: application/json: schema: { $ref: '#/components/schemas/Error' } NotFound: description: Не найдено content: application/json: schema: { $ref: '#/components/schemas/Error' } Forbidden: description: Недостаточно прав (нужны права администратора) content: application/json: schema: { $ref: '#/components/schemas/Error' } InternalError: description: Внутренняя ошибка сервера content: application/json: schema: { $ref: '#/components/schemas/Error' } schemas: Error: type: object properties: error: { type: string } required: [error] OkResponse: type: object properties: ok: { type: boolean, example: true } Bim: type: object properties: id: { type: integer, format: int64 } project_id: { type: integer, format: int64 } document_id: { type: integer, format: int64 } created_at: { type: string, format: date-time } status: { type: string, description: 'BimStatusType, напр. Pending' } transform: { type: array, items: { type: number, format: double } } status_model: type: array items: { $ref: '#/components/schemas/StatusCategory' } properties_names: { type: array, items: { type: string } } category_properties: type: object additionalProperties: type: object additionalProperties: { type: integer, format: int64 } data_types: { type: array, items: { type: string } } categories_names: { type: array, items: { type: string } } company_id: { type: integer, format: int64, nullable: true } StatusCategory: type: object required: [name, verbose_name, initial_status, statuses] properties: name: { type: string } verbose_name: { type: string } initial_status: { type: string } statuses: type: array minItems: 1 items: { $ref: '#/components/schemas/Statuses' } Statuses: type: object required: [verbose_name, color, permissions, name, allowed_transitions] properties: verbose_name: { type: string } color: { type: integer, description: '0..16777215 (RGB)' } permissions: { type: array, items: { type: string } } name: { type: string } allowed_transitions: { type: array, items: { type: string } } StatusColorRequest: type: object properties: name: { type: string } color: { type: integer } BIMElement: type: object description: 'Кастомная сериализация; hierarchy разворачивается в массив uint64' properties: sarex_id: { type: integer, format: int64 } name: { type: string } hierarchy: { type: array, items: { type: integer, format: int64 } } updated_at: { type: string, format: date-time, nullable: true } bim_id: { type: integer, format: int64 } statuses: type: object additionalProperties: { type: string } is_leaf: { type: boolean, nullable: true } extras_from_converter: type: object additionalProperties: true nullable: true bboxMax: { type: array, items: { type: number, format: double } } bboxMin: { type: array, items: { type: number, format: double } } color: { type: integer, nullable: true } BIMElementTiny: type: object properties: sarex_id: { type: integer, format: int64 } parent_id: { type: integer, format: int64, nullable: true } BIMElementStatuses: type: object properties: sarex_id: { type: integer, format: int64 } statuses: type: object additionalProperties: { type: string } BIMElementsResult: type: object properties: results: type: array items: { $ref: '#/components/schemas/BIMElement' } StringsType: type: object properties: values: { type: array, items: { type: string, nullable: true } } type: { type: string, enum: [multiselector, slider, checkbox] } MinMaxType: type: object properties: min: { type: number, format: double, nullable: true } max: { type: number, format: double, nullable: true } has_null: { type: boolean } type: { type: string, enum: [multiselector, slider, checkbox] } BooleansType: type: object properties: values: { type: array, items: { type: boolean, nullable: true } } type: { type: string, enum: [multiselector, slider, checkbox] } FilterFieldRequestStruct: type: object required: [category_name, property_name] properties: category_name: { type: string } property_name: { type: string } values: { type: array, items: {} } min: { type: number, format: double, nullable: true } max: { type: number, format: double, nullable: true } StatusFiltersRequestStruct: type: object properties: group: { type: string } values: { type: array, items: { type: string } } FiltersResponse: type: object properties: properties_filters: type: array items: { $ref: '#/components/schemas/FilterFieldRequestStruct' } status_filters: type: array items: { $ref: '#/components/schemas/StatusFiltersRequestStruct' } GetBimElementsRequest: type: object required: [sarex_ids] properties: sarex_ids: type: array minItems: 1 items: { type: integer, format: int64 } GetFilteredElementsRequest: type: object required: [filters] properties: filters: { $ref: '#/components/schemas/FiltersResponse' } SetStatusBodyRequest: type: object required: [sarex_ids, new_status_type, new_status_value] properties: sarex_ids: type: array items: { type: integer, format: int64 } new_status_type: { type: string } new_status_value: { type: string } SetStatusResponse: type: object properties: count: { type: integer, format: int64 } PaginatedChangesResponse: type: object properties: data: type: array items: { $ref: '#/components/schemas/ChangedBimElementDTO' } total: { type: integer, format: int64 } count: { type: integer, format: int64 } offset: { type: integer, format: int64 } limit: { type: integer, format: int64 } ChangedBimElementDTO: type: object properties: bim_id: { type: integer, format: int64 } sarex_id: { type: integer, format: int64 } created_at: { type: string, format: date-time } number: { type: integer, format: int64 } author: { type: integer, format: int64 } new_status: type: object additionalProperties: { type: string } old_statuses: type: object additionalProperties: { type: string } FilterElementsByStatusResponse: type: object properties: results: type: object additionalProperties: type: object additionalProperties: { $ref: '#/components/schemas/ElementsResponse' } ElementsResponse: type: object properties: sarex_ids: type: array items: { type: integer, format: int64 } GetCSVPropertiesReportRequest: type: object required: [filters] properties: filters: type: object properties: properties_filters: type: array items: { $ref: '#/components/schemas/FilterFieldRequestStruct' } statuses_filters: type: object additionalProperties: type: array items: { type: string } element_ids: type: array items: { type: integer, format: int64 } reported_category_property: type: object additionalProperties: type: array items: { type: string } reported_statuses: type: array items: { type: string } GetMetadataResponse: type: object properties: elements: type: object additionalProperties: { $ref: '#/components/schemas/MetaElement' } bim: { type: integer, format: int64 } created_at: { type: string, format: date-time } global_transformation_matrix: type: array items: { type: number, format: double } MetaElement: type: object properties: name: { type: string } hierarchy: { type: array, items: { type: integer, format: int64 } } bboxMax: { type: array, items: { type: number, format: double } } bboxMin: { type: array, items: { type: number, format: double } } children: { type: array, items: { type: integer, format: int64 } } color: { type: integer, nullable: true } SetMetadataTransformRequest: type: object required: [transform] properties: transform: type: array minItems: 16 maxItems: 16 items: { type: number, format: double } CompanyStatusModel: type: object properties: id: { type: integer, format: int64 } updated_at: { type: string, format: date-time, nullable: true } status_model: { $ref: '#/components/schemas/StatusCategory' } CreateBimRequest: type: object required: [document_id] properties: document_id: { type: integer, format: int64 } GetFilteredSarexIDsByStatusRequest: type: object properties: sarex_ids: type: array items: { type: integer, format: int64 } status_filters: type: array items: { $ref: '#/components/schemas/StatusFiltersRequestStruct' } BimIDSarexID: type: object properties: bim_id: { type: integer, format: int64 } document_id: { type: integer, format: int64 } sarex_id: { type: integer, format: int64 } path: { type: string } BIMV3: type: object properties: id: { type: integer, format: int64 } created_at: { type: string, format: date-time } company_id: { type: integer, format: int64 } bundle_id: { type: string, format: uuid } document_id: { type: integer, format: int64 } bim_type: { type: integer, description: '0 — BIM, 1 — Comparison' } transform: { type: array, items: { type: number, format: double } } reference_bundle_id: { type: string, format: uuid, nullable: true } compared_to_bundle_id: { type: string, format: uuid, nullable: true } BIMV3Element: type: object description: 'Кастомная сериализация; hierarchy разворачивается в массив uint64' properties: id: { type: integer, format: int64 } bim_id: { type: integer, format: int64 } sarex_id: { type: integer, format: int64 } name: { type: string } hierarchy: { type: array, items: { type: integer, format: int64 } } is_leaf: { type: boolean } bboxMin: { type: array, items: { type: number, format: double } } bboxMax: { type: array, items: { type: number, format: double } } attributes: type: object additionalProperties: true ListBIMElementsRequest: type: object properties: attributes_filters: type: array items: { $ref: '#/components/schemas/ListBIMElementsAttributesFilter' } ListBIMElementsAttributesFilter: type: object required: [id, values] properties: id: { type: integer, format: int64 } values: type: array minItems: 1 items: {}