iac/apps/comparisons/openapi.yaml

794 lines
26 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.0.3
info:
title: Comparisons Service API
version: "1.0.0"
description: |
REST API сервиса **comparisons-backend** (`pdm/comparisons-backend`) — создание и
просмотр сравнений (облако-BIM отклонение/статусы, облако-облако, облако-поверхность,
pdf-pdf), их элементов, изменений и фильтров.
Сервис написан на Go (роутер **gorilla/mux**). Сервер собирается функцией
`bootstrapAPI` в `cmd/api/bootstrap.go`. Роутинг состоит из двух групп:
- публичный API — префикс `/api/v1` (`cmd/api/routes_api.go`);
- внутренний API — префикс `/internal/v1` (`cmd/api/routes_internal.go`),
предназначен для вызовов внутри кластера (через ingress не публикуется).
### Аутентификация
Публичные эндпоинты (`/api/v1/*`) требуют JWT: middleware `auth.JWTToCtx` +
`auth.JWTUserExtractorFromCtx` (`gitlab.com/sarex-team/gotools/auth`). Токен
передаётся заголовком `Authorization: Bearer <jwt>`; middleware
`auth.DeleteJWTFromQueryMiddleware` дополнительно позволяет передать токен
query-параметром `jwt` (он удаляется из запроса после разбора).
Внутренние эндпоинты (`/internal/v1/*`) аутентификации на уровне приложения
не требуют — ограничение доступа обеспечивается сетевым слоем.
### Обработка ошибок
Ошибки возвращаются функцией `httperror.Write` (`gotools/httperror`). Основные
статусы: `400` — некорректный запрос/параметры, `404` — сравнение не найдено,
`500` — внутренняя ошибка. Идентификатор запроса пробрасывается middleware
`reqid`.
### Замечания (расхождения кода)
- `GET /api/v1/comparisons` возвращает данные разной формы в зависимости от
query-параметра: `workspace_id` → `{ comparisons: [] }`, `document_id` →
`{ results: [] }`, `bundle_id` → одиночный объект сравнения.
- `GET /api/v1/filter_fields` и `GET /api/v1/elements` работают только со
сравнениями типа `deviation`; для других типов вернётся `400`.
- Схема сравнения полиморфна по полю `type` (`deviation`/`c2c`/`c2s`/`abap`/`pdf2pdf`).
contact:
name: comparisons-backend
url: https://gitlab.com/sarex-team/comparisons-backend
servers:
- url: https://api.sarex.io/comparisons
description: Production (ingress)
- url: https://stage-api.sarex.io/comparisons
description: Stage (ingress)
- url: https://api.preprod.sarex.io/comparisons
description: Preprod (ingress)
- url: http://comparisons-backend-service.comparisons-stage
description: Внутрикластерный адрес (ClusterIP). Единственный способ достучаться до /internal/v1
- url: http://localhost:8080
description: Локальный запуск (API_ADDRESS по умолчанию 0.0.0.0:8080)
tags:
- name: types
description: Справочник типов сравнений
- name: comparisons
description: Сравнения — создание, просмотр, удаление
- name: elements
description: Элементы сравнения и их изменения
- name: internal
description: Внутренние эндпоинты (только внутри кластера)
security:
- bearerAuth: []
paths:
# ==========================================================================
# Types
# ==========================================================================
/api/v1/types:
get:
tags: [types]
summary: Справочник типов сравнений
description: Возвращает доступные типы сравнений и их параметры (для построения форм).
operationId: getTypes
responses:
'200':
description: Список типов сравнений
content:
application/json:
schema:
type: object
properties:
types:
type: array
items:
$ref: '#/components/schemas/CompareType'
# ==========================================================================
# Comparisons
# ==========================================================================
/api/v1/comparisons:
post:
tags: [comparisons]
summary: Создать сравнение
description: |
Создаёт сравнение указанного типа. Автор берётся из JWT. Если `parent_doc_id`
и `parent_disk_id` не заданы — вычисляются по рабочей области.
operationId: createComparison
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateRequest'
responses:
'200':
description: Созданное сравнение
content:
application/json:
schema:
$ref: '#/components/schemas/Comparison'
'400':
description: Некорректный запрос / неизвестный тип сравнения
'500':
description: Внутренняя ошибка
get:
tags: [comparisons]
summary: Список сравнений
description: |
Возвращает сравнения по одному из query-параметров. Форма ответа зависит
от параметра (см. описание в `info`). Должен быть задан ровно один параметр.
operationId: getComparisons
parameters:
- name: workspace_id
in: query
required: false
schema:
type: string
format: uuid
description: "Сравнения рабочей области → ответ `{ comparisons: [] }`"
- name: bundle_id
in: query
required: false
schema:
type: string
format: uuid
description: Сравнение по бандлу → ответ — одиночный объект
- name: document_id
in: query
required: false
schema:
type: integer
format: int64
description: "Сравнения документа → ответ `{ results: [] }`"
responses:
'200':
description: Результат (форма зависит от параметра запроса)
content:
application/json:
schema:
oneOf:
- type: object
properties:
comparisons:
type: array
items:
$ref: '#/components/schemas/Comparison'
- type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/Comparison'
- $ref: '#/components/schemas/Comparison'
'400':
description: Не задан workspace_id / bundle_id / document_id
'500':
description: Внутренняя ошибка
/api/v1/comparisons/{comparison_id}:
parameters:
- name: comparison_id
in: path
required: true
schema:
type: integer
format: int64
get:
tags: [comparisons]
summary: Сравнение по id
operationId: getComparisonById
responses:
'200':
description: Сравнение
content:
application/json:
schema:
$ref: '#/components/schemas/Comparison'
'404':
description: Сравнение не найдено
'500':
description: Внутренняя ошибка
delete:
tags: [comparisons]
summary: Удалить сравнение
description: Мягкое удаление сравнения. Автор берётся из JWT.
operationId: deleteComparisonById
responses:
'200':
description: Успешно удалено
'400':
description: Некорректный id
'500':
description: Внутренняя ошибка
/api/v1/filter_fields:
get:
tags: [comparisons]
summary: Поля фильтрации сравнения
description: |
Возвращает набор полей фильтрации для сравнения типа `deviation` по документу.
Для полей отклонения (`deviation`, `deviation_x/y/z`) заполняются `min`/`max`.
Если сравнение по документу не найдено — вернётся пустой `results`.
operationId: getFilterFields
parameters:
- name: doc_id
in: query
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Поля фильтрации
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/FilterFields'
'400':
description: Не задан doc_id / сравнение не типа deviation
'500':
description: Внутренняя ошибка
/api/v1/tolerance:
get:
tags: [comparisons]
summary: Допуск (tolerance) сравнения
description: Возвращает значение допустимого отклонения для сравнения типа `deviation` по бандлу.
operationId: getTolerance
parameters:
- name: bundle_id
in: query
required: true
schema:
type: string
format: uuid
responses:
'200':
description: Допуск
content:
application/json:
schema:
type: object
properties:
tolerance:
type: number
format: double
'400':
description: Не задан / некорректный bundle_id
'404':
description: Сравнение не найдено
'500':
description: Внутренняя ошибка
# ==========================================================================
# Elements
# ==========================================================================
/api/v1/elements:
get:
tags: [elements]
summary: Список элементов сравнения
description: |
Постранично возвращает элементы сравнения типа `deviation` по документу.
Параметры отклонения задаются строкой вида `min:max`. Если сравнение не
найдено — вернётся пустой `results` с типами по умолчанию.
operationId: getListElements
parameters:
- name: doc_id
in: query
required: true
schema:
type: integer
format: int64
- name: limit
in: query
required: false
schema:
type: integer
default: 10
minimum: 0
- name: offset
in: query
required: false
schema:
type: integer
default: 0
minimum: 0
- name: order_by
in: query
required: false
schema:
type: string
enum: [deviation, deviation_x, deviation_y, deviation_z, sarex_id, name]
default: sarex_id
- name: order
in: query
required: false
schema:
type: string
enum: [asc, desc]
default: asc
- name: deviation
in: query
required: false
schema:
type: string
description: Диапазон общего отклонения в формате `min:max`
- name: deviation_x
in: query
required: false
schema:
type: string
description: Диапазон отклонения по X в формате `min:max`
- name: deviation_y
in: query
required: false
schema:
type: string
description: Диапазон отклонения по Y в формате `min:max`
- name: deviation_z
in: query
required: false
schema:
type: string
description: Диапазон отклонения по Z в формате `min:max`
- name: deviation_status
in: query
required: false
schema:
type: string
enum: [in_tolerance, out_of_tolerance]
- name: view_status
in: query
required: false
schema:
type: string
enum: [viewed, not_viewed]
- name: only_with_comment
in: query
required: false
schema:
type: boolean
responses:
'200':
description: Страница элементов
content:
application/json:
schema:
$ref: '#/components/schemas/ListElementsResponse'
'400':
description: Некорректные параметры запроса
'500':
description: Внутренняя ошибка
/api/v1/elements/{element_id}:
parameters:
- name: element_id
in: path
required: true
schema:
type: integer
format: int64
patch:
tags: [elements]
summary: Обновить элемент
description: |
Обновляет один из атрибутов элемента: комментарий, статус отклонения или
статус просмотра. Должно быть задано ровно одно из полей. Изменение
фиксируется записью в истории изменений.
operationId: updateElement
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateElementRequest'
responses:
'200':
description: Успешно обновлено (тело не возвращается)
'400':
description: Некорректный запрос
'500':
description: Внутренняя ошибка
/api/v1/elements/{element_id}/changes:
get:
tags: [elements]
summary: История изменений элемента
operationId: getElementChanges
parameters:
- name: element_id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Список изменений
content:
application/json:
schema:
type: object
properties:
changes:
type: array
items:
$ref: '#/components/schemas/Change'
'400':
description: Некорректный element_id
'500':
description: Внутренняя ошибка
# ==========================================================================
# Internal
# ==========================================================================
/internal/v1/comparisons/{comparison_id}/webhook:
post:
tags: [internal]
summary: Webhook результата сравнения (внутренний)
description: |
Вызывается после завершения обработки сравнения типа `deviation`. Скачивает
`deviation_json` из PDM-хранилища по бандлу, создаёт элементы сравнения и
возвращает содержимое `deviation_json`. Аутентификация на уровне приложения
не требуется.
operationId: comparisonWebhook
security: []
parameters:
- name: comparison_id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Содержимое deviation_json
content:
application/json:
schema:
$ref: '#/components/schemas/DeviationJSON'
'404':
description: Сравнение не найдено
'500':
description: Внутренняя ошибка
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
JWT в заголовке `Authorization: Bearer <jwt>`. Допускается передача
query-параметром `jwt` (удаляется middleware после разбора).
schemas:
ComparisonType:
type: string
enum: [c2c, c2s, deviation, abap, pdf2pdf]
CompareType:
type: object
description: Тип сравнения и набор его параметров (для формы создания).
properties:
name:
$ref: '#/components/schemas/ComparisonType'
verbose_name:
type: string
params:
type: array
items:
$ref: '#/components/schemas/CompareFormParam'
CompareFormParam:
type: object
properties:
name:
type: string
verbose_name:
type: string
hint:
type: string
source:
type: string
enum: [form, viewer]
type:
type: string
description: Тип поля (напр. cloud, bimv2, number, multichoice, choice, array, pdf, surface)
options:
type: array
items:
type: object
additionalProperties: true
default: {}
min:
type: number
format: double
max:
type: number
format: double
CreateRequest:
type: object
required: [name, workspace_id, type, company_id, params]
properties:
name:
type: string
workspace_id:
type: string
format: uuid
parent_doc_id:
type: integer
format: int64
nullable: true
parent_disk_id:
type: string
format: uuid
nullable: true
type:
$ref: '#/components/schemas/ComparisonType'
company_id:
type: integer
format: int64
params:
type: object
description: Параметры сравнения, зависят от type (см. /api/v1/types).
additionalProperties: true
Comparison:
type: object
description: |
Полиморфное сравнение. Поле `type` определяет набор `params`. Ниже приведён
пример для типа `deviation`; для других типов набор params отличается.
properties:
id:
type: integer
format: int64
type:
$ref: '#/components/schemas/ComparisonType'
created_by:
type: integer
format: int64
name:
type: string
workspace_id:
type: string
format: uuid
workflow_id:
type: string
format: uuid
nullable: true
document_id:
type: integer
format: int64
nullable: true
bundle_id:
type: string
format: uuid
nullable: true
params:
$ref: '#/components/schemas/DeviationParams'
DeviationParams:
type: object
properties:
cloud_bundle_id:
type: string
format: uuid
model_bundle_id:
type: string
format: uuid
down_sample_size:
type: number
format: double
resolution:
type: number
format: double
linear_margin:
type: number
format: double
tolerance:
type: number
format: double
sarex_ids:
type: array
items:
type: integer
format: int64
transformation:
type: array
items:
type: number
format: double
applied_statuses:
type: array
items:
type: string
crop_margin:
type: number
format: double
nullable: true
Element:
type: object
properties:
id:
type: integer
format: int64
sarex_id:
type: integer
format: int64
name:
type: string
deviation_status:
type: string
enum: [in_tolerance, out_of_tolerance]
view_status:
type: string
enum: [viewed, not_viewed]
deviation:
type: number
format: double
deviation_x:
type: number
format: double
deviation_y:
type: number
format: double
deviation_z:
type: number
format: double
axis_and_angle:
type: object
description: Ось и угол поворота (utils.AxisAndAngle)
additionalProperties: true
comment:
type: string
nullable: true
bbox_matrix:
type: array
items:
type: number
format: double
reg_matrix:
type: array
items:
type: number
format: double
ListElementsResponse:
type: object
properties:
count:
type: integer
next:
type: string
nullable: true
previous:
type: string
nullable: true
types:
type: object
additionalProperties:
type: array
items:
$ref: '#/components/schemas/Option'
crop_margin:
type: number
format: double
nullable: true
results:
type: array
items:
$ref: '#/components/schemas/Element'
UpdateElementRequest:
type: object
description: |
Должно быть задано ровно одно из полей (`comment`, `deviation_status`,
`view_status`) — валидатор `required_without_all`.
properties:
comment:
type: string
deviation_status:
type: string
enum: [in_tolerance, out_of_tolerance]
view_status:
type: string
enum: [viewed, not_viewed]
Change:
type: object
properties:
id:
type: integer
format: int64
element_id:
type: integer
format: int64
created_at:
type: string
format: date-time
author:
type: integer
format: int64
changed_field:
type: string
enum: [deviation_status, view_status, comment]
old_value:
type: string
new_value:
type: string
FilterFields:
type: object
properties:
name:
type: string
enum: [deviation, deviation_x, deviation_y, deviation_z, deviation_status, view_status, only_with_comment]
verbose_name:
type: string
type:
type: string
enum: [checkbox, selector, slider]
options:
type: array
items:
$ref: '#/components/schemas/Option'
min:
type: number
format: double
nullable: true
max:
type: number
format: double
nullable: true
Option:
type: object
properties:
name:
type: string
verbose_name:
type: string
DeviationJSON:
type: object
properties:
crop_margin:
type: number
format: double
nodes:
type: object
additionalProperties:
$ref: '#/components/schemas/Node'
Node:
type: object
properties:
bbox_matrix:
type: array
items:
type: number
format: double
reg_matrix:
type: array
items:
type: number
format: double
node_name:
type: string