{
 "openapi": "3.1.0",
 "info": {
  "title": "hw-connector",
  "description": "Агент кассы на ПК кассира: ККТ, банковские терминалы, печать PDF.\n\nВсё, что меняет состояние устройства, — **операция**: `POST` с заголовком `Idempotency-Key`\nвозвращает `202` и ссылку `/api/v1/operations/{id}`. С заголовком `Prefer: wait=30`\nагент ждёт результат до 30 секунд и отвечает `200`, если успел. Изменения операций\nприходят событиями `GET /api/v1/events` (Server-Sent Events). Суммы — в копейках.\n",
  "version": "2.2.0"
 },
 "servers": [
  {
   "url": "http://localhost:7790",
   "description": "Агент на компьютере кассира"
  }
 ],
 "paths": {
  "/api/v1/setup/workplace": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "Настройки рабочего места",
    "description": "Кассир, почта отправителя, место расчётов и СНО по умолчанию",
    "operationId": "getWorkplace",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Workplace"
        }
       }
      }
     }
    }
   },
   "put": {
    "tags": [
     "Настройка"
    ],
    "summary": "Сохранить настройки рабочего места",
    "description": "Подставляются в операции ККТ, где касса их не передала. Сохраняются в data/workplace.json",
    "operationId": "saveWorkplace",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Workplace"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Workplace"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/printers/settings": {
   "put": {
    "tags": [
     "Настройка"
    ],
    "summary": "Настройки печати принтера",
    "description": "Бумага без полей нужного размера (бланк билета), масштаб, ориентация",
    "operationId": "setPrinterSettings",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PrinterSettingsRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/PrinterSettings"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/printers/roles": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "Назначения принтеров",
    "operationId": "roles",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/PrinterRole"
         }
        }
       }
      }
     }
    }
   },
   "put": {
    "tags": [
     "Настройка"
    ],
    "summary": "Назначить принтеры",
    "description": "{\"tickets\": \"имя принтера\", \"documents\": \"\"}; пусто — принтер по умолчанию",
    "operationId": "setRoles",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "additionalProperties": {
         "type": "string"
        }
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/PrinterRole"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/language": {
   "put": {
    "tags": [
     "Агент"
    ],
    "summary": "Сменить язык интерфейса агента",
    "description": "ru или en; открытые страницы получают событие language",
    "operationId": "set",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LanguageRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {
          "type": "string"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/devices/{number}": {
   "put": {
    "tags": [
     "Настройка"
    ],
    "summary": "Добавить или изменить устройство",
    "description": "Применяется сразу и сохраняется в data/devices.json",
    "operationId": "save",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeviceSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/DeviceConfig"
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "Настройка"
    ],
    "summary": "Удалить устройство",
    "operationId": "delete",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/api/v1/setup/access": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "Доступ и печать",
    "description": "Разрешённые сайты, токен API, откуда можно печатать PDF и ограничения скачивания",
    "operationId": "getAccess",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/AccessView"
        }
       }
      }
     }
    }
   },
   "put": {
    "tags": [
     "Настройка"
    ],
    "summary": "Сохранить доступ и печать",
    "description": "Действует сразу, без перезапуска. Сохраняется в data/access.json; поле null — значение из config/application.yml",
    "operationId": "saveAccess",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AccessSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/AccessView"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/settlements": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Сверка итогов",
    "description": "Закрытие дня на терминале; слип — в результате",
    "operationId": "settlement",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/reports": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Отчёт терминала",
    "description": "Операции смены без сверки с банком; full=true — по каждой операции. Слип — в результате",
    "operationId": "report",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "full",
      "in": "query",
      "required": false,
      "schema": {
       "type": "boolean",
       "default": false
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/refunds": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Возврат на карту",
    "description": "По оплате прошлых дней, после сверки итогов",
    "operationId": "refund",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReversalRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/payments": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Оплата картой",
    "operationId": "pay",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PaymentRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/emergency-reversals": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Аварийная отмена последней операции",
    "description": "Когда касса не получила результат оплаты (обрыв связи, зависание): терминал отменяет свою последнюю операцию",
    "operationId": "emergencyReversal",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EmergencyReversalRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/terminals/{id}/cancellations": {
   "post": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Отмена оплаты",
    "description": "В тот же день, до сверки итогов; деньги не списываются с карты",
    "operationId": "cancel",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReversalRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/printers/test": {
   "post": {
    "tags": [
     "Настройка"
    ],
    "summary": "Напечатать тестовую страницу",
    "operationId": "testPrint",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TestPrint"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/CheckResult"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/devices/{number}/check": {
   "post": {
    "tags": [
     "Настройка"
    ],
    "summary": "Проверить связь",
    "description": "Без денежных операций: ККТ — состояние смены, терминал — ПО банка или вход на терминал",
    "operationId": "check",
    "parameters": [
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/CheckResult"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/shift/open": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Открыть смену",
    "operationId": "openShift",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OperatorRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/shift/close": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Закрыть смену (Z-отчёт)",
    "description": "Z-отчёт по закону и есть отчёт о закрытии смены: отдельно от закрытия его не бывает",
    "operationId": "closeShift",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OperatorRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/reports/x": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "X-отчёт",
    "operationId": "xReport",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OperatorRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/reports/calculation-state": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Отчёт о текущем состоянии расчётов",
    "description": "Фискальный документ из ФН: сколько документов не передано в ОФД и с какой даты",
    "operationId": "calculationStateReport",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OperatorRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/receipts": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Пробить чек",
    "description": "Только чек на ККТ. Чтобы вместе с оплатой картой — POST /api/v1/checkouts",
    "operationId": "receipt",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Receipt"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/fn-documents/{number}/print": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Напечатать копию документа из ФН",
    "description": "АТОЛ, Пирит: документ из архива ФН по номеру",
    "operationId": "printFnDocument",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int64",
       "exclusiveMinimum": 0
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/documents": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Напечатать нефискальный текст",
    "description": "Слип терминала, служебные документы",
    "operationId": "document",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TextRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/corrections": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Пробить чек коррекции",
    "description": "Тип чека — как у исправляемого расчёта: SELL, SELL_RETURN, BUY, BUY_RETURN",
    "operationId": "correction",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CorrectionRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/cash/out": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Выплата наличных",
    "operationId": "cashOut",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CashRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/cash/in": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Внесение наличных",
    "operationId": "cashIn",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CashRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/cash-drawer/open": {
   "post": {
    "tags": [
     "ККТ"
    ],
    "summary": "Открыть денежный ящик",
    "description": "Ящик подключён к ККТ; тело запроса не нужно",
    "operationId": "openCashDrawer",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/print-jobs": {
   "post": {
    "tags": [
     "Печать"
    ],
    "summary": "Печать",
    "description": "PDF по ссылкам, готовый PDF или картинки — с настройками принтера (масштаб, бумага);\nraw — команды ESC/POS, ZPL, EPL напрямую на принтер. Ссылки скачиваются до печати",
    "operationId": "print",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PrintJobRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/displays/{id}": {
   "get": {
    "tags": [
     "Дисплей покупателя"
    ],
    "summary": "Что показано на дисплее",
    "description": "Для дисплея на втором мониторе: страница берёт отсюда строки при открытии",
    "operationId": "shown",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {}
        }
       }
      }
     }
    }
   },
   "post": {
    "tags": [
     "Дисплей покупателя"
    ],
    "summary": "Показать строки на дисплее покупателя",
    "description": "VFD — обычно 2 строки по 20 символов; второй монитор — до 10 строк крупно. Сразу, не операция",
    "operationId": "show",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DisplayRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/api/v1/displays/{id}/qr": {
   "post": {
    "tags": [
     "Дисплей покупателя"
    ],
    "summary": "Показать QR-код на дисплее покупателя",
    "description": "Дисплей QR-кодов (Mertech QR-PA, QR-Screen) или второй монитор. Пустой payload — убрать QR. Сразу, не операция",
    "operationId": "qr",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QrRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/api/v1/checkouts": {
   "post": {
    "tags": [
     "Продажа"
    ],
    "summary": "Продажа или возврат с чеком",
    "description": "Порядок: операция по карте на терминале (если есть оплата CARD) → чек на ККТ → слип на ККТ.\nЕсли чек не напечатался после оплаты картой, оплата отменяется на терминале (ошибка PAYMENT_CANCELLED);\nесли и отмена не прошла — PAYMENT_NOT_CANCELLED с данными оплаты в error.details.\nРезультат: { receipt: фискальный документ, payment: операция по карте }.",
    "operationId": "checkout",
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CheckoutRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/channels/{id}/exchange": {
   "post": {
    "tags": [
     "Порт устройства"
    ],
    "summary": "Отправить байты в порт и получить ответ",
    "description": "Только для портов, добавленных на странице настройки (вид «Порт устройства»). Сразу, не операция",
    "operationId": "exchange",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ExchangeRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/ExchangeResult"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/cash-drawers/{id}/open": {
   "post": {
    "tags": [
     "Денежный ящик"
    ],
    "summary": "Открыть денежный ящик",
    "description": "id — устройство, к которому подключён ящик: ККТ, принтер ESC/POS или ящик на COM-порту. Сразу, не операция",
    "operationId": "open",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     }
    }
   }
  },
  "/api/v1/terminals/{id}/last-slip": {
   "get": {
    "tags": [
     "Банковский терминал"
    ],
    "summary": "Последний слип терминала",
    "description": "Слип последней успешной операции из журнала (оплата, возврат, отмена, сверка, продажа) — чтобы напечатать его ещё раз",
    "operationId": "lastSlip",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {}
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/types": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "Поддерживаемые устройства и их поля настройки",
    "operationId": "types",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Type"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/ports": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "COM-порты компьютера",
    "operationId": "ports",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Port"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/setup/devices": {
   "get": {
    "tags": [
     "Настройка"
    ],
    "summary": "Настройки устройств",
    "operationId": "list",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/DeviceConfig"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/shift": {
   "get": {
    "tags": [
     "ККТ"
    ],
    "summary": "Состояние смены",
    "description": "Читается с ККТ; если ККТ занята другой операцией дольше 10 с — 409",
    "operationId": "shift",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/ShiftState"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/fn-documents/{number}": {
   "get": {
    "tags": [
     "ККТ"
    ],
    "summary": "Документ из ФН по номеру",
    "description": "Реквизиты документа из архива ФН (АТОЛ, Штрих-М): ответ ККТ как есть — у Штрих-М список тегов {tag, value}",
    "operationId": "fnDocument",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     },
     {
      "name": "number",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int64",
       "exclusiveMinimum": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {}
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/registers/{id}/counters": {
   "get": {
    "tags": [
     "ККТ"
    ],
    "summary": "Счётчики ККТ",
    "description": "Число чеков и суммы по признакам расчёта за смену и за всё время ФН (АТОЛ — ответ драйвера как есть); суммы в копейках",
    "operationId": "counters",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "integer",
       "format": "int32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {}
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/qr": {
   "get": {
    "tags": [
     "Банковские терминалы"
    ],
    "summary": "QR-код картинкой PNG",
    "description": "text — что закодировать, например payload из события qr; size — сторона в пикселях (100–1200)",
    "operationId": "qr_1",
    "parameters": [
     {
      "name": "text",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "size",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 400
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "string",
         "format": "byte"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/printers": {
   "get": {
    "tags": [
     "Печать"
    ],
    "summary": "Принтеры Windows, их назначения и настройки печати",
    "operationId": "printers",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/PrinterInfo"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/operations": {
   "get": {
    "tags": [
     "Операции"
    ],
    "summary": "Последние операции",
    "description": "Новые первыми; журнал хранит 1000 последних, в том числе после перезапуска",
    "operationId": "recent",
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
       "type": "integer",
       "format": "int32",
       "default": 50
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Operation"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/operations/{id}": {
   "get": {
    "tags": [
     "Операции"
    ],
    "summary": "Операция",
    "description": "С заголовком Prefer: wait=N ждёт окончания до N секунд",
    "operationId": "get",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "name": "Prefer",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/Operation"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/language": {
   "get": {
    "tags": [
     "Агент"
    ],
    "summary": "Язык интерфейса агента",
    "description": "ru или en",
    "operationId": "get_1",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "object",
         "additionalProperties": {
          "type": "string"
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/health": {
   "get": {
    "tags": [
     "Агент"
    ],
    "summary": "Агент работает",
    "description": "Версия, время запуска, питание; клиент проверяет, что агент установлен",
    "operationId": "health",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "$ref": "#/components/schemas/AgentInfo"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/events": {
   "get": {
    "tags": [
     "Операции"
    ],
    "summary": "События (Server-Sent Events)",
    "description": "event: operation, data: операция — при каждом изменении статуса или этапа. Токен можно передать в ?access_token=",
    "operationId": "events",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "text/event-stream": {
        "schema": {
         "$ref": "#/components/schemas/SseEmitter"
        }
       }
      }
     }
    }
   }
  },
  "/api/v1/devices": {
   "get": {
    "tags": [
     "Агент"
    ],
    "summary": "Устройства рабочего места",
    "operationId": "devices",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "*/*": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/DeviceInfo"
         }
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "Workplace": {
    "type": "object",
    "description": "Настройки рабочего места",
    "properties": {
     "cashierName": {
      "type": "string",
      "maxLength": 64,
      "minLength": 0
     },
     "cashierInn": {
      "type": "string",
      "pattern": "\\d{12}"
     },
     "senderEmail": {
      "type": "string",
      "format": "email",
      "maxLength": 64,
      "minLength": 0
     },
     "settlementPlace": {
      "type": "string",
      "maxLength": 128,
      "minLength": 0
     },
     "taxation": {
      "type": "string",
      "enum": [
       "OSN",
       "USN_INCOME",
       "USN_INCOME_OUTCOME",
       "ESHN",
       "PATENT"
      ]
     }
    }
   },
   "PrinterSettings": {
    "type": "object",
    "properties": {
     "scaling": {
      "type": "string",
      "enum": [
       "ACTUAL",
       "FIT",
       "SHRINK"
      ]
     },
     "orientation": {
      "type": "string",
      "enum": [
       "AUTO",
       "PORTRAIT",
       "LANDSCAPE"
      ]
     },
     "paperWidthMm": {
      "type": "number",
      "format": "double",
      "exclusiveMinimum": 0
     },
     "paperHeightMm": {
      "type": "number",
      "format": "double",
      "exclusiveMinimum": 0
     }
    }
   },
   "PrinterSettingsRequest": {
    "type": "object",
    "properties": {
     "printer": {
      "type": "string",
      "minLength": 1
     },
     "settings": {
      "$ref": "#/components/schemas/PrinterSettings"
     }
    },
    "required": [
     "printer"
    ]
   },
   "PrinterRole": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "printer": {
      "type": "string"
     }
    }
   },
   "LanguageRequest": {
    "type": "object",
    "properties": {
     "language": {
      "type": "string",
      "minLength": 1
     }
    },
    "required": [
     "language"
    ]
   },
   "DeviceSettings": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "minLength": 1
     },
     "name": {
      "type": "string"
     },
     "active": {
      "type": "boolean"
     },
     "params": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      }
     }
    },
    "required": [
     "type"
    ]
   },
   "DeviceConfig": {
    "type": "object",
    "properties": {
     "number": {
      "type": "integer",
      "format": "int32"
     },
     "type": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "active": {
      "type": "boolean"
     },
     "params": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      }
     }
    }
   },
   "AccessSettings": {
    "type": "object",
    "properties": {
     "allowedOrigins": {
      "type": "array",
      "items": {
       "type": "string",
       "pattern": "https?://[^/\\s]+"
      },
      "maxItems": 20,
      "minItems": 0
     },
     "apiToken": {
      "type": "string",
      "maxLength": 200,
      "minLength": 0
     },
     "printUrlPrefixes": {
      "type": "array",
      "items": {
       "type": "string",
       "pattern": "https?://\\S+"
      },
      "maxItems": 20,
      "minItems": 0
     },
     "downloadTimeoutSec": {
      "type": "integer",
      "format": "int32",
      "maximum": 600,
      "minimum": 1
     },
     "maxFileSizeMb": {
      "type": "integer",
      "format": "int32",
      "maximum": 500,
      "minimum": 1
     },
     "maxUrlsPerRequest": {
      "type": "integer",
      "format": "int32",
      "maximum": 1000,
      "minimum": 1
     }
    }
   },
   "AccessView": {
    "type": "object",
    "properties": {
     "settings": {
      "$ref": "#/components/schemas/AccessSettings"
     },
     "defaults": {
      "$ref": "#/components/schemas/AccessSettings"
     }
    }
   },
   "Operation": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "type": {
      "type": "string"
     },
     "idempotencyKey": {
      "type": "string"
     },
     "resources": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "status": {
      "type": "string",
      "enum": [
       "QUEUED",
       "RUNNING",
       "SUCCEEDED",
       "FAILED",
       "UNKNOWN"
      ]
     },
     "stage": {
      "type": "string"
     },
     "createdAt": {
      "type": "string",
      "format": "date-time"
     },
     "startedAt": {
      "type": "string",
      "format": "date-time"
     },
     "finishedAt": {
      "type": "string",
      "format": "date-time"
     },
     "result": {},
     "error": {
      "$ref": "#/components/schemas/OperationError"
     },
     "warnings": {
      "type": "array",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "OperationError": {
    "type": "object",
    "properties": {
     "code": {
      "type": "string"
     },
     "message": {
      "type": "string"
     },
     "details": {}
    }
   },
   "ReversalRequest": {
    "type": "object",
    "properties": {
     "amount": {
      "type": "integer",
      "format": "int64",
      "exclusiveMinimum": 0
     },
     "paymentRef": {
      "type": "string",
      "minLength": 1
     }
    },
    "required": [
     "paymentRef"
    ]
   },
   "PaymentRequest": {
    "type": "object",
    "properties": {
     "amount": {
      "type": "integer",
      "format": "int64",
      "exclusiveMinimum": 0
     }
    }
   },
   "EmergencyReversalRequest": {
    "type": "object",
    "properties": {
     "amount": {
      "type": "integer",
      "format": "int64",
      "exclusiveMinimum": 0
     },
     "paymentRef": {
      "type": "string"
     }
    }
   },
   "TestPrint": {
    "type": "object",
    "properties": {
     "printer": {
      "type": "string"
     }
    }
   },
   "CheckResult": {
    "type": "object",
    "properties": {
     "ok": {
      "type": "boolean"
     },
     "message": {
      "type": "string"
     },
     "details": {
      "type": "object",
      "additionalProperties": {}
     }
    }
   },
   "Operator": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1
     },
     "inn": {
      "type": "string"
     }
    },
    "required": [
     "name"
    ]
   },
   "OperatorRequest": {
    "type": "object",
    "properties": {
     "operator": {
      "$ref": "#/components/schemas/Operator"
     }
    }
   },
   "Customer": {
    "type": "object",
    "properties": {
     "contact": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "inn": {
      "type": "string"
     }
    }
   },
   "Receipt": {
    "type": "object",
    "description": "Кассовый чек",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "SELL",
       "SELL_RETURN",
       "BUY",
       "BUY_RETURN"
      ]
     },
     "taxation": {
      "type": "string",
      "enum": [
       "OSN",
       "USN_INCOME",
       "USN_INCOME_OUTCOME",
       "ESHN",
       "PATENT"
      ]
     },
     "operator": {
      "$ref": "#/components/schemas/Operator"
     },
     "customer": {
      "$ref": "#/components/schemas/Customer"
     },
     "header": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TextLine"
      }
     },
     "items": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReceiptItem"
      },
      "minItems": 1
     },
     "payments": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReceiptPayment"
      },
      "minItems": 1
     },
     "footer": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TextLine"
      }
     },
     "electronic": {
      "type": "boolean"
     },
     "senderEmail": {
      "type": "string"
     },
     "settlementPlace": {
      "type": "string"
     }
    },
    "required": [
     "items",
     "payments",
     "type"
    ]
   },
   "ReceiptItem": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1
     },
     "price": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
     },
     "quantity": {
      "type": "number",
      "exclusiveMinimum": 0
     },
     "amount": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
     },
     "vat": {
      "type": "string",
      "enum": [
       "NONE",
       "VAT0",
       "VAT5",
       "VAT7",
       "VAT10",
       "VAT20",
       "VAT22",
       "VAT105",
       "VAT107",
       "VAT110",
       "VAT120",
       "VAT122"
      ]
     },
     "paymentMethod": {
      "type": "string",
      "enum": [
       "FULL_PREPAYMENT",
       "PREPAYMENT",
       "ADVANCE",
       "FULL_PAYMENT",
       "PARTIAL_PAYMENT",
       "CREDIT",
       "CREDIT_PAYMENT"
      ]
     },
     "paymentObject": {
      "type": "string",
      "enum": [
       "COMMODITY",
       "EXCISE",
       "JOB",
       "SERVICE",
       "GAMBLING_BET",
       "GAMBLING_PRIZE",
       "LOTTERY",
       "LOTTERY_PRIZE",
       "INTELLECTUAL_ACTIVITY",
       "PAYMENT",
       "AGENT_COMMISSION",
       "COMPOSITE",
       "ANOTHER"
      ]
     },
     "department": {
      "type": "integer",
      "format": "int32"
     }
    },
    "required": [
     "name",
     "paymentMethod",
     "paymentObject",
     "quantity",
     "vat"
    ]
   },
   "ReceiptPayment": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "CASH",
       "CARD",
       "PREPAID",
       "CREDIT",
       "OTHER"
      ]
     },
     "amount": {
      "type": "integer",
      "format": "int64",
      "exclusiveMinimum": 0
     }
    },
    "required": [
     "type"
    ]
   },
   "TextLine": {
    "type": "object",
    "properties": {
     "kind": {
      "type": "string",
      "enum": [
       "TEXT",
       "PAIR",
       "SEPARATOR"
      ]
     },
     "text": {
      "type": "string"
     },
     "right": {
      "type": "string"
     },
     "align": {
      "type": "string",
      "enum": [
       "LEFT",
       "CENTER",
       "RIGHT"
      ]
     }
    },
    "required": [
     "kind"
    ]
   },
   "TextRequest": {
    "type": "object",
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TextLine"
      },
      "minItems": 1
     }
    },
    "required": [
     "lines"
    ]
   },
   "Correction": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "SELF",
       "INSTRUCTION"
      ]
     },
     "baseDate": {
      "type": "string",
      "format": "date"
     },
     "baseNumber": {
      "type": "string"
     }
    },
    "required": [
     "baseDate",
     "type"
    ]
   },
   "CorrectionRequest": {
    "type": "object",
    "properties": {
     "receipt": {
      "$ref": "#/components/schemas/Receipt"
     },
     "correction": {
      "$ref": "#/components/schemas/Correction"
     }
    },
    "required": [
     "correction",
     "receipt"
    ]
   },
   "CashRequest": {
    "type": "object",
    "properties": {
     "operator": {
      "$ref": "#/components/schemas/Operator"
     },
     "amount": {
      "type": "integer",
      "format": "int64",
      "exclusiveMinimum": 0
     }
    }
   },
   "PrintJobRequest": {
    "type": "object",
    "properties": {
     "urls": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "document": {
      "type": "string"
     },
     "images": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "raw": {
      "type": "string"
     },
     "text": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TextLine"
      }
     },
     "printer": {
      "type": "string"
     },
     "device": {
      "type": "integer",
      "format": "int32"
     },
     "role": {
      "type": "string"
     },
     "copies": {
      "type": "integer",
      "format": "int32",
      "maximum": 20,
      "minimum": 1
     }
    }
   },
   "DisplayRequest": {
    "type": "object",
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "maxItems": 20,
      "minItems": 0
     }
    },
    "required": [
     "lines"
    ]
   },
   "QrRequest": {
    "type": "object",
    "properties": {
     "payload": {
      "type": "string",
      "maxLength": 2000,
      "minLength": 0
     },
     "top": {
      "type": "string",
      "maxLength": 100,
      "minLength": 0
     },
     "bottom": {
      "type": "string",
      "maxLength": 100,
      "minLength": 0
     }
    }
   },
   "CheckoutRequest": {
    "type": "object",
    "properties": {
     "registerId": {
      "type": "integer",
      "format": "int32",
      "exclusiveMinimum": 0
     },
     "terminalId": {
      "type": "integer",
      "format": "int32"
     },
     "receipt": {
      "$ref": "#/components/schemas/Receipt"
     },
     "originalPaymentRef": {
      "type": "string"
     },
     "printSlip": {
      "type": "boolean"
     }
    },
    "required": [
     "receipt"
    ]
   },
   "ExchangeRequest": {
    "type": "object",
    "properties": {
     "hex": {
      "type": "string"
     },
     "base64": {
      "type": "string"
     },
     "text": {
      "type": "string"
     },
     "charset": {
      "type": "string"
     },
     "readTimeoutMs": {
      "type": "integer",
      "format": "int32",
      "maximum": 60000,
      "minimum": 0
     },
     "maxBytes": {
      "type": "integer",
      "format": "int32",
      "maximum": 65536,
      "minimum": 1
     },
     "until": {
      "type": "string"
     }
    }
   },
   "ExchangeResult": {
    "type": "object",
    "properties": {
     "bytes": {
      "type": "integer",
      "format": "int32"
     },
     "hex": {
      "type": "string"
     },
     "base64": {
      "type": "string"
     },
     "text": {
      "type": "string"
     }
    }
   },
   "Field": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "label": {
      "type": "string"
     },
     "input": {
      "type": "string"
     },
     "defaultValue": {
      "type": "string"
     },
     "options": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Option"
      }
     },
     "help": {
      "type": "string"
     },
     "showIf": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      }
     },
     "required": {
      "type": "boolean"
     }
    }
   },
   "Option": {
    "type": "object",
    "properties": {
     "value": {
      "type": "string"
     },
     "label": {
      "type": "string"
     }
    }
   },
   "Type": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "enum": [
       "FISCAL_REGISTER",
       "PAYMENT_TERMINAL",
       "BARCODE_SCANNER",
       "PRINTER",
       "CASH_DRAWER",
       "CUSTOMER_DISPLAY",
       "CARD_READER",
       "CHANNEL"
      ]
     },
     "title": {
      "type": "string"
     },
     "vendor": {
      "type": "string"
     },
     "description": {
      "type": "string"
     },
     "fields": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Field"
      }
     },
     "developer": {
      "type": "boolean"
     }
    }
   },
   "Port": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "description": {
      "type": "string"
     }
    }
   },
   "ShiftState": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "OPENED",
       "CLOSED",
       "EXPIRED"
      ]
     },
     "number": {
      "type": "integer",
      "format": "int32"
     }
    }
   },
   "PrinterInfo": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "isDefault": {
      "type": "boolean"
     },
     "roles": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "settings": {
      "$ref": "#/components/schemas/PrinterSettings"
     }
    }
   },
   "AgentInfo": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string"
     },
     "version": {
      "type": "string"
     },
     "startedAt": {
      "type": "string",
      "format": "date-time"
     },
     "power": {
      "$ref": "#/components/schemas/Power"
     }
    }
   },
   "Power": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "enum": [
       "AC",
       "BATTERY",
       "UNKNOWN"
      ]
     },
     "battery": {
      "type": "boolean"
     },
     "batteryPercent": {
      "type": "integer",
      "format": "int32"
     },
     "minutesLeft": {
      "type": "integer",
      "format": "int32"
     },
     "at": {
      "type": "string",
      "format": "date-time"
     }
    }
   },
   "SseEmitter": {
    "type": "object",
    "properties": {
     "timeout": {
      "type": "integer",
      "format": "int64"
     }
    }
   },
   "DeviceInfo": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer",
      "format": "int32"
     },
     "kind": {
      "type": "string",
      "enum": [
       "FISCAL_REGISTER",
       "PAYMENT_TERMINAL",
       "BARCODE_SCANNER",
       "PRINTER",
       "CASH_DRAWER",
       "CUSTOMER_DISPLAY",
       "CARD_READER",
       "CHANNEL"
      ]
     },
     "type": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "active": {
      "type": "boolean"
     },
     "info": {
      "type": "object",
      "additionalProperties": {}
     }
    }
   }
  }
 }
}