iac/apps/drawings/openapi.yaml

427 lines
13 KiB
YAML
Raw 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: Drawings API
version: "0.0.1"
description: |
REST API сервиса **drawings-api** (`gitlab.com/sarex-team/rnd/drawings-api`) —
управление разрезами (cross-sections) чертежей, их данными и экспортом
в DWG через сервис workflows.
Сервис написан на **Go** (gorilla/mux, go-pg). Роутер собирается в
`cmd/drawings-api/bootstrap.go`. Помимо служебных эндпоинтов
(`/ping`, `/metrics`) есть две группы бизнес-маршрутов с одинаковым
набором операций:
- `/api/v1/*` — публичный роутинг;
- `/internal/v1/*` — внутренний роутинг (набор тот же плюс webhook
экспорта, вызываемый воркером workflow).
На все бизнес-маршруты навешены middleware: JSON-ответ (`rest.JSONResponse`),
request-id (`reqid.Middleware`) и логирование. Явной аутентификации в коде
сервиса нет — доступ ограничивается на уровне ingress/сети кластера.
### Экспорт в DWG
`POST /exports` создаёт запись экспорта и запускает workflow из двух задач
(парсинг cross-section в DWG + webhook-уведомление). По завершении workflow
вызывает `POST /internal/v1/exports/{export_id}/webhook`, который переводит
экспорт в статус `done`.
servers:
- url: /api/v1
description: Публичный префикс
- url: /internal/v1
description: Внутренний префикс
tags:
- name: service
description: Служебные эндпоинты
- name: cross-sections
description: Разрезы чертежей
- name: exports
description: Экспорт разрезов в DWG
paths:
/ping:
get:
tags: [service]
summary: Healthcheck
description: Возвращает статус готовности. Доступен в корне (без префикса).
responses:
"200":
description: Сервис готов
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: ready
/metrics:
get:
tags: [service]
summary: Prometheus-метрики
description: Метрики в формате Prometheus. Доступен в корне (без префикса).
responses:
"200":
description: Метрики
content:
text/plain:
schema:
type: string
# ----- Публичные маршруты (/api/v1) и внутренние (/internal/v1) идентичны,
# кроме webhook, который есть только на /internal/v1. Пути ниже указаны
# относительно префикса из блока servers. -----
/cross-sections:
post:
tags: [cross-sections]
summary: Создать разрез
description: Создаёт cross-section вместе с его данными (`data.raw_data`).
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateCrossSectionRequest"
responses:
"200":
description: Созданный разрез
content:
application/json:
schema:
$ref: "#/components/schemas/CrossSection"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
get:
tags: [cross-sections]
summary: Список разрезов по instance_id
parameters:
- name: instance_id
in: query
required: true
description: UUID инстанса (чертежа)
schema:
type: string
format: uuid
responses:
"200":
description: Массив разрезов (пустой, если ничего не найдено)
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/CrossSection"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
/cross-sections/{cs_id}:
delete:
tags: [cross-sections]
summary: Удалить разрез (soft-delete)
parameters:
- $ref: "#/components/parameters/CrossSectionId"
responses:
"200":
$ref: "#/components/responses/OK"
"400":
$ref: "#/components/responses/BadRequest"
"404":
description: Разрез не найден (возможно, уже удалён)
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
"500":
$ref: "#/components/responses/StorageError"
/cross-sections/{cs_id}/data:
get:
tags: [cross-sections]
summary: Данные разреза
parameters:
- $ref: "#/components/parameters/CrossSectionId"
responses:
"200":
description: Данные разреза
content:
application/json:
schema:
$ref: "#/components/schemas/Data"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
/exports:
post:
tags: [exports]
summary: Создать экспорт разреза в DWG
description: |
Создаёт запись экспорта и запускает workflow экспорта в DWG.
В ответе `workflow_status` = `running`.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateExportRequest"
responses:
"200":
description: Созданный экспорт
content:
application/json:
schema:
$ref: "#/components/schemas/Export"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
get:
tags: [exports]
summary: Список экспортов по фильтрам
description: |
Хотя бы один из фильтров должен быть задан, иначе `400`.
Каждый параметр — список UUID/чисел через запятую.
parameters:
- name: cross_section_ids
in: query
required: false
description: UUID разрезов через запятую
schema:
type: string
- name: export_ids
in: query
required: false
description: UUID экспортов через запятую
schema:
type: string
- name: workflow_ids
in: query
required: false
description: UUID workflow через запятую
schema:
type: string
- name: attachment_ids
in: query
required: false
description: ID вложений (целые) через запятую
schema:
type: string
responses:
"200":
description: Массив экспортов (пустой, если ничего не найдено)
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Export"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
/exports/{export_id}:
delete:
tags: [exports]
summary: Удалить экспорт
parameters:
- $ref: "#/components/parameters/ExportId"
responses:
"200":
$ref: "#/components/responses/OK"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
/exports/{export_id}/webhook:
post:
tags: [exports]
summary: Webhook завершения экспорта (только /internal/v1)
description: |
Вызывается воркером workflow по завершении экспорта. Переводит
экспорт в статус `done`. Доступен только по внутреннему префиксу
`/internal/v1`.
parameters:
- $ref: "#/components/parameters/ExportId"
responses:
"200":
$ref: "#/components/responses/OK"
"400":
$ref: "#/components/responses/BadRequest"
"500":
$ref: "#/components/responses/StorageError"
components:
parameters:
CrossSectionId:
name: cs_id
in: path
required: true
description: UUID разреза
schema:
type: string
format: uuid
ExportId:
name: export_id
in: path
required: true
description: UUID экспорта
schema:
type: string
format: uuid
responses:
OK:
description: Успешно (тело — строка `"OK"`)
content:
application/json:
schema:
type: string
example: OK
BadRequest:
description: Некорректный запрос
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
StorageError:
description: Внутренняя ошибка (ошибка хранилища)
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
schemas:
CrossSection:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
created_at:
type: string
format: date-time
deleted_at:
type: string
format: date-time
instance_id:
type: string
format: uuid
documents:
type: object
additionalProperties:
$ref: "#/components/schemas/ConnectedDocument"
exports:
type: array
items:
$ref: "#/components/schemas/Export"
ConnectedDocument:
type: object
properties:
color:
type: string
name:
type: string
Data:
type: object
properties:
cross_section_id:
type: string
format: uuid
raw_data:
type: string
CreateCrossSectionRequest:
type: object
description: Разрез плюс его данные. Наследует поля CrossSection.
allOf:
- $ref: "#/components/schemas/CrossSection"
- type: object
properties:
data:
$ref: "#/components/schemas/Data"
Author:
type: object
properties:
id:
type: integer
format: int64
first_name:
type: string
last_name:
type: string
Export:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
author:
$ref: "#/components/schemas/Author"
created_at:
type: string
format: date-time
deleted_at:
type: string
format: date-time
nullable: true
cross_section_id:
type: string
format: uuid
workflow_id:
type: string
format: uuid
nullable: true
workflow_status:
type: string
nullable: true
enum: [done, running, error]
file_type:
type: string
enum: [dwg]
attachment_id:
type: integer
nullable: true
CreateExportRequest:
type: object
required: [cross_section_id, author, file_type, company_id]
properties:
cross_section_id:
type: string
format: uuid
author:
$ref: "#/components/schemas/Author"
file_type:
type: string
enum: [dwg]
company_id:
type: integer
format: int64
Error:
type: object
description: Ответ об ошибке (gotools/httperror).
properties:
error:
type: string