{
  "openapi": "3.0.1",
  "info": {
    "title": "API для плагинов Графини",
    "description": "Публичный контракт для разработки плагинов",
    "version": "1.2.0"
  },
  "tags": [
    {
      "name": "Query",
      "description": "Запрос данных"
    },
    {
      "name": "Datasource",
      "description": "Настройка конфигурации плагина"
    },
    {
      "name": "Variable",
      "description": "Работа с переменными"
    },
    {
      "name": "WellKnown",
      "description": "Запрос метаданных"
    }
  ],
  "paths": {
    "/api/v1/variable/values": {
      "post": {
        "tags": [
          "Variable"
        ],
        "summary": "Запрос значений переменных",
        "description": "Запрос значений переменных. Принимает разные поля, в зависимости от того, что ожидает плагин. Конструктор запросов переменных, если его поддерживает плагин дает понимание, какие поля ожидаются",
        "operationId": "getVariableValues",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VariablesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает значения переменных по соответствующим фильтрам",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConstructorFieldPropOption"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/variable/constructor-fields": {
      "post": {
        "tags": [
          "Variable"
        ],
        "summary": "Получение конструктора запроса переменных",
        "description": "Получение конструктора запроса переменных. Последовательность запросов со значениями, позволит создать DTO для выполения запроса значений переменных.",
        "operationId": "getVariableConstructor",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Язык вывода данных",
            "required": false,
            "schema": {
              "type": "string",
              "default": "ru-RU"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConstructorRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает поля фильтрации переменных для плагина со определениями типов значений",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConstructorField"
                  }
                },
                "example": [
                  {
                    "code": "url",
                    "name": "URL",
                    "type": "text",
                    "description": "Путь к источнику данных",
                    "placeholder": "Введите валидный URL",
                    "validationRule": "^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$",
                    "validationMessage": "Значение должно быть валидным URL",
                    "required": true
                  },
                  {
                    "code": "type",
                    "name": "Тип",
                    "description": "Тип файла",
                    "type": "select",
                    "props": {
                      "options": [
                        {
                          "value": "json",
                          "label": "JSON"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/query/get-result": {
      "post": {
        "tags": [
          "Query"
        ],
        "summary": "Запрос данных из источника данных",
        "description": "Запрос данных из источника данных. Принимает разные поля, в зависимости от того, что ожидает плагин. Конструктор запросов плагина, если его поддерживает плагин дает понимание, какие поля ожидаются",
        "operationId": "getQueryData",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryDataRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает набор данных согласно параметрам запроса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryDataResponse"
                },
                "example": {
                  "status": 200,
                  "frames": [
                    {
                      "refID": "id1",
                      "fields": [
                        {
                          "name": "Потоки",
                          "refID": "id1",
                          "values": [
                            {
                              "1730298165": "10"
                            },
                            {
                              "1730298180": "13"
                            },
                            {
                              "1730298195": "16"
                            },
                            {
                              "1730298210": "17"
                            },
                            {
                              "1730298225": "17"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Неверный формат запроса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryDataResponse"
                },
                "example": {
                  "message": "Недостаточно полей в массиве DatasourceConfig.fields"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/query/constructor-fields": {
      "post": {
        "tags": [
          "Query"
        ],
        "summary": "Получение конструктора запроса плагина",
        "description": "Получение конструктора запроса плагина. Последовательность запросов со значениями, позволит создать DTO для выполения запроса на получение данных.",
        "operationId": "getQueryConstructorFields",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Язык вывода данных",
            "required": false,
            "schema": {
              "type": "string",
              "default": "ru-RU"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConstructorRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает поля запроса данных для плагина со определениями типов значений",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConstructorField"
                  }
                },
                "example": [
                  {
                    "code": "url",
                    "name": "URL",
                    "type": "text",
                    "description": "Путь к источнику данных",
                    "placeholder": "Введите валидный URL",
                    "validationRule": "^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$",
                    "validationMessage": "Значение должно быть валидным URL",
                    "required": true
                  },
                  {
                    "code": "type",
                    "name": "Тип",
                    "description": "Тип файла",
                    "type": "select",
                    "props": {
                      "options": [
                        {
                          "value": "json",
                          "label": "JSON"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/datasource/health-check": {
      "post": {
        "tags": [
          "Datasource"
        ],
        "summary": "Проверка работоспособности источника данных",
        "description": "Проверка работоспособности источника данных. Принимает разные поля, в зависимости от того, что ожидает плагин. Конструктор запроса источников данных, если его поддерживает плагин дает понимание, какие поля ожидаются",
        "operationId": "healthCheckDatasource",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DatasourceConfig"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает статус источника данных",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthCheckResponse"
                },
                "example": {
                  "status": true,
                  "datasourceConfig": {
                    "fields": [
                      {
                        "code": "url",
                        "name": "URL",
                        "description": "Путь к источнику данных",
                        "placeholder": "Введите валидный URL",
                        "validationRule": "^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$",
                        "validationMessage": "Значение должно быть валидным URL",
                        "required": true,
                        "value": "http://prometheus"
                      },
                      {
                        "code": "port",
                        "name": "Порт",
                        "description": "Порт источника данных",
                        "placeholder": "9090",
                        "validationRule": "^[0-9]*$",
                        "min": 80,
                        "max": 49151,
                        "value": "9090"
                      },
                      {
                        "code": "login",
                        "name": "Пользователь",
                        "placeholder": "Введите логин",
                        "validationRule": "^[a-zA-Z0-9_.-]*$",
                        "required": true,
                        "value": "admin"
                      },
                      {
                        "code": "pass",
                        "name": "Пароль",
                        "placeholder": "Введите пароль",
                        "type": "password",
                        "validationRule": "^[a-zA-Z0-9_.-]*$",
                        "required": true,
                        "value": "admin"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Неверный формат запроса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthCheckResponse"
                },
                "example": {
                  "message": "Недостаточно полей в массиве DatasourceConfig.fields"
                }
              }
            }
          },
          "422": {
            "description": "Ошибка валидации",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthCheckResponse"
                },
                "example": {
                  "message": "Ошибка валидации",
                  "validationErrors": {
                    "login": "Поле содержит неразрешенные символы",
                    "password": "Поле не может быть пустым"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/datasource/constructor-fields": {
      "post": {
        "tags": [
          "Datasource"
        ],
        "summary": "Получение конструктора запроса источника данных",
        "description": "Получение конструктора запроса источника данных. Последовательность запросов со значениями, позволит создать DTO для проверки подключения к источнику данных и pluginContext при выполении других запросов.",
        "operationId": "getDatasourceConstructor",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "description": "Язык вывода данных",
            "required": false,
            "schema": {
              "type": "string",
              "default": "ru-RU"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DataSourceConstructorRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Возвращает поля нужные для создания истоника данных",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConstructorField"
                  }
                },
                "example": [
                  {
                    "code": "url",
                    "name": "URL",
                    "type": "text",
                    "description": "Путь к источнику данных",
                    "placeholder": "Введите валидный URL",
                    "validationRule": "^https?:\\/\\/(?:www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b(?:[-a-zA-Z0-9()@:%_\\+.~#?&\\/=]*)$",
                    "validationMessage": "Значение должно быть валидным URL",
                    "required": true
                  },
                  {
                    "code": "type",
                    "name": "Тип",
                    "description": "Тип файла",
                    "type": "select",
                    "props": {
                      "options": [
                        {
                          "value": "json",
                          "label": "JSON"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/well-known": {
      "get": {
        "tags": [
          "WellKnown"
        ],
        "summary": "Запрос метаданных",
        "description": "Запрос метаданных",
        "operationId": "getWellKnown",
        "responses": {
          "200": {
            "description": "Возвращает набор данных согласно параметрам запроса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PluginMetadata"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ConstructorFieldPropOption": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "description": "Читаемое имя выбора",
            "example": "XML"
          },
          "value": {
            "type": "string",
            "description": "Кодовое значение",
            "example": "XML"
          }
        },
        "description": "Ограниченный Enum"
      },
      "DatasourceConfig": {
        "type": "object",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DatasourceField"
            }
          }
        },
        "description": "Конфигурация источника данных, содержит значения по-умолчанию при запросе конфигурации, или значения, заданные клиентом, при запросе данных"
      },
      "DatasourceConfigResponse": {
        "type": "object",
        "properties": {
          "datasourceConfig": {
            "$ref": "#/components/schemas/DatasourceConfig"
          }
        },
        "description": "Ответ с конфигурацией источника данных"
      },
      "DatasourceField": {
        "required": [
          "code"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Поле будет участвовать в формировании HTML-атрибутов id, name",
            "example": "login"
          },
          "name": {
            "type": "string",
            "description": "Читаемое название поля",
            "example": "Логин пользователя"
          },
          "description": {
            "type": "string",
            "description": "Читаемое описание поля",
            "example": "Идентификатор пользователя полученный после регистрации в системе"
          },
          "required": {
            "type": "boolean",
            "description": "Поле не может быть пустым, если данное свойство установлено в true",
            "example": false
          },
          "max": {
            "type": "integer",
            "description": "Максимальное значение для полей типа NUMBER",
            "format": "int32",
            "example": 100
          },
          "min": {
            "type": "integer",
            "description": "Минимальное значение для полей типа NUMBER",
            "format": "int32",
            "example": 10
          },
          "maxLength": {
            "type": "integer",
            "description": "Максимальная длина строки для полей типа TEXT",
            "format": "int32",
            "example": 100
          },
          "minLength": {
            "type": "integer",
            "description": "Минимальная длина строки для полей типа TEXT",
            "format": "int32",
            "example": 10
          },
          "maxFileSize": {
            "type": "integer",
            "description": "Максимальный размер файла для полей типа FILE",
            "format": "int32",
            "example": 100
          },
          "acceptFile": {
            "type": "string",
            "description": "Расширения файла, которые может выбрать пользователь",
            "example": ".csv"
          },
          "readOnly": {
            "type": "boolean",
            "description": "Разрешено ли пользователю редактировать поле",
            "example": true
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DatasourceFieldOption"
            }
          },
          "placeholder": {
            "type": "string",
            "description": "Текст, присутствующий в поле ввода, перед тем как пользователь начинает вводить данные",
            "example": "Введите имя пользователя"
          },
          "type": {
            "type": "string",
            "enum": [
              "number",
              "password",
              "text",
              "textarea",
              "file",
              "select",
              "radio"
            ]
          },
          "validationRule": {
            "type": "string",
            "description": "RegExp выражение для валидации поля на стороне клиента",
            "example": "^[a-zA-Z0-9_.-]*$"
          },
          "validationMessage": {
            "type": "string",
            "description": "Сообщению пользователю об формате вводимого значения",
            "example": "Поле логина должно содержать символы [a-zA-Z0-9_.-]"
          },
          "value": {
            "type": "string",
            "description": "Значение поля / значени поля по-умолчанию (в зависимости от направления DTO)"
          }
        },
        "description": "Метаданные поля, описывающие его атрибуты: тип и ограничения"
      },
      "DatasourceFieldOption": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "description": "Читаемое имя выбора",
            "example": "Get"
          },
          "value": {
            "type": "string",
            "description": "Кодовое значение",
            "example": "GET"
          }
        },
        "description": "Ограниченный Enum"
      },
      "LocalizedString": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string",
            "description": "Код языка",
            "example": "ru-RU"
          },
          "value": {
            "type": "string",
            "description": "Текст на выбранном языке",
            "example": "Плагин для работы с метриками"
          }
        },
        "required": [
          "lang",
          "value"
        ],
        "description": "Локализованная строка"
      },
      "PluginMetadata": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Уникальный идентификатор плагина",
            "example": "prometheus"
          },
          "title": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocalizedString"
            }
          },
          "version": {
            "type": "string",
            "example": "1.2.0"
          },
          "description": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocalizedString"
            }
          },
          "queryHelp": {
            "type": "array",
            "description": "Подсказка для поля ввода запроса (если выбран режим запроса JSON)",
            "items": {
              "$ref": "#/components/schemas/LocalizedString"
            }
          },
          "baseUrl": {
            "type": "string",
            "description": "Базовый URL плагина",
            "example": "http://plugin-domain/api/v1"
          }
        },
        "description": "Метаданные плагина"
      },
      "PluginContext": {
        "type": "object",
        "properties": {
          "orgID": {
            "type": "integer",
            "description": "orgID",
            "format": "int64",
            "example": 0
          },
          "pluginID": {
            "type": "string",
            "description": "Клиентский идентификатор плагина",
            "example": "pult1"
          },
          "dataSourceInstanceSettings": {
            "$ref": "#/components/schemas/DatasourceConfig"
          }
        },
        "description": "Текущая конфигурация источника данных"
      },
      "VariablesRequest": {
        "type": "object",
        "properties": {
          "pluginContext": {
            "$ref": "#/components/schemas/PluginContext"
          },
          "json": {
            "type": "string",
            "description": "JSON со свободной структурой, которая будет зависеть от типа запроса",
            "example": "TODO"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Переменные, которые потом будет подставлены в запросе. Переменная может быть строкой или массивом строк"
          }
        },
        "description": "Запрос значений для переменных из источника данных"
      },
      "ConstructorField": {
        "required": [
          "code"
        ],
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Поле будет участвовать в формировании HTML-атрибутов id, name",
            "example": "login"
          },
          "name": {
            "type": "string",
            "description": "Читаемое название поля",
            "example": "Логин пользователя"
          },
          "description": {
            "type": "string",
            "description": "Читаемое описание поля",
            "example": "Идентификатор пользователя полученный после регистрации в системе"
          },
          "required": {
            "type": "boolean",
            "description": "Поле не может быть пустым, если данное свойство установлено в true",
            "example": false
          },
          "placeholder": {
            "type": "string",
            "description": "Текст, присутствующий в поле ввода, перед тем как пользователь начинает вводить данные",
            "example": "Введите имя пользователя"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "password",
              "number",
              "textarea",
              "select",
              "radio",
              "checkbox",
              "array",
              "file"
            ]
          },
          "validationRule": {
            "type": "string",
            "description": "RegExp выражение для валидации поля на стороне клиента",
            "example": "^[a-zA-Z0-9_.-]*$"
          },
          "validationMessage": {
            "type": "string",
            "description": "Сообщению пользователю об формате вводимого значения",
            "example": "Поле логина должно содержать символы [a-zA-Z0-9_.-]"
          },
          "value": {
            "type": "string",
            "description": "Значение, которое должно быть предустановлено на UI",
            "example": "localhost"
          },
          "readOnly": {
            "type": "boolean",
            "description": "Разрешено ли пользователю редактировать поле",
            "example": true
          },
          "inline": {
            "type": "boolean",
            "description": "Маркер, для определения нужно ли фронту показывать поле в той же строке, что и предыдущее или с новой строки.",
            "example": false
          },
          "denyVariables": {
            "type": "boolean",
            "description": "Маркер, для того, что бы установить запрет на использование переменных в данном филде.",
            "example": false
          },
          "arrayIndex": {
            "type": "integer",
            "description": "Только для вложенных полей array. Может быть не заполнен для дефолтных значений, либо заполнен для сопоставления с входящими параметрами",
            "format": "int32",
            "example": 0
          },
          "size": {
            "type": "string",
            "enum": [
              "xs",
              "sm",
              "md",
              "lg",
              "xl",
              "xxl"
            ]
          },
          "isTrigger": {
            "type": "boolean",
            "description": "Если значение в поле было изменено, требуется перевыполнить запрос на получение полей",
            "example": false
          },
          "props": {
            "$ref": "#/components/schemas/ConstructorFieldProps"
          }
        },
        "description": "Метаданные полядля конструктора запроса, описывающие его атрибуты: тип, ограничения и перезапращиваемость"
      },
      "ConstructorFieldProps": {
        "type": "object",
        "properties": {
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConstructorFieldPropOption"
            }
          },
          "allowHandwriting": {
            "type": "boolean",
            "description": "Разрешить вводить значение не из списка (Применим для типа select)",
            "example": false
          },
          "allowMultiSelect": {
            "type": "boolean",
            "description": "Разрешить множественный выбор (Применим для типа select)",
            "example": false
          },
          "max": {
            "type": "integer",
            "description": "Максимальное значение для полей типа NUMBER",
            "format": "int32",
            "example": 100
          },
          "min": {
            "type": "integer",
            "description": "Минимальное значение для полей типа NUMBER",
            "format": "int32",
            "example": 10
          },
          "fields": {
            "type": "array",
            "description": "Поля в блоке (Применим для типа array)",
            "items": {
              "$ref": "#/components/schemas/ConstructorField"
            }
          },
          "maxFileSize": {
            "type": "integer",
            "description": "Максимальный размер файла для полей типа file",
            "format": "int32",
            "example": 100
          },
          "acceptFile": {
            "type": "string",
            "description": "Разрешенный тип файла для полей типа file",
            "example": ".csv"
          }
        },
        "description": "Дополнительные свойства полей"
      },
      "ConstructorFilter": {
        "type": "object",
        "properties": {
          "from": {
            "type": "integer",
            "description": "Дата в формате linux timestamp",
            "format": "int32",
            "example": 1729848300
          },
          "to": {
            "type": "integer",
            "description": "Дата в формате linux timestamp",
            "format": "int32",
            "example": 1729848300
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConstructorFilterField"
            }
          }
        },
        "description": "Фильтр для конструктора запросов по полям с данными и датой выборки"
      },
      "ConstructorFilterField": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "queryType"
          },
          "arrayIndex": {
            "type": "integer",
            "format": "int32",
            "example": 0
          },
          "value": {
            "type": "string",
            "example": "METRICS"
          }
        },
        "description": "Фильтр по полю, где ключ - название поля, значение - значение поля"
      },
      "ConstructorRequest": {
        "type": "object",
        "properties": {
          "pluginContext": {
            "$ref": "#/components/schemas/PluginContext"
          },
          "filter": {
            "$ref": "#/components/schemas/ConstructorFilter"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Переменные, которые потом будет подставлены в запросе. Переменная может быть строкой или массивом строк"
          }
        },
        "description": "Запрос полей из источника данных"
      },
      "Field": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Название метрики",
            "example": "The current number of live daemon threads"
          },
          "refID": {
            "type": "string",
            "description": "refID",
            "example": "id1"
          },
          "type": {
            "type": "string",
            "description": "Тип метрики",
            "example": "gauge"
          },
          "labels": {
            "type": "string",
            "description": "labels",
            "example": "?"
          },
          "values": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          }
        }
      },
      "Frame": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Название",
            "example": "The current number of live daemon threads"
          },
          "refID": {
            "type": "string",
            "description": "refID",
            "example": "id1"
          },
          "meta": {
            "type": "string",
            "description": "Метаданные",
            "example": "?"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Field"
            }
          }
        },
        "description": "Серии данных согласно запрошенным фильтрам"
      },
      "Pair": {
        "type": "object",
        "properties": {
          "value": {
            "type": "object"
          },
          "key": {
            "type": "object"
          },
          "left": {
            "type": "object"
          },
          "right": {
            "type": "object"
          }
        }
      },
      "QueryDataResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "boolean",
            "description": "Признак наличия ошибки",
            "example": false
          },
          "message": {
            "type": "string",
            "description": "Сообщение об ошибке при выполнении запроса"
          },
          "validationErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "description": "Ошибки валидации в формате Поле -> Ошибка"
            },
            "description": "Ошибки валидации в формате Поле -> Ошибка"
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "example": 200
          },
          "frames": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Frame"
            }
          }
        }
      },
      "DataQuery": {
        "type": "object",
        "properties": {
          "refID": {
            "type": "string",
            "description": "RefID",
            "example": "id1"
          },
          "codeQuery": {
            "type": "string",
            "description": "Текст прямого запроса в синтаксисе источника данных",
            "example": "node_exporter_build_info{goversion=\"go1.22.3\"}"
          },
          "maxDataPoints": {
            "type": "integer",
            "description": "Тип запроса",
            "format": "int64"
          },
          "timeRange": {
            "$ref": "#/components/schemas/TimeRange"
          },
          "json": {
            "type": "string",
            "description": "JSON со свободной структурой, которая будет зависеть от типа запроса",
            "example": "{\"metricName\":\"jvm_threads_daemon_threads\",\"serieName\":\"Потоки\",\"selectors\":{\"application\":\"prometheus-plugin-data\"},\"step\":\"15s\"}"
          }
        },
        "description": "Данные запроса"
      },
      "QueryDataRequest": {
        "type": "object",
        "properties": {
          "pluginContext": {
            "$ref": "#/components/schemas/PluginContext"
          },
          "dataQuery": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataQuery"
            }
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Переменные, которые потом будет подставлены в запросе. Переменная может быть строкой или массивом строк"
          }
        },
        "description": "Запрос данных из источника данных"
      },
      "TimeRange": {
        "type": "object",
        "properties": {
          "from": {
            "type": "integer",
            "format": "int64",
            "example": 1729848300
          },
          "to": {
            "type": "integer",
            "format": "int64",
            "example": 1729870200
          }
        },
        "description": "Временной диапазон [от] и [до] включительно, UNIX TIME"
      },
      "HealthCheckResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "boolean",
            "description": "Признак наличия ошибки",
            "example": false
          },
          "message": {
            "type": "string",
            "description": "Сообщение об ошибке при выполнении запроса"
          },
          "validationErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "description": "Ошибки валидации в формате Поле -> Ошибка"
            },
            "description": "Ошибки валидации в формате Поле -> Ошибка"
          },
          "status": {
            "type": "boolean",
            "example": true
          },
          "datasourceConfig": {
            "$ref": "#/components/schemas/DatasourceConfig"
          }
        }
      },
      "DataSourceConstructorRequest": {
        "type": "object",
        "properties": {
          "pluginContext": {
            "$ref": "#/components/schemas/PluginContext"
          },
          "filter": {
            "$ref": "#/components/schemas/ConstructorFilter"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Переменные, которые потом будет подставлены в запросе. Переменная может быть строкой или массивом строк"
          }
        },
        "description": "Запрос полей из источника данных"
      }
    }
  }
}
