{
  "openapi": "3.0.0",
  "paths": {
    "/catalog/products": {
      "get": {
        "operationId": "catalog_listProducts",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "categoryId",
            "required": false,
            "in": "query",
            "schema": {
              "nullable": true,
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "default": "active",
              "type": "string",
              "enum": [
                "active",
                "hidden",
                "all"
              ]
            }
          },
          {
            "name": "priceMin",
            "required": false,
            "in": "query",
            "description": "Мин. цена в копейках",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "priceMax",
            "required": false,
            "in": "query",
            "description": "Макс. цена в копейках",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "brand",
            "required": false,
            "in": "query",
            "description": "Фильтр по бренду (точное совпадение).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "attr",
            "required": false,
            "in": "query",
            "description": "Карта фильтров по характеристикам: attr[<attributeId>]=<значение | minNumber:maxNumber | optionId>",
            "schema": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "name",
                "sku",
                "price",
                "brand",
                "model",
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "include",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "stock"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ProductResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список товаров.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "post": {
        "operationId": "catalog_createProduct",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProductDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать товар.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/products/{id}": {
      "get": {
        "operationId": "catalog_getProduct",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить товар.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "patch": {
        "operationId": "catalog_updateProduct",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateProductDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить товар.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      },
      "delete": {
        "operationId": "catalog_removeProduct",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Скрыть товар (soft-delete).",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/services": {
      "get": {
        "operationId": "catalog_listServices",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "categoryId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "default": "active",
              "type": "string",
              "enum": [
                "active",
                "hidden",
                "all"
              ]
            }
          },
          {
            "name": "priceMin",
            "required": false,
            "in": "query",
            "description": "Мин. цена в копейках",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "priceMax",
            "required": false,
            "in": "query",
            "description": "Макс. цена в копейках",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "priceModel",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "fixed",
                "per_hour",
                "per_minute",
                "per_day",
                "per_item"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "name",
                "sku",
                "price",
                "totalCost",
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ServiceResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список услуг.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "post": {
        "operationId": "catalog_createService",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateServiceDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать услугу.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/services/{id}": {
      "get": {
        "operationId": "catalog_getService",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить услугу.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "patch": {
        "operationId": "catalog_updateService",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateServiceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить услугу.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      },
      "delete": {
        "operationId": "catalog_removeService",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Скрыть услугу.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/categories": {
      "get": {
        "operationId": "catalog_listCategories",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CategoryResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список категорий.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "post": {
        "operationId": "catalog_createCategory",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCategoryDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать категорию.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/categories/{id}": {
      "get": {
        "operationId": "catalog_getCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить категорию.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      },
      "patch": {
        "operationId": "catalog_updateCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCategoryDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить категорию.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      },
      "delete": {
        "operationId": "catalog_removeCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Удалить категорию.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:write"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/products/{id}/variants": {
      "get": {
        "description": "Идентификаторы вариантов нужны в `variantId` строк заказа, продажи и приёмки, а также в корректировке остатков.",
        "operationId": "catalog_listVariants",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductVariantResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Варианты товара (SKU по размеру, цвету и т. п.).",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/attributes": {
      "get": {
        "description": "Идентификаторы атрибутов и их опций подставляются в `attributes[]` при создании и изменении товара.",
        "operationId": "catalog_listAttributes",
        "parameters": [
          {
            "name": "categoryId",
            "required": false,
            "in": "query",
            "schema": {
              "nullable": true,
              "type": "string"
            }
          },
          {
            "name": "primaryOnly",
            "required": false,
            "in": "query",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AttributeDefinitionResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Атрибуты товаров с вариантами значений.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      }
    },
    "/catalog/units": {
      "get": {
        "description": "Идентификаторы — для `unitId` и `packUnitId` товара.",
        "operationId": "catalog_listUnits",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UnitResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Единицы измерения компании.",
        "tags": [
          "external/catalog"
        ],
        "x-scopes": [
          "catalog:read"
        ],
        "x-module": "catalog"
      }
    },
    "/clients": {
      "get": {
        "operationId": "clients_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "displayName",
              "type": "string",
              "enum": [
                "displayName",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "asc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "legal"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "archived"
              ]
            }
          },
          {
            "name": "assignedToId",
            "required": false,
            "in": "query",
            "description": "ID ответственного сотрудника",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "required": false,
            "in": "query",
            "description": "Один тег для фильтра",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ClientListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список клиентов.",
        "tags": [
          "external/clients"
        ],
        "x-scopes": [
          "clients:read"
        ],
        "x-module": "clients"
      },
      "post": {
        "operationId": "clients_create",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateClientDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать клиента.",
        "tags": [
          "external/clients"
        ],
        "x-scopes": [
          "clients:write"
        ],
        "x-module": "clients"
      }
    },
    "/clients/{id}": {
      "get": {
        "operationId": "clients_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить клиента.",
        "tags": [
          "external/clients"
        ],
        "x-scopes": [
          "clients:read"
        ],
        "x-module": "clients"
      },
      "patch": {
        "operationId": "clients_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateClientDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить клиента.",
        "tags": [
          "external/clients"
        ],
        "x-scopes": [
          "clients:write"
        ],
        "x-module": "clients"
      }
    },
    "/clients/{id}/archive": {
      "post": {
        "description": "Команда над существующим клиентом — отвечает 200.",
        "operationId": "clients_archive",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClientResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Архивировать клиента (soft-delete).",
        "tags": [
          "external/clients"
        ],
        "x-scopes": [
          "clients:write"
        ],
        "x-module": "clients"
      }
    },
    "/orders": {
      "get": {
        "operationId": "orders_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt",
                "number",
                "dueAt",
                "readyBy",
                "payDueAt",
                "total",
                "status",
                "paymentStatus"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "new",
                "confirmed",
                "in_progress",
                "ready",
                "completed",
                "cancelled"
              ]
            }
          },
          {
            "name": "paymentStatus",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "unpaid",
                "partial",
                "paid",
                "refunded"
              ]
            }
          },
          {
            "name": "assignedToId",
            "required": false,
            "in": "query",
            "description": "ID ответственного сотрудника",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "createdById",
            "required": false,
            "in": "query",
            "description": "ID создателя",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "description": "ID клиента",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "required": false,
            "in": "query",
            "description": "Создан от (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateTo",
            "required": false,
            "in": "query",
            "description": "Создан до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dueFrom",
            "required": false,
            "in": "query",
            "description": "Срок от (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dueTo",
            "required": false,
            "in": "query",
            "description": "Срок до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OrderListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список заказов.",
        "tags": [
          "external/orders"
        ],
        "x-scopes": [
          "orders:read"
        ],
        "x-module": "orders"
      },
      "post": {
        "operationId": "orders_create",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать заказ.",
        "tags": [
          "external/orders"
        ],
        "x-scopes": [
          "orders:write"
        ],
        "x-module": "orders"
      }
    },
    "/orders/{id}": {
      "get": {
        "operationId": "orders_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить заказ.",
        "tags": [
          "external/orders"
        ],
        "x-scopes": [
          "orders:read"
        ],
        "x-module": "orders"
      },
      "patch": {
        "operationId": "orders_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOrderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить заказ.",
        "tags": [
          "external/orders"
        ],
        "x-scopes": [
          "orders:write"
        ],
        "x-module": "orders"
      }
    },
    "/orders/{id}/status/{next}": {
      "post": {
        "description": "Команда над существующим заказом — отвечает 200 с обновлённым заказом. Недопустимый переход — 409 `ORDER_STATUS_TRANSITION_INVALID`, значение вне перечня — 400.",
        "operationId": "orders_changeStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "next",
            "required": true,
            "in": "path",
            "description": "Целевой статус заказа",
            "schema": {
              "$ref": "#/components/schemas/OrderStatus"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Сменить статус заказа.",
        "tags": [
          "external/orders"
        ],
        "x-scopes": [
          "orders:write"
        ],
        "x-module": "orders"
      }
    },
    "/sales": {
      "get": {
        "operationId": "sales_listSales",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt",
                "number",
                "total"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "shiftId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cashierId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "paymentMethod",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "cash",
                "card",
                "sbp",
                "mixed"
              ]
            }
          },
          {
            "name": "dateFrom",
            "required": false,
            "in": "query",
            "description": "ISO 8601",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateTo",
            "required": false,
            "in": "query",
            "description": "ISO 8601",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "default": "all",
              "type": "string",
              "enum": [
                "all",
                "sale",
                "refund"
              ]
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "description": "Фильтр по клиенту",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SaleListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Журнал продаж.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:read"
        ],
        "x-module": "cashier"
      },
      "post": {
        "operationId": "sales_createSale",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSaleDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать продажу.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:write"
        ],
        "x-module": "cashier"
      }
    },
    "/sales/{id}": {
      "get": {
        "operationId": "sales_getSale",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить продажу.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:read"
        ],
        "x-module": "cashier"
      }
    },
    "/sales/{id}/refund": {
      "post": {
        "description": "Команда над существующей продажей — отвечает 200.",
        "operationId": "sales_refundSale",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Оформить возврат продажи целиком.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:write"
        ],
        "x-module": "cashier"
      }
    },
    "/shifts/open": {
      "post": {
        "operationId": "sales_openShift",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenShiftDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Открыть смену.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:write"
        ],
        "x-module": "cashier"
      }
    },
    "/shifts/current": {
      "get": {
        "description": "Смена, открытая этим же API-токеном через `POST /shifts/open` и ещё не закрытая. Нужна, чтобы восстановить `shiftId` для `POST /sales`, если ответ открытия потерян. Открытой смены нет — 404 `SHIFT_NOT_FOUND`.",
        "operationId": "sales_currentShift",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Текущая открытая смена интеграции.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:read"
        ],
        "x-module": "cashier"
      }
    },
    "/shifts/{id}": {
      "get": {
        "operationId": "sales_getShift",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить смену.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:read"
        ],
        "x-module": "cashier"
      }
    },
    "/shifts/{id}/close": {
      "post": {
        "description": "Команда над существующей сменой — отвечает 200.",
        "operationId": "sales_closeShift",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseShiftDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShiftResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Закрыть смену.",
        "tags": [
          "external/sales"
        ],
        "x-scopes": [
          "sales:write"
        ],
        "x-module": "cashier"
      }
    },
    "/warehouse/warehouses": {
      "get": {
        "operationId": "warehouse_listWarehouses",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "name",
              "type": "string",
              "enum": [
                "name",
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "asc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WarehouseListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список складов.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      },
      "post": {
        "operationId": "warehouse_createWarehouse",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWarehouseDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать склад.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/warehouses/{id}": {
      "get": {
        "operationId": "warehouse_getWarehouse",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить склад.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      },
      "patch": {
        "operationId": "warehouse_updateWarehouse",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWarehouseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить склад.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      },
      "delete": {
        "operationId": "warehouse_removeWarehouse",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Удалить склад.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/suppliers": {
      "get": {
        "operationId": "warehouse_listSuppliers",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "name",
              "type": "string",
              "enum": [
                "name",
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "asc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SupplierResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список поставщиков.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      },
      "post": {
        "operationId": "warehouse_createSupplier",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSupplierDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplierResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать поставщика.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/suppliers/{id}": {
      "get": {
        "operationId": "warehouse_getSupplier",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplierResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить поставщика.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      },
      "patch": {
        "operationId": "warehouse_updateSupplier",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSupplierDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SupplierResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить поставщика.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      },
      "delete": {
        "operationId": "warehouse_removeSupplier",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Удалить поставщика.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/stocks": {
      "get": {
        "operationId": "warehouse_listStocks",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "productName",
              "type": "string",
              "enum": [
                "productName",
                "productSku",
                "qty",
                "updatedAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "asc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "warehouseId",
            "required": false,
            "in": "query",
            "description": "Фильтр по складу",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "categoryId",
            "required": false,
            "in": "query",
            "description": "Фильтр по категории товара",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "level",
            "required": false,
            "in": "query",
            "schema": {
              "default": "all",
              "type": "string",
              "enum": [
                "all",
                "low",
                "negative",
                "reorder"
              ]
            }
          },
          {
            "name": "groupBy",
            "required": false,
            "in": "query",
            "description": "Режим агрегации: product — сводка по сети (W4)",
            "schema": {
              "type": "string",
              "enum": [
                "product"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StockListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Остатки по товарам.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/stocks/adjust": {
      "post": {
        "operationId": "warehouse_adjustStock",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdjustStockDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockListItemResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Скорректировать остаток (инвентаризация).",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/receipts": {
      "get": {
        "operationId": "warehouse_listReceipts",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt",
                "date",
                "number",
                "totalQty",
                "totalAmount"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "posted",
                "cancelled"
              ]
            }
          },
          {
            "name": "warehouseId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "supplierId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "required": false,
            "in": "query",
            "description": "Дата приёмки от (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateTo",
            "required": false,
            "in": "query",
            "description": "Дата приёмки до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReceiptListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список приёмок.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      },
      "post": {
        "operationId": "warehouse_createReceipt",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReceiptDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать приёмку.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/receipts/{id}": {
      "get": {
        "operationId": "warehouse_getReceipt",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить приёмку.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:read"
        ],
        "x-module": "warehouse"
      }
    },
    "/warehouse/receipts/{id}/cancel": {
      "post": {
        "description": "Команда над существующей приёмкой — отвечает 200.",
        "operationId": "warehouse_cancelReceipt",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Отменить приёмку.",
        "tags": [
          "external/warehouse"
        ],
        "x-scopes": [
          "warehouse:write"
        ],
        "x-module": "warehouse"
      }
    },
    "/calendar/events": {
      "get": {
        "description": "Отдаёт массив без пагинации: экземпляры повторяющихся событий разворачиваются на лету, и страницы по ним не считаются. Период ограничен 92 днями — шире → 400 `VALIDATION_ERROR`.",
        "operationId": "calendar_listEvents",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Начало периода (ISO 8601, включается)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Конец периода (ISO 8601, не включается)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "event",
                "work_shift",
                "day_off",
                "task",
                "reminder"
              ]
            }
          },
          {
            "name": "userId",
            "required": false,
            "in": "query",
            "description": "ID участника/создателя для фильтра",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "companyWide",
            "required": false,
            "in": "query",
            "description": "true=только события компании, false=только личные",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Поиск по заголовку (case-insensitive)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CalendarEventInstanceResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Развёрнутые экземпляры событий за период (raw + recurrence expansion).",
        "tags": [
          "external/calendar"
        ],
        "x-scopes": [
          "calendar:read"
        ],
        "x-module": "calendar"
      },
      "post": {
        "operationId": "calendar_createEvent",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCalendarEventDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarEventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать событие.",
        "tags": [
          "external/calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ],
        "x-module": "calendar"
      }
    },
    "/calendar/events/{id}": {
      "get": {
        "operationId": "calendar_getEvent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarEventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить событие.",
        "tags": [
          "external/calendar"
        ],
        "x-scopes": [
          "calendar:read"
        ],
        "x-module": "calendar"
      },
      "patch": {
        "operationId": "calendar_updateEvent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCalendarEventDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarEventResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить событие.",
        "tags": [
          "external/calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ],
        "x-module": "calendar"
      },
      "delete": {
        "operationId": "calendar_removeEvent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": ""
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Удалить событие.",
        "tags": [
          "external/calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ],
        "x-module": "calendar"
      }
    },
    "/deals/lost-reasons": {
      "get": {
        "description": "Идентификатор причины обязателен в `lostReasonId` при переводе сделки на терминальную стадию с исходом «проиграна»; в ответах сделок поле расшифровывается по этому списку. По умолчанию только активные.",
        "operationId": "deals_listLostReasons",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DealLostReasonResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Причины проигрыша сделки.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:read"
        ],
        "x-module": "deals"
      }
    },
    "/deals/sources": {
      "get": {
        "description": "Идентификатор источника — для `sourceId` при создании сделки и для расшифровки поля в ответах. По умолчанию только активные.",
        "operationId": "deals_listSources",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LeadSourceResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Источники сделок и лидов.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:read"
        ],
        "x-module": "deals"
      }
    },
    "/deals/types": {
      "get": {
        "description": "Только типы включённых компонентов: id стадий отсюда нужны для создания сделки и смены стадии.",
        "operationId": "deals_listTypes",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DealTypeResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Типы сделок со стадиями пайплайна.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:read"
        ],
        "x-module": "deals"
      }
    },
    "/deals": {
      "get": {
        "operationId": "deals_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt",
                "number",
                "dueAt",
                "scheduledAt",
                "total",
                "boardOrder"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "typeId",
            "required": false,
            "in": "query",
            "description": "ID типа сделки",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stageId",
            "required": false,
            "in": "query",
            "description": "ID стадии",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "outcome",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "won",
                "lost",
                "done",
                "cancelled"
              ]
            }
          },
          {
            "name": "openOnly",
            "required": false,
            "in": "query",
            "description": "Только открытые (без исхода) сделки",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "assignedToId",
            "required": false,
            "in": "query",
            "description": "ID ответственного",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "description": "ID клиента",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "addressId",
            "required": false,
            "in": "query",
            "description": "ID адреса клиента: все визиты по конкретной точке обслуживания",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduledFrom",
            "required": false,
            "in": "query",
            "description": "Запланирован от (ISO 8601) — окно дня для полевого экрана",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scheduledTo",
            "required": false,
            "in": "query",
            "description": "Запланирован до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sourceId",
            "required": false,
            "in": "query",
            "description": "ID источника лида (D7)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "required": false,
            "in": "query",
            "description": "Создан от (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateTo",
            "required": false,
            "in": "query",
            "description": "Создан до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "noTask",
            "required": false,
            "in": "query",
            "description": "Только сделки без задачи (next-action отсутствует)",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "overdue",
            "required": false,
            "in": "query",
            "description": "Только сделки с просроченной задачей",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DealListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список сделок.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:read"
        ],
        "x-module": "deals"
      },
      "post": {
        "operationId": "deals_create",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDealDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать сделку выбранного типа.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:write"
        ],
        "x-module": "deals"
      }
    },
    "/deals/{id}": {
      "get": {
        "operationId": "deals_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить сделку с позициями.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:read"
        ],
        "x-module": "deals"
      },
      "patch": {
        "operationId": "deals_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDealDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить сделку. Позиции и поля меняются, пока сделка не закрыта.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:write"
        ],
        "x-module": "deals"
      }
    },
    "/deals/{id}/stage": {
      "patch": {
        "operationId": "deals_changeStage",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeDealStageDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DealResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Перевести сделку на другую стадию пайплайна её типа.",
        "tags": [
          "external/deals"
        ],
        "x-scopes": [
          "deals:write"
        ],
        "x-module": "deals"
      }
    },
    "/scheduling/resources": {
      "get": {
        "operationId": "scheduling_listResources",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "name",
              "type": "string",
              "enum": [
                "name",
                "type",
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "asc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "staff",
                "seat",
                "unit",
                "equipment"
              ]
            }
          },
          {
            "name": "serviceId",
            "required": false,
            "in": "query",
            "description": "S7: только ресурсы, оказывающие эту услугу (или агностики).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "activeOnly",
            "required": false,
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ResourceResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список ресурсов (кабинеты, мастера, юниты).",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:read"
        ],
        "x-module": "scheduling"
      },
      "post": {
        "operationId": "scheduling_createResource",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateResourceDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать ресурс.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:write"
        ],
        "x-module": "scheduling"
      }
    },
    "/scheduling/resources/{id}": {
      "get": {
        "operationId": "scheduling_getResource",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить ресурс.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:read"
        ],
        "x-module": "scheduling"
      },
      "patch": {
        "operationId": "scheduling_updateResource",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateResourceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResourceResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить ресурс.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:write"
        ],
        "x-module": "scheduling"
      }
    },
    "/scheduling/bookings/slots": {
      "get": {
        "operationId": "scheduling_slots",
        "parameters": [
          {
            "name": "resourceId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "serviceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "required": true,
            "in": "query",
            "description": "Дата YYYY-MM-DD",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "startAt",
                      "endAt",
                      "free"
                    ],
                    "properties": {
                      "startAt": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "endAt": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "free": {
                        "type": "boolean"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Свободные и занятые слоты ресурса на день.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:read"
        ],
        "x-module": "scheduling"
      }
    },
    "/scheduling/bookings": {
      "get": {
        "operationId": "scheduling_listBookings",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "startAt",
              "type": "string",
              "enum": [
                "startAt",
                "createdAt",
                "number"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "resourceId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "confirmed",
                "completed",
                "no_show",
                "cancelled"
              ]
            }
          },
          {
            "name": "assignedToId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "clientId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Начало от (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "Начало до (ISO 8601)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "classesOnly",
            "required": false,
            "in": "query",
            "description": "Только групповые занятия (с вместимостью).",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BookingListItemResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список броней.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:read"
        ],
        "x-module": "scheduling"
      },
      "post": {
        "operationId": "scheduling_createBooking",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBookingDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать бронь (с проверкой пересечений и вместимости ресурса).",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:write"
        ],
        "x-module": "scheduling"
      }
    },
    "/scheduling/bookings/{id}": {
      "get": {
        "operationId": "scheduling_getBooking",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить бронь.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:read"
        ],
        "x-module": "scheduling"
      },
      "patch": {
        "operationId": "scheduling_updateBooking",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Изменить бронь.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:write"
        ],
        "x-module": "scheduling"
      }
    },
    "/scheduling/bookings/{id}/status": {
      "patch": {
        "operationId": "scheduling_changeBookingStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeBookingStatusDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Сменить статус брони.",
        "tags": [
          "external/scheduling"
        ],
        "x-scopes": [
          "scheduling:write"
        ],
        "x-module": "scheduling"
      }
    },
    "/leads": {
      "get": {
        "operationId": "leads_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Текстовый поиск.",
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "status"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "new",
                "in_progress",
                "converted",
                "spam"
              ]
            }
          },
          {
            "name": "source",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "assignedToId",
            "required": false,
            "in": "query",
            "description": "ID ответственного или `unassigned` (без ответственного).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LeadResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список лидов.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:read"
        ],
        "x-module": "marketing"
      },
      "post": {
        "description": "Идемпотентно по `externalId` в рамках источника: повторный запрос возвращает уже созданный лид без нового события `lead.created`.",
        "operationId": "leads_create",
        "parameters": [
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakeLeadDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Создать лид.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:write"
        ],
        "x-module": "marketing"
      }
    },
    "/leads/{id}": {
      "get": {
        "operationId": "leads_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить лид.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:read"
        ],
        "x-module": "marketing"
      }
    },
    "/leads/{id}/status": {
      "patch": {
        "operationId": "leads_updateStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLeadDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Сменить статус лида.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:write"
        ],
        "x-module": "marketing"
      }
    },
    "/leads/{id}/assign": {
      "post": {
        "description": "Команда над существующим лидом — отвечает 200.",
        "operationId": "leads_assign",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignLeadDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Назначить или снять ответственного за лид.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:write"
        ],
        "x-module": "marketing"
      }
    },
    "/leads/{id}/convert": {
      "post": {
        "description": "Создаёт клиента в компоненте «Клиенты» по данным лида (или связывает с найденным по телефону/почте). Достаточно scope `leads:write` — отдельный `clients:write` не нужен.",
        "operationId": "leads_convert",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "clientId"
                  ],
                  "properties": {
                    "clientId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Конвертировать лид в клиента.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:write"
        ],
        "x-module": "marketing"
      }
    },
    "/leads/{id}/convert-deal": {
      "post": {
        "description": "Создаёт клиента и сделку выбранного типа в дефолтном филиале. Достаточно scope `leads:write`; компонент «Сделки» должен быть включён у компании, иначе 403 `MODULE_ACCESS_INACTIVE`.",
        "operationId": "leads_convertDeal",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "UUID запроса. Повтор с тем же ключом в течение 7 дней вернёт сохранённый ответ вместо второго заказа или продажи; пока первый запрос не завершён — 409 `IDEMPOTENCY_IN_FLIGHT`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConvertLeadToDealDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "dealId",
                    "clientId"
                  ],
                  "properties": {
                    "dealId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "clientId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Конвертировать лид в клиента и сделку.",
        "tags": [
          "external/leads"
        ],
        "x-scopes": [
          "leads:write"
        ],
        "x-module": "marketing"
      }
    },
    "/audit": {
      "get": {
        "operationId": "audit_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "maximum": 200,
              "default": 50,
              "type": "number"
            }
          },
          {
            "name": "entity",
            "required": false,
            "in": "query",
            "description": "Фильтр по типу сущности",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "action",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "create",
                "update",
                "delete",
                "login",
                "logout",
                "shift_open",
                "shift_close",
                "cash_movement_create",
                "sale",
                "refund_issue",
                "invitation_send",
                "order_create",
                "order_update",
                "order_status_change",
                "order_cancel",
                "order_payment",
                "order_payment_delete",
                "order_checkout",
                "order_line_fulfill",
                "order_template_create",
                "order_template_update",
                "order_template_delete",
                "deal_create",
                "deal_update",
                "deal_stage_change",
                "deal_checkout",
                "deal_share_enable",
                "deal_share_revoke",
                "deal_share_files",
                "deal_file_approval_request",
                "deal_file_approve",
                "deal_file_reject",
                "deal_type_create",
                "deal_type_update",
                "deal_type_delete",
                "expense_create",
                "expense_update",
                "expense_delete",
                "other_income_create",
                "other_income_update",
                "other_income_delete",
                "cash_account_create",
                "cash_account_update",
                "cash_account_delete",
                "cash_transaction_create",
                "cash_transaction_delete",
                "recurring_expense_create",
                "recurring_expense_update",
                "recurring_expense_delete",
                "budget_create",
                "budget_update",
                "budget_delete",
                "resource_create",
                "resource_update",
                "resource_delete",
                "booking_create",
                "booking_update",
                "booking_status_change",
                "booking_attendee_enroll",
                "booking_attendee_update",
                "booking_attendee_remove",
                "housekeeping_task_create",
                "housekeeping_task_update",
                "housekeeping_task_generate",
                "warehouse_create",
                "warehouse_update",
                "warehouse_delete",
                "warehouse_set_default",
                "branch_create",
                "branch_update",
                "branch_delete",
                "branch_set_default",
                "supplier_create",
                "supplier_update",
                "supplier_delete",
                "receipt_create",
                "receipt_cancel",
                "stock_adjustment",
                "product_bom_set",
                "production_run_create",
                "production_run_cancel",
                "product_variant_create",
                "product_variant_update",
                "product_variant_delete",
                "automation_rule_create",
                "automation_rule_update",
                "automation_rule_delete",
                "stock_write_off",
                "stock_reorder_set",
                "stocktake_create",
                "stocktake_apply",
                "stocktake_cancel",
                "purchase_order_create",
                "purchase_order_send",
                "purchase_order_cancel",
                "purchase_order_receive",
                "stock_bulk_reorder_set",
                "stock_bulk_adjust",
                "stock_transfer_ship",
                "stock_transfer_receive",
                "stock_transfer_cancel",
                "client_create",
                "client_update",
                "client_archive",
                "client_restore",
                "client_asset_create",
                "client_asset_update",
                "client_asset_delete",
                "client_address_create",
                "client_address_update",
                "client_address_delete",
                "client_balance_topup",
                "client_balance_charge",
                "client_package_create",
                "client_package_update",
                "client_package_delete",
                "client_package_use",
                "client_package_refund",
                "package_template_create",
                "package_template_update",
                "package_template_delete",
                "client_relation_create",
                "client_relation_delete",
                "student_group_create",
                "student_group_update",
                "student_group_delete",
                "student_group_schedule",
                "student_group_member_add",
                "student_group_member_update",
                "student_group_member_remove",
                "service_contract_create",
                "service_contract_update",
                "service_contract_delete",
                "service_contract_generate",
                "client_price_set",
                "client_price_delete",
                "price_list_create",
                "price_list_update",
                "price_list_delete",
                "price_list_fill",
                "client_group_create",
                "client_group_update",
                "client_group_delete",
                "shipment_create",
                "shipment_ship",
                "shipment_cancel",
                "client_portal_enable",
                "client_portal_disable",
                "b2b_portal_order_create",
                "interaction_create",
                "interaction_update",
                "interaction_delete",
                "calendar_event_create",
                "calendar_event_update",
                "calendar_event_delete",
                "product_bulk_reprice",
                "product_bulk_set_category",
                "product_bulk_set_brand",
                "product_bulk_hide",
                "product_bulk_restore",
                "product_duplicate",
                "client_merge",
                "client_import",
                "client_bulk_assign",
                "client_bulk_tag",
                "client_bulk_archive",
                "client_bulk_restore",
                "client_asset_service_done",
                "client_segment_create",
                "client_segment_update",
                "client_segment_delete",
                "client_segment_broadcast",
                "client_marketing_consent",
                "message_template_create",
                "message_template_update",
                "message_template_delete",
                "client_anonymize",
                "client_tag_set",
                "client_tag_delete",
                "loyalty_tier_set",
                "loyalty_tier_delete",
                "promo_code_create",
                "promo_code_update",
                "promo_code_delete",
                "promo_code_redeem",
                "deal_comment_create",
                "deal_comment_delete",
                "deal_task_create",
                "deal_task_update",
                "deal_task_delete",
                "deal_template_create",
                "deal_template_delete",
                "lead_source_create",
                "lead_source_update",
                "lead_source_delete",
                "deal_lost_reason_create",
                "deal_lost_reason_update",
                "deal_lost_reason_delete",
                "booking_issue",
                "booking_return",
                "waitlist_create",
                "waitlist_notify",
                "storefront_settings_update",
                "storefront_product_publish",
                "delivery_zone_create",
                "delivery_zone_update",
                "delivery_zone_delete",
                "storefront_payment_paid",
                "order_delivery_status_change",
                "restaurant_settings_update",
                "restaurant_menu_visibility",
                "restaurant_table_create",
                "restaurant_table_update",
                "restaurant_table_delete",
                "restaurant_session_close",
                "restaurant_session_cancel",
                "kds_ticket_status_change",
                "restaurant_payment_paid",
                "hardware_enrollment_issue",
                "hardware_agent_enroll",
                "hardware_agent_update",
                "hardware_agent_revoke",
                "hardware_command_dispatch",
                "crew_create",
                "crew_update",
                "crew_delete",
                "work_order_create",
                "work_order_update",
                "work_order_complete",
                "work_order_cancel",
                "deal_material_issue",
                "deal_material_return",
                "estimate_version_create",
                "estimate_version_approve",
                "user_ip_restriction_disable",
                "company_deletion_request",
                "company_deletion_cancel",
                "company_deletion_confirm",
                "company_restore",
                "data_export",
                "password_change",
                "two_factor_enable",
                "two_factor_disable",
                "ip_restriction_update",
                "user_create",
                "user_update",
                "user_role_change",
                "user_status_change",
                "user_password_reset",
                "user_delete",
                "sa_company_update",
                "sa_billing_update",
                "sa_user_update",
                "sa_session_revoke",
                "access_denied",
                "file_download",
                "file_delete"
              ]
            }
          },
          {
            "name": "actorId",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "required": false,
            "in": "query",
            "description": "ISO дата начала",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateTo",
            "required": false,
            "in": "query",
            "description": "ISO дата окончания",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "createdAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AuditLogResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Журнал действий компании.",
        "tags": [
          "external/audit"
        ],
        "x-scopes": [
          "audit:read"
        ],
        "x-module": "core"
      }
    },
    "/users": {
      "get": {
        "operationId": "users_list",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "pageSize",
            "required": false,
            "in": "query",
            "schema": {
              "maximum": 100,
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Поиск по email/имени/фамилии",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "role",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "admin",
                "manager",
                "employee",
                "director"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number",
              "enum": [
                0,
                1,
                2,
                3
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "createdAt",
              "type": "string",
              "enum": [
                "lastName",
                "email",
                "role",
                "status",
                "createdAt",
                "updatedAt"
              ]
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "total",
                    "page",
                    "pageSize"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserResponse"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Всего записей по фильтру"
                    },
                    "page": {
                      "type": "integer",
                      "description": "Номер страницы, с 1"
                    },
                    "pageSize": {
                      "type": "integer",
                      "description": "Размер страницы"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Список сотрудников.",
        "tags": [
          "external/users"
        ],
        "x-scopes": [
          "users:read"
        ],
        "x-module": "core"
      }
    },
    "/users/{id}": {
      "get": {
        "operationId": "users_get",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Ошибка валидации тела или параметров (`VALIDATION_ERROR`, `message` — массив строк).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Токен отсутствует, недействителен, отозван или истёк (`AUTH_API_TOKEN_INVALID`, `AUTH_API_TOKEN_EXPIRED`), компания архивирована (`COMPANY_ARCHIVED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Не хватает scope (`AUTH_API_SCOPE_INSUFFICIENT`, нужные — в `meta.scopes`), компонент выключен у компании (`MODULE_ACCESS_INACTIVE`, алиас — в `meta.alias`), API недоступно на тарифе (`PLAN_API_DISABLED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Сущность не найдена в компании (`<ENTITY>_NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Конфликт состояния: недопустимый переход статуса, занятый артикул, повтор `X-Idempotency-Key` с незавершённым запросом (`IDEMPOTENCY_IN_FLIGHT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Лимит частоты по токену; пауза — в заголовке `Retry-After`, остаток — в `X-RateLimit-Remaining`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalErrorResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "api-token": []
          }
        ],
        "summary": "Получить сотрудника.",
        "tags": [
          "external/users"
        ],
        "x-scopes": [
          "users:read"
        ],
        "x-module": "core"
      }
    }
  },
  "info": {
    "title": "Easy Microbusiness — External API",
    "description": "Публичный API «Лёгкого Микробизнеса» для интеграций. Аутентификация — Bearer API-токеном, выпущенным в админке (раздел «Разработчикам»). Деньги — целые числа в минорных единицах, идентификаторы — UUID, даты — ISO 8601 в UTC.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "external/catalog",
      "description": "Товары, услуги и категории каталога."
    },
    {
      "name": "external/clients",
      "description": "Клиенты компании."
    },
    {
      "name": "external/leads",
      "description": "Лиды входящего контура: приём, статус, ответственный, конвертация."
    },
    {
      "name": "external/orders",
      "description": "Заказы клиентов и их статусы."
    },
    {
      "name": "external/deals",
      "description": "Сделки с пайплайном стадий и их типы."
    },
    {
      "name": "external/sales",
      "description": "Продажи, возвраты и кассовые смены."
    },
    {
      "name": "external/warehouse",
      "description": "Склады, поставщики, остатки и приёмки."
    },
    {
      "name": "external/scheduling",
      "description": "Ресурсы (кабинеты, мастера, юниты) и брони."
    },
    {
      "name": "external/calendar",
      "description": "События календаря."
    },
    {
      "name": "external/audit",
      "description": "Журнал действий компании."
    },
    {
      "name": "external/users",
      "description": "Сотрудники компании (только чтение)."
    }
  ],
  "servers": [
    {
      "url": "https://app.easymb.ru/api/external/v1",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "api-token": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "emb_live_<random>",
        "description": "Токен формата `emb_live_…`, выпускается в админке. Передавайте в заголовке `Authorization: Bearer <token>`."
      }
    },
    "schemas": {
      "ExternalErrorResponse": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "number",
            "description": "HTTP-статус",
            "example": 403
          },
          "error": {
            "type": "string",
            "description": "Название статуса",
            "example": "Forbidden"
          },
          "message": {
            "type": "string",
            "description": "Текст ошибки (английский)",
            "example": "Insufficient permissions. One of the following scopes is required: deals:write"
          },
          "code": {
            "type": "string",
            "description": "Машинный код ошибки (CAPS_ENUM) — по нему ветвится обработка на стороне интеграции",
            "example": "AUTH_API_SCOPE_INSUFFICIENT"
          },
          "meta": {
            "type": "object",
            "description": "Параметры ошибки: значения плейсхолдеров `message` (например, требуемые scope или алиас неактивного компонента)",
            "additionalProperties": true,
            "example": {
              "scopes": "deals:write"
            }
          },
          "timestamp": {
            "type": "string",
            "description": "Момент ошибки, ISO 8601"
          },
          "path": {
            "type": "string",
            "description": "Путь запроса",
            "example": "/api/external/v1/deals"
          }
        },
        "required": [
          "statusCode",
          "error",
          "message",
          "timestamp",
          "path"
        ]
      },
      "ProductAttributeValueResponse": {
        "type": "object",
        "properties": {
          "attributeId": {
            "type": "string",
            "description": "ID характеристики"
          },
          "valueString": {
            "type": "string",
            "nullable": true,
            "description": "Строковое значение (тип text)"
          },
          "valueNumber": {
            "type": "number",
            "nullable": true,
            "description": "Числовое значение (тип number)"
          },
          "valueColor": {
            "type": "string",
            "nullable": true,
            "description": "Цвет HEX (тип color)"
          },
          "colorName": {
            "type": "string",
            "nullable": true,
            "description": "Имя цвета из палитры NamedColor; пара с valueColor"
          },
          "valueBoolean": {
            "type": "boolean",
            "nullable": true,
            "description": "Логическое значение (тип boolean)"
          },
          "optionId": {
            "type": "string",
            "nullable": true,
            "description": "ID выбранной опции (тип select)"
          }
        },
        "required": [
          "attributeId",
          "valueString",
          "valueNumber",
          "valueColor",
          "colorName",
          "valueBoolean",
          "optionId"
        ]
      },
      "ProductResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID товара"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "sku": {
            "type": "string",
            "description": "Артикул"
          },
          "barcode": {
            "type": "string",
            "nullable": true,
            "description": "Штрихкод"
          },
          "name": {
            "type": "string",
            "description": "Название товара"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание"
          },
          "nameI18n": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Переводы названия по локали: { \"de\": \"...\" }"
          },
          "descriptionI18n": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Переводы описания по локали"
          },
          "categoryId": {
            "type": "string",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "brand": {
            "type": "string",
            "nullable": true,
            "description": "Бренд"
          },
          "model": {
            "type": "string",
            "nullable": true,
            "description": "Модель"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках"
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость в копейках"
          },
          "unit": {
            "type": "string",
            "description": "Единица измерения (код, денорм)"
          },
          "unitId": {
            "type": "string",
            "nullable": true,
            "description": "ID единицы измерения из справочника"
          },
          "packQty": {
            "type": "number",
            "nullable": true,
            "description": "Фасовка: кол-во packUnit в одной unit"
          },
          "minOrderQty": {
            "type": "number",
            "nullable": true,
            "description": "Минимальная партия к заказу (опт); null — без ограничения"
          },
          "orderStepQty": {
            "type": "number",
            "nullable": true,
            "description": "Кратность отгрузки (опт); null — любая"
          },
          "packUnitId": {
            "type": "string",
            "nullable": true,
            "description": "ID единицы фасовки"
          },
          "costComponents": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Разбивка себестоимости: [{ label, productId?, qty?, unitId?, unitCost?, amount }]"
          },
          "isBundle": {
            "type": "boolean",
            "description": "Комплект/набор (BOM)"
          },
          "modifierGroups": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Группы модификаторов позиции с надбавками"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "description": "Статус карточки"
          },
          "hasStock": {
            "type": "boolean",
            "description": "Ведётся складской учёт остатков"
          },
          "defaultSupplierId": {
            "type": "string",
            "nullable": true,
            "description": "ID поставщика по умолчанию (авто-дозаказ)"
          },
          "emoji": {
            "type": "string",
            "nullable": true,
            "description": "Эмодзи-иконка"
          },
          "photoFileId": {
            "type": "string",
            "nullable": true,
            "description": "ID файла основного фото"
          },
          "thumbnailFileId": {
            "type": "string",
            "nullable": true,
            "description": "ID файла миниатюры"
          },
          "attributeValues": {
            "description": "Значения характеристик",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAttributeValueResponse"
            }
          },
          "stockQty": {
            "type": "number",
            "description": "Суммарный остаток по складам компании (только при include=stock и hasStock)."
          },
          "stockAvailable": {
            "type": "number",
            "description": "Свободный остаток (qty − резервы) — при include=stock."
          },
          "isLowStock": {
            "type": "boolean",
            "description": "Низкий запас (Σqty ≤ Σпорог дозаказа) — при include=stock."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "sku",
          "barcode",
          "name",
          "description",
          "nameI18n",
          "descriptionI18n",
          "categoryId",
          "brand",
          "model",
          "price",
          "cost",
          "unit",
          "unitId",
          "packQty",
          "minOrderQty",
          "orderStepQty",
          "packUnitId",
          "costComponents",
          "isBundle",
          "modifierGroups",
          "status",
          "hasStock",
          "defaultSupplierId",
          "emoji",
          "photoFileId",
          "thumbnailFileId",
          "attributeValues",
          "createdAt",
          "updatedAt"
        ]
      },
      "ProductAttributeValueInput": {
        "type": "object",
        "properties": {
          "attributeId": {
            "type": "string",
            "description": "ID характеристики",
            "format": "uuid"
          },
          "valueString": {
            "type": "string",
            "nullable": true,
            "description": "Строковое значение (тип text)"
          },
          "valueNumber": {
            "type": "number",
            "nullable": true,
            "description": "Числовое значение (тип number)"
          },
          "valueColor": {
            "type": "string",
            "nullable": true,
            "example": "#1ABC9C",
            "description": "Цвет HEX (тип color)"
          },
          "colorName": {
            "type": "string",
            "nullable": true,
            "enum": [
              "black",
              "white",
              "gray",
              "dark_gray",
              "light_gray",
              "red",
              "orange",
              "light_orange",
              "yellow",
              "gold",
              "green",
              "light_green",
              "dark_green",
              "light_blue",
              "blue",
              "dark_blue",
              "indigo",
              "purple",
              "pink",
              "light_pink",
              "brown",
              "beige",
              "burgundy",
              "khaki"
            ],
            "description": "Имя цвета из палитры NamedColor; пара с `valueColor`."
          },
          "valueBoolean": {
            "type": "boolean",
            "nullable": true,
            "description": "Логическое значение (тип boolean)"
          },
          "optionId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID выбранной опции (тип select)"
          }
        },
        "required": [
          "attributeId"
        ]
      },
      "CreateProductDto": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Артикул. Если опущен и у выбранной категории есть prefix — будет сгенерирован автоматически как PREFIX-NNNN",
            "example": "CFE-0012"
          },
          "barcode": {
            "type": "string",
            "nullable": true,
            "example": "4607034630621",
            "description": "Штрихкод"
          },
          "name": {
            "type": "string",
            "example": "Кофе зерновой «Эспрессо», 1 кг",
            "description": "Название товара"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание товара"
          },
          "nameI18n": {
            "type": "object",
            "description": "Переводы названия по локали (C9): { \"de\": \"...\" }",
            "additionalProperties": {
              "type": "string"
            }
          },
          "descriptionI18n": {
            "type": "object",
            "description": "Переводы описания по локали (C9).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "categoryId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках",
            "example": 240000
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость в копейках",
            "default": 0
          },
          "unit": {
            "type": "string",
            "description": "Единица измерения (код)",
            "default": "pcs"
          },
          "unitId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "FK на справочник единиц (C5)."
          },
          "packQty": {
            "type": "number",
            "nullable": true,
            "description": "Фасовка: кол-во packUnit в одной unit."
          },
          "packUnitId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "FK на единицу фасовки."
          },
          "minOrderQty": {
            "type": "number",
            "nullable": true,
            "description": "Минимальная партия к заказу (опт). Пусто — без ограничения."
          },
          "orderStepQty": {
            "type": "number",
            "nullable": true,
            "description": "Кратность отгрузки (опт): коробка 12 шт → 12, 24, 36."
          },
          "costComponents": {
            "type": "array",
            "description": "Разбивка себестоимости (C8): [{ label, productId?, qty?, unitId?, unitCost?, amount }]",
            "items": {
              "type": "object"
            }
          },
          "isBundle": {
            "type": "boolean",
            "description": "Комплект/набор (BOM)",
            "default": false
          },
          "modifierGroups": {
            "type": "array",
            "description": "Модификаторы позиции (P1.3b): группы опций с надбавкой.",
            "items": {
              "type": "object"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "default": "active",
            "description": "Статус карточки"
          },
          "hasStock": {
            "type": "boolean",
            "default": false,
            "description": "Вести складской учёт остатков по товару"
          },
          "defaultSupplierId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Поставщик по умолчанию (W3, авто-дозаказ)"
          },
          "emoji": {
            "type": "string",
            "nullable": true,
            "example": "☕",
            "description": "Эмодзи-иконка для карточки и POS"
          },
          "brand": {
            "type": "string",
            "nullable": true,
            "example": "Lavazza",
            "description": "Бренд"
          },
          "model": {
            "type": "string",
            "nullable": true,
            "example": "Crema e Aroma",
            "description": "Модель"
          },
          "attributes": {
            "description": "Значения характеристик. Если массив передан — он полностью заменяет предыдущий набор значений у товара (отсутствующие удаляются).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAttributeValueInput"
            }
          }
        },
        "required": [
          "name",
          "price"
        ]
      },
      "UpdateProductDto": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Артикул. Если опущен и у выбранной категории есть prefix — будет сгенерирован автоматически как PREFIX-NNNN",
            "example": "CFE-0012"
          },
          "barcode": {
            "type": "string",
            "nullable": true,
            "example": "4607034630621",
            "description": "Штрихкод"
          },
          "name": {
            "type": "string",
            "example": "Кофе зерновой «Эспрессо», 1 кг",
            "description": "Название товара"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание товара"
          },
          "nameI18n": {
            "type": "object",
            "description": "Переводы названия по локали (C9): { \"de\": \"...\" }",
            "additionalProperties": {
              "type": "string"
            }
          },
          "descriptionI18n": {
            "type": "object",
            "description": "Переводы описания по локали (C9).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "categoryId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках",
            "example": 240000
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость в копейках",
            "default": 0
          },
          "unit": {
            "type": "string",
            "description": "Единица измерения (код)",
            "default": "pcs"
          },
          "unitId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "FK на справочник единиц (C5)."
          },
          "packQty": {
            "type": "number",
            "nullable": true,
            "description": "Фасовка: кол-во packUnit в одной unit."
          },
          "packUnitId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "FK на единицу фасовки."
          },
          "minOrderQty": {
            "type": "number",
            "nullable": true,
            "description": "Минимальная партия к заказу (опт). Пусто — без ограничения."
          },
          "orderStepQty": {
            "type": "number",
            "nullable": true,
            "description": "Кратность отгрузки (опт): коробка 12 шт → 12, 24, 36."
          },
          "costComponents": {
            "type": "array",
            "description": "Разбивка себестоимости (C8): [{ label, productId?, qty?, unitId?, unitCost?, amount }]",
            "items": {
              "type": "object"
            }
          },
          "isBundle": {
            "type": "boolean",
            "description": "Комплект/набор (BOM)",
            "default": false
          },
          "modifierGroups": {
            "type": "array",
            "description": "Модификаторы позиции (P1.3b): группы опций с надбавкой.",
            "items": {
              "type": "object"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "default": "active",
            "description": "Статус карточки"
          },
          "hasStock": {
            "type": "boolean",
            "default": false,
            "description": "Вести складской учёт остатков по товару"
          },
          "defaultSupplierId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Поставщик по умолчанию (W3, авто-дозаказ)"
          },
          "emoji": {
            "type": "string",
            "nullable": true,
            "example": "☕",
            "description": "Эмодзи-иконка для карточки и POS"
          },
          "brand": {
            "type": "string",
            "nullable": true,
            "example": "Lavazza",
            "description": "Бренд"
          },
          "model": {
            "type": "string",
            "nullable": true,
            "example": "Crema e Aroma",
            "description": "Модель"
          },
          "attributes": {
            "description": "Значения характеристик. Если массив передан — он полностью заменяет предыдущий набор значений у товара (отсутствующие удаляются).",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductAttributeValueInput"
            }
          }
        }
      },
      "ServiceCostItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID позиции"
          },
          "serviceId": {
            "type": "string",
            "description": "ID услуги"
          },
          "kind": {
            "type": "string",
            "enum": [
              "material",
              "labor"
            ],
            "description": "Тип позиции"
          },
          "productId": {
            "type": "string",
            "nullable": true,
            "description": "ID товара из справочника; null — freeform-позиция"
          },
          "name": {
            "type": "string",
            "description": "Название (snapshot)"
          },
          "quantity": {
            "type": "number",
            "description": "Количество (десятичное)"
          },
          "unitCost": {
            "type": "number",
            "description": "Себестоимость единицы, копейки"
          },
          "lineTotal": {
            "type": "number",
            "description": "Итог по строке, копейки"
          },
          "position": {
            "type": "number",
            "description": "Порядок в составе"
          }
        },
        "required": [
          "id",
          "serviceId",
          "kind",
          "productId",
          "name",
          "quantity",
          "unitCost",
          "lineTotal",
          "position"
        ]
      },
      "ServiceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID услуги"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "sku": {
            "type": "string",
            "description": "Артикул"
          },
          "name": {
            "type": "string",
            "description": "Название услуги"
          },
          "nameI18n": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Переводы названия по локали"
          },
          "categoryId": {
            "type": "string",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "priceModel": {
            "type": "string",
            "enum": [
              "fixed",
              "per_hour",
              "per_minute",
              "per_day",
              "per_item"
            ],
            "description": "Способ формирования цены"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках"
          },
          "durationMinutes": {
            "type": "number",
            "nullable": true,
            "description": "Длительность, мин"
          },
          "totalCost": {
            "type": "number",
            "description": "Сумма по составу затрат, копейки"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "description": "Статус карточки"
          },
          "costItems": {
            "description": "Состав затрат — присутствует в детальной выдаче",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ServiceCostItemResponse"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "sku",
          "name",
          "nameI18n",
          "categoryId",
          "priceModel",
          "price",
          "durationMinutes",
          "totalCost",
          "status",
          "createdAt",
          "updatedAt"
        ]
      },
      "ServiceCostItemInputDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "material",
              "labor"
            ],
            "description": "Тип позиции"
          },
          "productId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "UUID товара из справочника. null/undefined — freeform."
          },
          "name": {
            "type": "string",
            "description": "Название (snapshot)",
            "example": "Цемент М500"
          },
          "quantity": {
            "type": "number",
            "description": "Количество (десятичное)",
            "example": 2.5
          },
          "unitCost": {
            "type": "number",
            "description": "Себестоимость единицы, копейки",
            "example": 50000
          }
        },
        "required": [
          "kind",
          "name",
          "quantity",
          "unitCost"
        ]
      },
      "CreateServiceDto": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Артикул. Если опущен и у выбранной категории есть prefix — будет сгенерирован автоматически как PREFIX-NNNN",
            "example": "SVC-0001"
          },
          "name": {
            "type": "string",
            "example": "Консультация бариста",
            "description": "Название услуги"
          },
          "nameI18n": {
            "type": "object",
            "description": "Переводы названия по локали (C9).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "categoryId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "priceModel": {
            "type": "string",
            "enum": [
              "fixed",
              "per_hour",
              "per_minute",
              "per_day",
              "per_item"
            ],
            "default": "fixed",
            "description": "Способ формирования цены"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках",
            "example": 150000
          },
          "durationMinutes": {
            "type": "number",
            "nullable": true,
            "description": "Длительность услуги в минутах (для записи/брони)",
            "example": 60
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "default": "active",
            "description": "Статус карточки"
          },
          "costItems": {
            "description": "Состав затрат (материалы и работы). Replace-all при наличии в запросе.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ServiceCostItemInputDto"
            }
          }
        },
        "required": [
          "name",
          "price"
        ]
      },
      "UpdateServiceDto": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string",
            "description": "Артикул. Если опущен и у выбранной категории есть prefix — будет сгенерирован автоматически как PREFIX-NNNN",
            "example": "SVC-0001"
          },
          "name": {
            "type": "string",
            "example": "Консультация бариста",
            "description": "Название услуги"
          },
          "nameI18n": {
            "type": "object",
            "description": "Переводы названия по локали (C9).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "categoryId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID категории; null — без категории"
          },
          "priceModel": {
            "type": "string",
            "enum": [
              "fixed",
              "per_hour",
              "per_minute",
              "per_day",
              "per_item"
            ],
            "default": "fixed",
            "description": "Способ формирования цены"
          },
          "price": {
            "type": "number",
            "description": "Цена в копейках",
            "example": 150000
          },
          "durationMinutes": {
            "type": "number",
            "nullable": true,
            "description": "Длительность услуги в минутах (для записи/брони)",
            "example": 60
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "default": "active",
            "description": "Статус карточки"
          },
          "costItems": {
            "description": "Состав затрат (материалы и работы). Replace-all при наличии в запросе.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ServiceCostItemInputDto"
            }
          }
        }
      },
      "CategoryResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID категории"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "parentId": {
            "type": "string",
            "nullable": true,
            "description": "ID родительской категории; null — корень"
          },
          "name": {
            "type": "string",
            "description": "Название категории"
          },
          "icon": {
            "type": "string",
            "description": "Имя иконки"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета иконки"
          },
          "bg": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета фона иконки"
          },
          "sortOrder": {
            "type": "number",
            "description": "Порядок сортировки"
          },
          "prefix": {
            "type": "string",
            "nullable": true,
            "description": "Префикс артикулов: A-Z, 1-4 символа",
            "example": "CFE"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "parentId",
          "name",
          "icon",
          "color",
          "bg",
          "sortOrder",
          "prefix",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateCategoryDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Напитки",
            "description": "Название категории"
          },
          "parentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID родительской категории; null — корень"
          },
          "icon": {
            "type": "string",
            "default": "folder",
            "description": "Имя иконки"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета иконки"
          },
          "bg": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета фона иконки"
          },
          "sortOrder": {
            "type": "number",
            "default": 0,
            "description": "Порядок сортировки"
          },
          "prefix": {
            "type": "string",
            "nullable": true,
            "description": "Префикс артикула: A-Z, 1-4 символа",
            "example": "CFE"
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateCategoryDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Напитки",
            "description": "Название категории"
          },
          "parentId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID родительской категории; null — корень"
          },
          "icon": {
            "type": "string",
            "default": "folder",
            "description": "Имя иконки"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета иконки"
          },
          "bg": {
            "type": "string",
            "nullable": true,
            "description": "HEX цвета фона иконки"
          },
          "sortOrder": {
            "type": "number",
            "default": 0,
            "description": "Порядок сортировки"
          },
          "prefix": {
            "type": "string",
            "nullable": true,
            "description": "Префикс артикула: A-Z, 1-4 символа",
            "example": "CFE"
          }
        }
      },
      "ProductVariantResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID варианта"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "productId": {
            "type": "string",
            "description": "ID родительского товара"
          },
          "sku": {
            "type": "string",
            "description": "Артикул варианта"
          },
          "barcode": {
            "type": "string",
            "nullable": true,
            "description": "Штрихкод"
          },
          "attributes": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Атрибуты варианта: { \"color\": \"red\", \"size\": \"M\" }"
          },
          "price": {
            "type": "number",
            "description": "Цена варианта в копейках"
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость варианта в копейках"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "hidden"
            ],
            "description": "Статус варианта"
          },
          "stockQty": {
            "type": "number",
            "description": "Суммарный остаток по складам (матрица)."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "productId",
          "sku",
          "barcode",
          "attributes",
          "price",
          "cost",
          "status",
          "createdAt",
          "updatedAt"
        ]
      },
      "AttributeOptionResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID опции"
          },
          "attributeId": {
            "type": "string",
            "description": "ID характеристики"
          },
          "value": {
            "type": "string",
            "description": "Значение опции"
          },
          "position": {
            "type": "number",
            "description": "Порядок в списке"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создана (ISO 8601)"
          }
        },
        "required": [
          "id",
          "attributeId",
          "value",
          "position",
          "createdAt"
        ]
      },
      "AttributeDefinitionResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID характеристики"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "name": {
            "type": "string",
            "description": "Название характеристики"
          },
          "type": {
            "type": "string",
            "enum": [
              "color",
              "string",
              "number",
              "option_set",
              "boolean"
            ],
            "description": "Тип значения: определяет, какое поле заполняется в значении"
          },
          "isPrimary": {
            "type": "boolean",
            "description": "Основная характеристика: показывается в карточке и списках"
          },
          "categoryId": {
            "type": "string",
            "nullable": true,
            "description": "ID категории, к которой привязана; null — общая"
          },
          "position": {
            "type": "number",
            "description": "Порядок в списке"
          },
          "options": {
            "description": "Варианты значений (для типа select)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttributeOptionResponse"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создана (ISO 8601)"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Обновлена (ISO 8601)"
          }
        },
        "required": [
          "id",
          "companyId",
          "name",
          "type",
          "isPrimary",
          "categoryId",
          "position",
          "options",
          "createdAt",
          "updatedAt"
        ]
      },
      "UnitResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID единицы"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "code": {
            "type": "string",
            "description": "Код, уникален в компании"
          },
          "name": {
            "type": "string",
            "description": "Название"
          },
          "kind": {
            "type": "string",
            "enum": [
              "count",
              "weight",
              "volume",
              "time",
              "length"
            ],
            "description": "Род единицы"
          },
          "baseRatio": {
            "type": "number",
            "description": "Коэффициент к базовой единице рода."
          },
          "isFractional": {
            "type": "boolean",
            "description": "Разрешён дробный ввод количества"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "code",
          "name",
          "kind",
          "baseRatio",
          "isFractional",
          "createdAt",
          "updatedAt"
        ]
      },
      "ClientListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID клиента"
          },
          "kind": {
            "type": "string",
            "enum": [
              "individual",
              "legal"
            ],
            "description": "Физлицо или юрлицо"
          },
          "displayName": {
            "type": "string",
            "description": "Отображаемое имя"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "tags": {
            "description": "Теги",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "archived"
            ],
            "description": "Статус клиента"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "assignedToName": {
            "type": "string",
            "nullable": true,
            "description": "Имя ответственного сотрудника"
          },
          "lastInteractionAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Последнее взаимодействие (ISO 8601)"
          },
          "ordersCount": {
            "type": "number",
            "description": "Число заказов клиента"
          },
          "balance": {
            "type": "number",
            "description": "Баланс клиента, копейки (может быть < 0 = долг)"
          },
          "totalSpent": {
            "type": "number",
            "description": "Совокупная выручка (LTV-прокси), копейки"
          },
          "lastOrderAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Последний заказ (ISO 8601)"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "kind",
          "displayName",
          "phone",
          "email",
          "tags",
          "status",
          "assignedToId",
          "assignedToName",
          "lastInteractionAt",
          "ordersCount",
          "balance",
          "totalSpent",
          "lastOrderAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "ClientResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID клиента"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "kind": {
            "type": "string",
            "enum": [
              "individual",
              "legal"
            ],
            "description": "Физлицо или юрлицо"
          },
          "displayName": {
            "type": "string",
            "description": "Отображаемое имя — ФИО для физлица, название для юрлица"
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "description": "Имя"
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "description": "Фамилия"
          },
          "middleName": {
            "type": "string",
            "nullable": true,
            "description": "Отчество"
          },
          "companyName": {
            "type": "string",
            "nullable": true,
            "description": "Название компании (юрлицо)"
          },
          "position": {
            "type": "string",
            "nullable": true,
            "description": "Должность контактного лица"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "telegramChatId": {
            "type": "string",
            "nullable": true,
            "description": "Telegram chat id для исходящих сообщений"
          },
          "whatsappPhone": {
            "type": "string",
            "nullable": true,
            "description": "Номер WhatsApp; null — используется phone"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН (B2B)"
          },
          "kpp": {
            "type": "string",
            "nullable": true,
            "description": "КПП (B2B)"
          },
          "legalAddress": {
            "type": "string",
            "nullable": true,
            "description": "Юр. адрес (B2B)"
          },
          "bankDetails": {
            "type": "string",
            "nullable": true,
            "description": "Банковские реквизиты строкой (B2B)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          },
          "tags": {
            "description": "Теги",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "birthday": {
            "type": "string",
            "nullable": true,
            "format": "date",
            "description": "Дата рождения / основания (ISO 8601)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "archived"
            ],
            "description": "Статус клиента"
          },
          "balance": {
            "type": "number",
            "description": "Баланс/абонемент в копейках"
          },
          "points": {
            "type": "number",
            "description": "Баллы лояльности (копейки-эквивалент)"
          },
          "contractNumber": {
            "type": "string",
            "nullable": true,
            "description": "Номер договора (B2B)"
          },
          "groupId": {
            "type": "string",
            "nullable": true,
            "description": "ID группы контрагентов (опт)"
          },
          "priceListId": {
            "type": "string",
            "nullable": true,
            "description": "ID персонального прайс-листа (опт)"
          },
          "paymentTermsDays": {
            "type": "number",
            "nullable": true,
            "description": "Срок оплаты по договору, дни"
          },
          "creditLimit": {
            "type": "number",
            "description": "Кредитный лимит B2B в копейках (0 — без лимита)"
          },
          "slaHours": {
            "type": "number",
            "nullable": true,
            "description": "SLA по договору, часы"
          },
          "marketingConsent": {
            "type": "boolean",
            "description": "Согласие на маркетинговые рассылки"
          },
          "marketingConsentAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда дано согласие на рассылки (ISO 8601)"
          },
          "marketingConsentSource": {
            "type": "string",
            "nullable": true,
            "description": "Откуда получено согласие (форма, оператор…)"
          },
          "anonymizedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Дата анонимизации (право на забвение)"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "kind",
          "displayName",
          "firstName",
          "lastName",
          "middleName",
          "companyName",
          "position",
          "phone",
          "email",
          "telegramChatId",
          "whatsappPhone",
          "inn",
          "kpp",
          "legalAddress",
          "bankDetails",
          "note",
          "tags",
          "birthday",
          "status",
          "balance",
          "points",
          "contractNumber",
          "groupId",
          "priceListId",
          "paymentTermsDays",
          "creditLimit",
          "slaHours",
          "marketingConsent",
          "marketingConsentAt",
          "marketingConsentSource",
          "anonymizedAt",
          "assignedToId",
          "createdById",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateClientDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "individual",
              "legal"
            ],
            "description": "Физлицо или юрлицо"
          },
          "displayName": {
            "type": "string",
            "description": "Отображаемое имя — ФИО для физлица, название для юрлица"
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "description": "Имя"
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "description": "Фамилия"
          },
          "middleName": {
            "type": "string",
            "nullable": true,
            "description": "Отчество"
          },
          "companyName": {
            "type": "string",
            "nullable": true,
            "description": "Название компании (юрлицо)"
          },
          "position": {
            "type": "string",
            "nullable": true,
            "description": "Должность контактного лица"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "telegramChatId": {
            "type": "string",
            "nullable": true,
            "description": "Telegram chat id для исходящих сообщений (канал telegram)."
          },
          "whatsappPhone": {
            "type": "string",
            "nullable": true,
            "description": "Номер WhatsApp; пустой → используется phone."
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          },
          "tags": {
            "description": "Теги",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "birthday": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Дата рождения / основания (ISO 8601)"
          },
          "assignedToId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН (B2B, для документов)"
          },
          "kpp": {
            "type": "string",
            "nullable": true,
            "description": "КПП (B2B)"
          },
          "legalAddress": {
            "type": "string",
            "nullable": true,
            "description": "Юр. адрес (B2B)"
          },
          "bankDetails": {
            "type": "string",
            "nullable": true,
            "description": "Банковские реквизиты строкой (B2B)"
          },
          "contractNumber": {
            "type": "string",
            "nullable": true,
            "description": "Номер договора (B2B)"
          },
          "paymentTermsDays": {
            "type": "number",
            "nullable": true,
            "description": "Срок оплаты по договору, дни"
          },
          "creditLimit": {
            "type": "number",
            "nullable": true,
            "description": "Кредитный лимит B2B, копейки (0 = без лимита)"
          },
          "groupId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Группа контрагентов (опт): общий прайс-лист и скидка сегмента"
          },
          "priceListId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Персональный прайс-лист (опт), перекрывает прайс группы"
          },
          "slaHours": {
            "type": "number",
            "nullable": true,
            "description": "SLA по договору, часы"
          },
          "marketingConsent": {
            "type": "boolean",
            "description": "Согласие на маркетинговые рассылки (CL9)"
          }
        },
        "required": [
          "kind",
          "displayName"
        ]
      },
      "UpdateClientDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "individual",
              "legal"
            ],
            "description": "Физлицо или юрлицо"
          },
          "displayName": {
            "type": "string",
            "description": "Отображаемое имя — ФИО для физлица, название для юрлица"
          },
          "firstName": {
            "type": "string",
            "nullable": true,
            "description": "Имя"
          },
          "lastName": {
            "type": "string",
            "nullable": true,
            "description": "Фамилия"
          },
          "middleName": {
            "type": "string",
            "nullable": true,
            "description": "Отчество"
          },
          "companyName": {
            "type": "string",
            "nullable": true,
            "description": "Название компании (юрлицо)"
          },
          "position": {
            "type": "string",
            "nullable": true,
            "description": "Должность контактного лица"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "telegramChatId": {
            "type": "string",
            "nullable": true,
            "description": "Telegram chat id для исходящих сообщений (канал telegram)."
          },
          "whatsappPhone": {
            "type": "string",
            "nullable": true,
            "description": "Номер WhatsApp; пустой → используется phone."
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          },
          "tags": {
            "description": "Теги",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "birthday": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Дата рождения / основания (ISO 8601)"
          },
          "assignedToId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН (B2B, для документов)"
          },
          "kpp": {
            "type": "string",
            "nullable": true,
            "description": "КПП (B2B)"
          },
          "legalAddress": {
            "type": "string",
            "nullable": true,
            "description": "Юр. адрес (B2B)"
          },
          "bankDetails": {
            "type": "string",
            "nullable": true,
            "description": "Банковские реквизиты строкой (B2B)"
          },
          "contractNumber": {
            "type": "string",
            "nullable": true,
            "description": "Номер договора (B2B)"
          },
          "paymentTermsDays": {
            "type": "number",
            "nullable": true,
            "description": "Срок оплаты по договору, дни"
          },
          "creditLimit": {
            "type": "number",
            "nullable": true,
            "description": "Кредитный лимит B2B, копейки (0 = без лимита)"
          },
          "groupId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Группа контрагентов (опт): общий прайс-лист и скидка сегмента"
          },
          "priceListId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Персональный прайс-лист (опт), перекрывает прайс группы"
          },
          "slaHours": {
            "type": "number",
            "nullable": true,
            "description": "SLA по договору, часы"
          },
          "marketingConsent": {
            "type": "boolean",
            "description": "Согласие на маркетинговые рассылки (CL9)"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "archived"
            ],
            "description": "Статус клиента"
          }
        }
      },
      "OrderListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID заказа"
          },
          "number": {
            "type": "number",
            "description": "Номер заказа"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "confirmed",
              "in_progress",
              "ready",
              "completed",
              "cancelled"
            ],
            "description": "Статус заказа"
          },
          "paymentStatus": {
            "type": "string",
            "enum": [
              "unpaid",
              "partial",
              "paid",
              "refunded"
            ],
            "description": "Статус оплаты"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок (legacy, ISO 8601)"
          },
          "readyBy": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок готовности (ISO 8601)"
          },
          "payDueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок оплаты B2B-отсрочки (ISO 8601)"
          },
          "customerId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя покупателя"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон покупателя"
          },
          "itemsCount": {
            "type": "number",
            "description": "Сумма qty по всем позициям"
          },
          "subtotal": {
            "type": "number",
            "description": "Подытог в копейках"
          },
          "discountPercent": {
            "type": "number",
            "description": "Скидка на весь заказ, %"
          },
          "total": {
            "type": "number",
            "description": "Итог в копейках"
          },
          "prepaidAmount": {
            "type": "number",
            "description": "Внесено (копейки)"
          },
          "balanceDue": {
            "type": "number",
            "description": "Остаток к оплате (копейки)"
          },
          "createdById": {
            "type": "string",
            "nullable": true,
            "description": "ID сотрудника-автора"
          },
          "createdByName": {
            "type": "string",
            "nullable": true,
            "description": "Имя сотрудника-автора"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "assignedToName": {
            "type": "string",
            "nullable": true,
            "description": "Имя ответственного сотрудника"
          }
        },
        "required": [
          "id",
          "number",
          "status",
          "paymentStatus",
          "createdAt",
          "dueAt",
          "readyBy",
          "payDueAt",
          "customerId",
          "customerName",
          "customerPhone",
          "itemsCount",
          "subtotal",
          "discountPercent",
          "total",
          "prepaidAmount",
          "balanceDue",
          "createdById",
          "createdByName",
          "assignedToId",
          "assignedToName"
        ]
      },
      "OrderLineResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID позиции"
          },
          "orderId": {
            "type": "string",
            "description": "ID заказа"
          },
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ],
            "description": "Товар или услуга"
          },
          "productId": {
            "type": "string",
            "nullable": true,
            "description": "ID товара"
          },
          "variantId": {
            "type": "string",
            "nullable": true,
            "description": "ID варианта товара (SKU-вариация)"
          },
          "serviceId": {
            "type": "string",
            "nullable": true,
            "description": "ID услуги"
          },
          "name": {
            "type": "string",
            "description": "Название (snapshot на момент добавления)"
          },
          "qty": {
            "type": "number",
            "description": "Количество"
          },
          "unitPrice": {
            "type": "number",
            "description": "Цена за единицу в копейках"
          },
          "fulfilledQty": {
            "type": "number",
            "description": "Отгружено/готово (O6)"
          },
          "lineTotal": {
            "type": "number",
            "description": "Стоимость позиции в копейках"
          }
        },
        "required": [
          "id",
          "orderId",
          "kind",
          "productId",
          "variantId",
          "serviceId",
          "name",
          "qty",
          "unitPrice",
          "fulfilledQty",
          "lineTotal"
        ]
      },
      "OrderResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID заказа"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "number": {
            "type": "number",
            "description": "Номер заказа (сквозной по компании)"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "confirmed",
              "in_progress",
              "ready",
              "completed",
              "cancelled"
            ],
            "description": "Статус заказа"
          },
          "paymentStatus": {
            "type": "string",
            "enum": [
              "unpaid",
              "partial",
              "paid",
              "refunded"
            ],
            "description": "Статус оплаты"
          },
          "customerId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "assetId": {
            "type": "string",
            "nullable": true,
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "addressId": {
            "type": "string",
            "nullable": true,
            "description": "ID адреса клиента (ClientAddress)"
          },
          "addressLabel": {
            "type": "string",
            "nullable": true,
            "description": "Название адреса клиента (denorm по addressId)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя покупателя"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон покупателя"
          },
          "customerEmail": {
            "type": "string",
            "nullable": true,
            "description": "E-mail покупателя"
          },
          "customerNote": {
            "type": "string",
            "nullable": true,
            "description": "Пожелания покупателя"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Канал привлечения"
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "Источник (интеграция/форма)"
          },
          "deliveryStatus": {
            "type": "string",
            "nullable": true,
            "enum": [
              "pending",
              "packing",
              "shipped",
              "delivered",
              "returned"
            ],
            "description": "Статус доставки; null — без доставки"
          },
          "deliveryMethod": {
            "type": "string",
            "nullable": true,
            "enum": [
              "pickup",
              "courier",
              "post"
            ],
            "description": "Способ доставки; null — без доставки"
          },
          "deliveryCost": {
            "type": "number",
            "description": "Стоимость доставки (копейки)"
          },
          "deliveryAddressText": {
            "type": "string",
            "nullable": true,
            "description": "Адрес доставки строкой"
          },
          "dueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок (legacy, ISO 8601)"
          },
          "readyBy": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок готовности (ISO 8601)"
          },
          "payDueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок оплаты B2B-отсрочки (ISO 8601)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "subtotal": {
            "type": "number",
            "description": "Сумма позиций до скидки, копейки"
          },
          "discountPercent": {
            "type": "number",
            "description": "Скидка на весь заказ, %"
          },
          "total": {
            "type": "number",
            "description": "Итог со скидкой, копейки"
          },
          "prepaidAmount": {
            "type": "number",
            "description": "Предоплата (копейки)"
          },
          "createdById": {
            "type": "string",
            "nullable": true,
            "description": "ID сотрудника-автора"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lines": {
            "description": "Позиции заказа",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLineResponse"
            }
          }
        },
        "required": [
          "id",
          "companyId",
          "number",
          "status",
          "paymentStatus",
          "customerId",
          "assetId",
          "addressId",
          "addressLabel",
          "customerName",
          "customerPhone",
          "customerEmail",
          "customerNote",
          "channel",
          "source",
          "deliveryStatus",
          "deliveryMethod",
          "deliveryCost",
          "deliveryAddressText",
          "dueAt",
          "readyBy",
          "payDueAt",
          "note",
          "subtotal",
          "discountPercent",
          "total",
          "prepaidAmount",
          "createdById",
          "assignedToId",
          "createdAt",
          "updatedAt",
          "lines"
        ]
      },
      "OrderLineInputDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ]
          },
          "refId": {
            "type": "string",
            "description": "ID товара или услуги"
          },
          "variantId": {
            "type": "string",
            "description": "Вариант товара (SKU-вариация)"
          },
          "qty": {
            "type": "number",
            "example": 1
          },
          "unitPrice": {
            "type": "number",
            "description": "Цена за единицу в копейках"
          }
        },
        "required": [
          "kind",
          "refId",
          "qty",
          "unitPrice"
        ]
      },
      "CreateOrderDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLineInputDto"
            }
          },
          "customerId": {
            "type": "string",
            "description": "ID клиента из модуля Clients"
          },
          "assetId": {
            "type": "string",
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "addressId": {
            "type": "string",
            "description": "ID адреса клиента (ClientAddress)"
          },
          "customerName": {
            "type": "string"
          },
          "customerPhone": {
            "type": "string"
          },
          "customerEmail": {
            "type": "string"
          },
          "customerNote": {
            "type": "string"
          },
          "channel": {
            "type": "string",
            "description": "Канал привлечения (manual|public_link|phone)"
          },
          "source": {
            "type": "string",
            "description": "Источник (интеграция/форма)"
          },
          "dealId": {
            "type": "string",
            "description": "ID сделки, к которой привязан заказ-запчастей (D5)"
          },
          "dueAt": {
            "type": "string",
            "description": "Срок (legacy, ISO 8601)"
          },
          "readyBy": {
            "type": "string",
            "description": "Срок готовности (ISO 8601, O8)"
          },
          "payDueAt": {
            "type": "string",
            "description": "Срок оплаты B2B-отсрочки (ISO 8601, O8)"
          },
          "note": {
            "type": "string",
            "description": "Внутренний комментарий по заказу"
          },
          "discountPercent": {
            "type": "number",
            "default": 0,
            "minimum": 0,
            "maximum": 100
          },
          "prepaidAmount": {
            "type": "number",
            "description": "Предоплата (копейки)",
            "default": 0
          },
          "assignedToId": {
            "type": "string",
            "description": "ID ответственного сотрудника"
          }
        },
        "required": [
          "items"
        ]
      },
      "UpdateOrderDto": {
        "type": "object",
        "properties": {
          "items": {
            "description": "Полная замена позиций заказа (только в статусах new/confirmed)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderLineInputDto"
            }
          },
          "customerId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID клиента (null — отвязать)"
          },
          "assetId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID объекта обслуживания (null — отвязать)"
          },
          "addressId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID адреса клиента (null — отвязать)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя покупателя"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон покупателя"
          },
          "customerEmail": {
            "type": "string",
            "nullable": true,
            "description": "E-mail покупателя"
          },
          "customerNote": {
            "type": "string",
            "nullable": true,
            "description": "Пожелания покупателя"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Канал привлечения"
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "Источник"
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Срок (legacy, ISO 8601)"
          },
          "readyBy": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Срок готовности (ISO 8601, O8)"
          },
          "payDueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Срок оплаты B2B-отсрочки (ISO 8601, O8)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "discountPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Скидка на весь заказ, %"
          },
          "prepaidAmount": {
            "type": "number",
            "description": "Предоплата — целевая Σ оплат (копейки)"
          },
          "assignedToId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника (null — снять)"
          }
        }
      },
      "OrderStatus": {
        "type": "string",
        "enum": [
          "new",
          "confirmed",
          "in_progress",
          "ready",
          "completed",
          "cancelled"
        ]
      },
      "SaleListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID чека"
          },
          "number": {
            "type": "number",
            "description": "Номер чека"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Момент продажи (ISO 8601)"
          },
          "shiftId": {
            "type": "string",
            "description": "ID кассовой смены"
          },
          "shiftNumber": {
            "type": "number",
            "description": "Номер смены"
          },
          "cashierId": {
            "type": "string",
            "description": "ID кассира"
          },
          "cashierName": {
            "type": "string",
            "description": "Имя кассира"
          },
          "itemsCount": {
            "type": "number",
            "description": "Сумма qty по всем позициям"
          },
          "subtotal": {
            "type": "number",
            "description": "Подытог в копейках (со знаком)"
          },
          "discountPercent": {
            "type": "number",
            "description": "Скидка на весь чек, %"
          },
          "total": {
            "type": "number",
            "description": "Итог в копейках (со знаком)"
          },
          "paymentMethod": {
            "type": "string",
            "enum": [
              "cash",
              "card",
              "sbp",
              "mixed"
            ],
            "description": "Способ оплаты"
          },
          "isRefund": {
            "type": "boolean",
            "description": "Чек возврата"
          },
          "refundOfSaleId": {
            "type": "string",
            "nullable": true,
            "description": "ID исходного чека (у возврата)"
          },
          "refundOfSaleNumber": {
            "type": "number",
            "nullable": true,
            "description": "Номер исходного чека (у возврата)"
          },
          "customerId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя покупателя"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон покупателя"
          }
        },
        "required": [
          "id",
          "number",
          "createdAt",
          "shiftId",
          "shiftNumber",
          "cashierId",
          "cashierName",
          "itemsCount",
          "subtotal",
          "discountPercent",
          "total",
          "paymentMethod",
          "isRefund",
          "refundOfSaleId",
          "refundOfSaleNumber",
          "customerId",
          "customerName",
          "customerPhone"
        ]
      },
      "SaleLineResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID позиции"
          },
          "saleId": {
            "type": "string",
            "description": "ID чека"
          },
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ],
            "description": "Товар или услуга"
          },
          "productId": {
            "type": "string",
            "nullable": true,
            "description": "ID товара"
          },
          "variantId": {
            "type": "string",
            "nullable": true,
            "description": "ID варианта товара (SKU-вариация)"
          },
          "serviceId": {
            "type": "string",
            "nullable": true,
            "description": "ID услуги"
          },
          "name": {
            "type": "string",
            "description": "Название (snapshot на момент продажи)"
          },
          "qty": {
            "type": "number",
            "description": "Количество"
          },
          "unitPrice": {
            "type": "number",
            "description": "Цена за единицу в копейках"
          },
          "lineDiscountPercent": {
            "type": "number",
            "description": "Построчная скидка в процентах (K3)"
          },
          "lineDiscountAmount": {
            "type": "number",
            "description": "Построчная скидка суммой за единицу, копейки (K3)"
          },
          "lineTotal": {
            "type": "number",
            "description": "Стоимость позиции в копейках"
          },
          "refundedQty": {
            "type": "number",
            "description": "Сколько единиц уже возвращено предыдущими возвратами. Доступно к возврату — qty минус это число."
          },
          "modifiers": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "nullable": true,
            "description": "Выбранные модификаторы (P1.3b); null — без них."
          }
        },
        "required": [
          "id",
          "saleId",
          "kind",
          "productId",
          "variantId",
          "serviceId",
          "name",
          "qty",
          "unitPrice",
          "lineDiscountPercent",
          "lineDiscountAmount",
          "lineTotal",
          "refundedQty",
          "modifiers"
        ]
      },
      "SalePaymentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID платежа"
          },
          "method": {
            "type": "string",
            "enum": [
              "cash",
              "card",
              "sbp",
              "mixed"
            ],
            "description": "Способ оплаты"
          },
          "amount": {
            "type": "number",
            "description": "Сумма платежа в копейках"
          },
          "ext": {
            "type": "string",
            "nullable": true,
            "description": "Уточнение способа (эквайринг, СБП, сертификат…)"
          }
        },
        "required": [
          "id",
          "method",
          "amount",
          "ext"
        ]
      },
      "SaleResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID чека"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "shiftId": {
            "type": "string",
            "description": "ID кассовой смены"
          },
          "number": {
            "type": "number",
            "description": "Номер чека (сквозной по компании)"
          },
          "subtotal": {
            "type": "number",
            "description": "Сумма позиций до скидки, копейки"
          },
          "discountPercent": {
            "type": "number",
            "description": "Скидка на весь чек, %"
          },
          "total": {
            "type": "number",
            "description": "Итог к оплате, копейки"
          },
          "paymentMethod": {
            "type": "string",
            "enum": [
              "cash",
              "card",
              "sbp",
              "mixed"
            ],
            "description": "Основной способ оплаты (mixed — смешанная, см. payments)"
          },
          "paymentMethodExt": {
            "type": "string",
            "nullable": true,
            "description": "Уточнение способа оплаты"
          },
          "receivedAmount": {
            "type": "number",
            "nullable": true,
            "description": "Получено наличными в копейках (для расчёта сдачи)"
          },
          "cashierId": {
            "type": "string",
            "description": "ID кассира"
          },
          "refundOfSaleId": {
            "type": "string",
            "nullable": true,
            "description": "ID исходного чека; заполнен только у возврата"
          },
          "customerId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя покупателя"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон покупателя"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Канал продажи (pos, qr_menu, storefront…)"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Момент продажи (ISO 8601)"
          },
          "lines": {
            "description": "Позиции чека",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaleLineResponse"
            }
          },
          "payments": {
            "description": "Платежи чека (несколько при смешанной оплате)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalePaymentResponse"
            }
          }
        },
        "required": [
          "id",
          "companyId",
          "shiftId",
          "number",
          "subtotal",
          "discountPercent",
          "total",
          "paymentMethod",
          "paymentMethodExt",
          "receivedAmount",
          "cashierId",
          "refundOfSaleId",
          "customerId",
          "customerName",
          "customerPhone",
          "channel",
          "createdAt",
          "lines",
          "payments"
        ]
      },
      "SaleLineInputDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ]
          },
          "refId": {
            "type": "string",
            "description": "ID товара или услуги"
          },
          "variantId": {
            "type": "string",
            "description": "Вариант товара (SKU-вариация), если продаётся конкретный вариант (kind=product)."
          },
          "packageHolderId": {
            "type": "string",
            "description": "Кому выдать абонемент (kind=package), если платит не он сам: родитель оплачивает занятия ребёнка. Пусто — владельцем становится клиент чека."
          },
          "qty": {
            "type": "number",
            "example": 1,
            "maximum": 10000
          },
          "unitPrice": {
            "type": "number",
            "description": "Базовая цена за единицу в копейках"
          },
          "modifiers": {
            "type": "array",
            "description": "Выбранные модификаторы (P1.3b): [{ groupId, optionId }]. Надбавки считает сервер.",
            "items": {
              "type": "object"
            }
          },
          "lineDiscountPercent": {
            "type": "number",
            "description": "Построчная скидка в процентах (0..100) на позицию (K3)",
            "minimum": 0,
            "maximum": 100
          },
          "lineDiscountAmount": {
            "type": "number",
            "description": "Построчная скидка фиксированной суммой за единицу, копейки (K3)",
            "minimum": 0
          }
        },
        "required": [
          "kind",
          "refId",
          "qty",
          "unitPrice"
        ]
      },
      "SalePaymentInputDto": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "cash",
              "card",
              "sbp",
              "mixed"
            ]
          },
          "amount": {
            "type": "number",
            "description": "Сумма платежа в копейках"
          },
          "ext": {
            "type": "string",
            "description": "Алиас интеграционного способа оплаты"
          }
        },
        "required": [
          "method",
          "amount"
        ]
      },
      "CreateSaleDto": {
        "type": "object",
        "properties": {
          "shiftId": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SaleLineInputDto"
            }
          },
          "discountPercent": {
            "type": "number",
            "default": 0,
            "minimum": 0,
            "maximum": 100
          },
          "paymentMethod": {
            "type": "string",
            "enum": [
              "cash",
              "card",
              "sbp",
              "mixed"
            ]
          },
          "paymentMethodExt": {
            "type": "string",
            "description": "Алиас способа оплаты интеграции (ozon-wallet и т.п.); базовый paymentMethod при этом — ближайший стандартный"
          },
          "receivedAmount": {
            "type": "number",
            "description": "Полученная сумма в копейках (для cash)"
          },
          "customerId": {
            "type": "string",
            "description": "ID клиента из модуля Clients"
          },
          "redeemPoints": {
            "type": "number",
            "description": "Списать N баллов лояльности клиента как скидку (1 балл = 1 копейка)",
            "minimum": 0
          },
          "customerName": {
            "type": "string",
            "description": "Snapshot имени клиента (опционально)"
          },
          "customerPhone": {
            "type": "string",
            "description": "Snapshot телефона клиента (опционально)"
          },
          "channel": {
            "type": "string",
            "description": "Канал продажи (default pos)"
          },
          "payments": {
            "description": "Платежи (K5). Для paymentMethod=mixed обязателен и Σamount = итог чека. Для одиночной оплаты можно опустить — сервер запишет один платёж зеркально.",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SalePaymentInputDto"
            }
          }
        },
        "required": [
          "shiftId",
          "items",
          "paymentMethod"
        ]
      },
      "OpenShiftDto": {
        "type": "object",
        "properties": {
          "openingCash": {
            "type": "number",
            "description": "Начальная сумма наличных в копейках",
            "example": 500000
          }
        },
        "required": [
          "openingCash"
        ]
      },
      "ShiftResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID смены"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "number": {
            "type": "number",
            "description": "Номер смены (сквозной по компании)"
          },
          "openedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Открыта (ISO 8601)"
          },
          "closedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Закрыта (ISO 8601); null — смена открыта"
          },
          "openingCash": {
            "type": "number",
            "description": "Начальная сумма в копейках"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "description": "Статус смены"
          },
          "openedById": {
            "type": "string",
            "description": "ID сотрудника, открывшего смену"
          },
          "closedById": {
            "type": "string",
            "nullable": true,
            "description": "ID сотрудника, закрывшего смену"
          }
        },
        "required": [
          "id",
          "companyId",
          "number",
          "openedAt",
          "closedAt",
          "openingCash",
          "status",
          "openedById",
          "closedById"
        ]
      },
      "CloseShiftDto": {
        "type": "object",
        "properties": {
          "closingCash": {
            "type": "number",
            "description": "Фактический остаток наличных в копейках"
          }
        }
      },
      "WarehouseListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID склада"
          },
          "name": {
            "type": "string",
            "description": "Название склада"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес склада"
          },
          "isDefault": {
            "type": "boolean",
            "description": "Склад по умолчанию"
          },
          "managerUserId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "managerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя ответственного сотрудника"
          },
          "totalQty": {
            "type": "number",
            "description": "Сумма qty по складу"
          },
          "productsCount": {
            "type": "number",
            "description": "Кол-во SKU с qty > 0 на складе"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "address",
          "isDefault",
          "managerUserId",
          "managerName",
          "totalQty",
          "productsCount",
          "createdAt",
          "updatedAt"
        ]
      },
      "WarehouseResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID склада"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "name": {
            "type": "string",
            "description": "Название склада"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес склада"
          },
          "isDefault": {
            "type": "boolean",
            "description": "Склад по умолчанию для приёмок и списаний"
          },
          "managerUserId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создано (ISO 8601)"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Обновлено (ISO 8601)"
          }
        },
        "required": [
          "id",
          "companyId",
          "name",
          "address",
          "isDefault",
          "managerUserId",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateWarehouseDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Основной",
            "description": "Название склада"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес склада"
          },
          "managerUserId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "branchId": {
            "type": "string",
            "format": "uuid",
            "description": "Филиал склада (1:1). Если не указан — берётся филиал компании без склада."
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateWarehouseDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Основной",
            "description": "Название склада"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес склада"
          },
          "managerUserId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "branchId": {
            "type": "string",
            "format": "uuid",
            "description": "Филиал склада (1:1). Если не указан — берётся филиал компании без склада."
          }
        }
      },
      "SupplierResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID поставщика"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "name": {
            "type": "string",
            "description": "Название поставщика"
          },
          "contactName": {
            "type": "string",
            "nullable": true,
            "description": "Контактное лицо"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создано (ISO 8601)"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Обновлено (ISO 8601)"
          }
        },
        "required": [
          "id",
          "companyId",
          "name",
          "contactName",
          "phone",
          "email",
          "inn",
          "address",
          "note",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateSupplierDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Название поставщика"
          },
          "contactName": {
            "type": "string",
            "nullable": true,
            "description": "Контактное лицо"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          }
        },
        "required": [
          "name"
        ]
      },
      "UpdateSupplierDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Название поставщика"
          },
          "contactName": {
            "type": "string",
            "nullable": true,
            "description": "Контактное лицо"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "inn": {
            "type": "string",
            "nullable": true,
            "description": "ИНН"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          }
        }
      },
      "StockListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID записи остатка"
          },
          "productId": {
            "type": "string",
            "description": "ID товара"
          },
          "productName": {
            "type": "string",
            "description": "Название товара"
          },
          "productSku": {
            "type": "string",
            "description": "Артикул товара"
          },
          "variantId": {
            "type": "string",
            "nullable": true,
            "description": "ID варианта товара; null — товар без вариантов"
          },
          "variantSku": {
            "type": "string",
            "nullable": true,
            "description": "Артикул варианта"
          },
          "variantAttributes": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true,
            "description": "Атрибуты варианта: { \"color\": \"red\", \"size\": \"M\" }"
          },
          "categoryId": {
            "type": "string",
            "nullable": true,
            "description": "ID категории товара"
          },
          "categoryName": {
            "type": "string",
            "nullable": true,
            "description": "Название категории"
          },
          "warehouseId": {
            "type": "string",
            "description": "ID склада"
          },
          "warehouseName": {
            "type": "string",
            "description": "Название склада"
          },
          "qty": {
            "type": "number",
            "description": "Физический остаток"
          },
          "reserved": {
            "type": "number",
            "description": "Зарезервировано под незавершённые заказы"
          },
          "available": {
            "type": "number",
            "description": "Свободно к продаже: qty − reserved"
          },
          "reorderPoint": {
            "type": "number",
            "description": "Порог дозаказа (0 — не задан)"
          },
          "isLowStock": {
            "type": "boolean",
            "description": "Остаток на пороге или ниже"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Последнее движение по остатку (ISO 8601)"
          }
        },
        "required": [
          "id",
          "productId",
          "productName",
          "productSku",
          "variantId",
          "variantSku",
          "variantAttributes",
          "categoryId",
          "categoryName",
          "warehouseId",
          "warehouseName",
          "qty",
          "reserved",
          "available",
          "reorderPoint",
          "isLowStock",
          "updatedAt"
        ]
      },
      "AdjustStockDto": {
        "type": "object",
        "properties": {
          "productId": {
            "type": "string"
          },
          "variantId": {
            "type": "string",
            "description": "Вариант товара (SKU-вариация); опускается для товара без вариантов."
          },
          "warehouseId": {
            "type": "string"
          },
          "targetQty": {
            "type": "number",
            "description": "Новое значение остатка (целое число, может быть отрицательным)."
          },
          "reason": {
            "type": "string",
            "description": "Причина корректировки (обязательно)."
          }
        },
        "required": [
          "productId",
          "warehouseId",
          "targetQty",
          "reason"
        ]
      },
      "ReceiptListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID приёмки"
          },
          "number": {
            "type": "number",
            "description": "Номер приёмки"
          },
          "status": {
            "type": "string",
            "enum": [
              "posted",
              "cancelled"
            ],
            "description": "Статус приёмки"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "description": "Дата приёмки (ISO 8601)"
          },
          "warehouseId": {
            "type": "string",
            "description": "ID склада"
          },
          "warehouseName": {
            "type": "string",
            "description": "Название склада"
          },
          "supplierId": {
            "type": "string",
            "nullable": true,
            "description": "ID поставщика"
          },
          "supplierName": {
            "type": "string",
            "nullable": true,
            "description": "Название поставщика"
          },
          "purchaseOrderId": {
            "type": "string",
            "nullable": true,
            "description": "ID заказа поставщику"
          },
          "purchaseOrderNumber": {
            "type": "number",
            "nullable": true,
            "description": "Номер заказа поставщику"
          },
          "itemsCount": {
            "type": "number",
            "description": "Число позиций"
          },
          "totalQty": {
            "type": "number",
            "description": "Сумма qty по всем позициям"
          },
          "totalAmount": {
            "type": "number",
            "description": "Сумма приёмки в копейках"
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "createdByName": {
            "type": "string",
            "description": "Имя сотрудника-автора"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создано (ISO 8601)"
          }
        },
        "required": [
          "id",
          "number",
          "status",
          "date",
          "warehouseId",
          "warehouseName",
          "supplierId",
          "supplierName",
          "purchaseOrderId",
          "purchaseOrderNumber",
          "itemsCount",
          "totalQty",
          "totalAmount",
          "createdById",
          "createdByName",
          "createdAt"
        ]
      },
      "ReceiptLineResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID позиции"
          },
          "receiptId": {
            "type": "string",
            "description": "ID приёмки"
          },
          "productId": {
            "type": "string",
            "description": "ID товара"
          },
          "variantId": {
            "type": "string",
            "nullable": true,
            "description": "ID варианта товара (SKU-вариация)"
          },
          "productName": {
            "type": "string",
            "description": "Название товара"
          },
          "productSku": {
            "type": "string",
            "description": "Артикул товара"
          },
          "qty": {
            "type": "number",
            "description": "Количество"
          },
          "unitCost": {
            "type": "number",
            "description": "Закупочная цена за единицу в копейках"
          },
          "lineTotal": {
            "type": "number",
            "description": "Стоимость позиции в копейках"
          }
        },
        "required": [
          "id",
          "receiptId",
          "productId",
          "variantId",
          "productName",
          "productSku",
          "qty",
          "unitCost",
          "lineTotal"
        ]
      },
      "ReceiptResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID приёмки"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "number": {
            "type": "number",
            "description": "Номер приёмки (сквозной по компании)"
          },
          "status": {
            "type": "string",
            "enum": [
              "posted",
              "cancelled"
            ],
            "description": "Статус приёмки"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "description": "Дата приёмки (ISO 8601)"
          },
          "warehouseId": {
            "type": "string",
            "description": "ID склада"
          },
          "warehouseName": {
            "type": "string",
            "description": "Название склада"
          },
          "supplierId": {
            "type": "string",
            "nullable": true,
            "description": "ID поставщика"
          },
          "supplierName": {
            "type": "string",
            "nullable": true,
            "description": "Название поставщика"
          },
          "purchaseOrderId": {
            "type": "string",
            "nullable": true,
            "description": "ID заказа поставщику, по которому пришёл товар"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Комментарий к приёмке"
          },
          "totalQty": {
            "type": "number",
            "description": "Сумма qty по всем позициям"
          },
          "totalAmount": {
            "type": "number",
            "description": "Сумма приёмки в копейках"
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "createdByName": {
            "type": "string",
            "description": "Имя сотрудника-автора"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создано (ISO 8601)"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Обновлено (ISO 8601)"
          },
          "lines": {
            "description": "Позиции приёмки",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptLineResponse"
            }
          }
        },
        "required": [
          "id",
          "companyId",
          "number",
          "status",
          "date",
          "warehouseId",
          "warehouseName",
          "supplierId",
          "supplierName",
          "purchaseOrderId",
          "note",
          "totalQty",
          "totalAmount",
          "createdById",
          "createdByName",
          "createdAt",
          "updatedAt",
          "lines"
        ]
      },
      "ReceiptLineInputDto": {
        "type": "object",
        "properties": {
          "productId": {
            "type": "string",
            "format": "uuid",
            "description": "ID товара"
          },
          "variantId": {
            "type": "string",
            "description": "Вариант товара (SKU-вариация); опускается для товара без вариантов."
          },
          "qty": {
            "type": "number",
            "minimum": 1,
            "example": 1,
            "description": "Количество"
          },
          "unitCost": {
            "type": "number",
            "description": "Закупочная цена за единицу в копейках"
          },
          "batchNumber": {
            "type": "string",
            "description": "Номер партии (информационный учёт)"
          },
          "expiryDate": {
            "type": "string",
            "description": "Срок годности партии (ISO 8601)"
          }
        },
        "required": [
          "productId",
          "qty",
          "unitCost"
        ]
      },
      "CreateReceiptDto": {
        "type": "object",
        "properties": {
          "warehouseId": {
            "type": "string",
            "format": "uuid",
            "description": "ID склада"
          },
          "supplierId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID поставщика"
          },
          "purchaseOrderId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID заказа поставщику (W3)"
          },
          "date": {
            "type": "string",
            "description": "Дата приёмки (ISO 8601)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Комментарий к приёмке"
          },
          "items": {
            "description": "Позиции приёмки",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptLineInputDto"
            }
          }
        },
        "required": [
          "warehouseId",
          "items"
        ]
      },
      "CalendarEventInstanceResponse": {
        "type": "object",
        "properties": {
          "originId": {
            "type": "string",
            "description": "ID master-события (одинаков для всех инстансов серии)"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "kind": {
            "type": "string",
            "enum": [
              "event",
              "work_shift",
              "day_off",
              "task",
              "reminder"
            ],
            "description": "Вид события"
          },
          "title": {
            "type": "string",
            "description": "Заголовок события"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание"
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "description": "Начало инстанса (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "description": "Окончание инстанса (ISO 8601)"
          },
          "allDay": {
            "type": "boolean",
            "description": "Событие на весь день"
          },
          "isCompanyWide": {
            "type": "boolean",
            "description": "Видно всем сотрудникам компании"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Цвет (HEX)"
          },
          "location": {
            "type": "string",
            "nullable": true,
            "description": "Место проведения"
          },
          "isRecurringInstance": {
            "type": "boolean",
            "description": "Инстанс развёрнут из повторяющейся серии, а не разовое событие"
          },
          "isDone": {
            "type": "boolean",
            "description": "Событие отмечено выполненным"
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "attendeeIds": {
            "description": "ID участников события",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "originId",
          "companyId",
          "kind",
          "title",
          "description",
          "startAt",
          "endAt",
          "allDay",
          "isCompanyWide",
          "color",
          "location",
          "isRecurringInstance",
          "isDone",
          "createdById",
          "attendeeIds"
        ]
      },
      "CalendarRecurrenceResponse": {
        "type": "object",
        "properties": {
          "freq": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "Частота повторения"
          },
          "interval": {
            "type": "number",
            "description": "Шаг повторения: каждые N дней/недель/месяцев"
          },
          "byWeekday": {
            "nullable": true,
            "description": "Дни недели для weekly: 0=вс, 1=пн, ..., 6=сб",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "until": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Дата окончания серии (ISO 8601); null — бессрочно"
          }
        },
        "required": [
          "freq",
          "interval",
          "byWeekday",
          "until"
        ]
      },
      "CalendarEventResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID события"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "kind": {
            "type": "string",
            "enum": [
              "event",
              "work_shift",
              "day_off",
              "task",
              "reminder"
            ],
            "description": "Вид события"
          },
          "title": {
            "type": "string",
            "description": "Заголовок события"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание"
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "description": "Начало (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "description": "Окончание (ISO 8601)"
          },
          "allDay": {
            "type": "boolean",
            "description": "Событие на весь день"
          },
          "isCompanyWide": {
            "type": "boolean",
            "description": "Видно всем сотрудникам компании"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Цвет (HEX)"
          },
          "location": {
            "type": "string",
            "nullable": true,
            "description": "Место проведения"
          },
          "recurrence": {
            "nullable": true,
            "description": "Правило повторения; null — разовое событие",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/CalendarRecurrenceResponse"
              }
            ]
          },
          "reminderMinutesBefore": {
            "type": "number",
            "nullable": true,
            "description": "За сколько минут до начала прислать напоминание"
          },
          "reminderSentAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда отправлено напоминание (ISO 8601)"
          },
          "isDone": {
            "type": "boolean",
            "description": "Событие отмечено выполненным"
          },
          "doneAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда отмечено выполненным (ISO 8601)"
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "attendeeIds": {
            "description": "ID участников события",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создано (ISO 8601)"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Обновлено (ISO 8601)"
          }
        },
        "required": [
          "id",
          "companyId",
          "kind",
          "title",
          "description",
          "startAt",
          "endAt",
          "allDay",
          "isCompanyWide",
          "color",
          "location",
          "reminderMinutesBefore",
          "reminderSentAt",
          "isDone",
          "doneAt",
          "createdById",
          "attendeeIds",
          "createdAt",
          "updatedAt"
        ]
      },
      "CalendarRecurrenceDto": {
        "type": "object",
        "properties": {
          "freq": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "Частота повторения"
          },
          "interval": {
            "type": "number",
            "minimum": 1,
            "maximum": 365,
            "default": 1,
            "description": "Шаг повторения: каждые N дней/недель/месяцев"
          },
          "byWeekday": {
            "nullable": true,
            "description": "Дни недели для weekly: 0=вс, 1=пн, ..., 6=сб",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Дата окончания серии (ISO 8601); null — бессрочно"
          }
        },
        "required": [
          "freq",
          "interval"
        ]
      },
      "CreateCalendarEventDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "event",
              "work_shift",
              "day_off",
              "task",
              "reminder"
            ],
            "description": "Вид события"
          },
          "title": {
            "type": "string",
            "description": "Заголовок события"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание события"
          },
          "startAt": {
            "type": "string",
            "description": "Начало события (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "description": "Окончание события (ISO 8601)"
          },
          "allDay": {
            "type": "boolean",
            "default": false,
            "description": "Событие на весь день"
          },
          "isCompanyWide": {
            "type": "boolean",
            "default": false,
            "description": "Видно всем сотрудникам компании"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "example": "#7A5AF8",
            "description": "Цвет события (HEX)"
          },
          "location": {
            "type": "string",
            "nullable": true,
            "description": "Место проведения"
          },
          "attendeeIds": {
            "description": "ID участников события",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recurrence": {
            "nullable": true,
            "description": "Правило повторения; null — разовое событие",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/CalendarRecurrenceDto"
              }
            ]
          },
          "reminderMinutesBefore": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "maximum": 43200,
            "description": "Минут до начала, чтобы прислать напоминание"
          }
        },
        "required": [
          "kind",
          "title",
          "startAt",
          "endAt"
        ]
      },
      "UpdateCalendarEventDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "event",
              "work_shift",
              "day_off",
              "task",
              "reminder"
            ],
            "description": "Вид события"
          },
          "title": {
            "type": "string",
            "description": "Заголовок события"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Описание события"
          },
          "startAt": {
            "type": "string",
            "description": "Начало события (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "description": "Окончание события (ISO 8601)"
          },
          "allDay": {
            "type": "boolean",
            "default": false,
            "description": "Событие на весь день"
          },
          "isCompanyWide": {
            "type": "boolean",
            "default": false,
            "description": "Видно всем сотрудникам компании"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "example": "#7A5AF8",
            "description": "Цвет события (HEX)"
          },
          "location": {
            "type": "string",
            "nullable": true,
            "description": "Место проведения"
          },
          "attendeeIds": {
            "description": "ID участников события",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recurrence": {
            "nullable": true,
            "description": "Правило повторения; null — разовое событие",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/CalendarRecurrenceDto"
              }
            ]
          },
          "reminderMinutesBefore": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "maximum": 43200,
            "description": "Минут до начала, чтобы прислать напоминание"
          }
        }
      },
      "DealLostReasonResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID причины"
          },
          "name": {
            "type": "string",
            "description": "Название причины"
          },
          "isActive": {
            "type": "boolean",
            "description": "Активна: доступна при закрытии сделки"
          },
          "position": {
            "type": "number",
            "description": "Порядок в списке"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создана (ISO 8601)"
          }
        },
        "required": [
          "id",
          "name",
          "isActive",
          "position",
          "createdAt"
        ]
      },
      "LeadSourceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "UUID источника"
          },
          "name": {
            "type": "string",
            "description": "Название"
          },
          "isActive": {
            "type": "boolean",
            "description": "Активен ли источник"
          },
          "position": {
            "type": "number",
            "description": "Порядок сортировки"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "isActive",
          "position",
          "createdAt"
        ]
      },
      "DealStageResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID стадии"
          },
          "sortOrder": {
            "type": "number",
            "description": "Порядок в пайплайне"
          },
          "name": {
            "type": "string",
            "description": "Название стадии"
          },
          "isInitial": {
            "type": "boolean",
            "description": "Начальная стадия для новых сделок"
          },
          "terminalOutcome": {
            "type": "string",
            "enum": [
              "won",
              "lost",
              "done",
              "cancelled"
            ],
            "nullable": true,
            "description": "Исход терминальной стадии (won/lost); null — промежуточная"
          },
          "kind": {
            "type": "string",
            "enum": [
              "in_transit",
              "on_site"
            ],
            "nullable": true,
            "description": "Семантика стадии для автоматики; null — обычная"
          },
          "checklist": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Чек-лист стадии: [{ label, done? }]"
          },
          "wipLimit": {
            "type": "number",
            "nullable": true,
            "description": "Мягкий лимит карточек в колонке доски (WIP)"
          }
        },
        "required": [
          "id",
          "sortOrder",
          "name",
          "isInitial",
          "terminalOutcome",
          "kind",
          "checklist",
          "wipLimit"
        ]
      },
      "DealTypeResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID типа сделки"
          },
          "alias": {
            "type": "string",
            "enum": [
              "sale_order",
              "project",
              "production",
              "field_job",
              "lead",
              "intake",
              "maintenance",
              "event"
            ],
            "description": "Системный алиас типа (sale_order, project, field_job, intake…)"
          },
          "name": {
            "type": "string",
            "description": "Название типа"
          },
          "features": {
            "description": "Включённые возможности типа (lines, payments, schedule, address…)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Конфигурация типа (правила доски, печати, автоматики)"
          },
          "isActive": {
            "type": "boolean",
            "description": "Тип активен и доступен для новых сделок"
          },
          "isSystem": {
            "type": "boolean",
            "description": "Системный тип: нельзя удалить"
          },
          "available": {
            "type": "boolean",
            "description": "Компонент типа включён у компании"
          },
          "stages": {
            "description": "Стадии пайплайна по порядку",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DealStageResponse"
            }
          }
        },
        "required": [
          "id",
          "alias",
          "name",
          "features",
          "config",
          "isActive",
          "isSystem",
          "available",
          "stages"
        ]
      },
      "DealListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID сделки"
          },
          "number": {
            "type": "number",
            "description": "Номер сделки"
          },
          "typeId": {
            "type": "string",
            "description": "ID типа сделки"
          },
          "typeName": {
            "type": "string",
            "description": "Название типа сделки"
          },
          "stageId": {
            "type": "string",
            "description": "ID текущей стадии"
          },
          "stageName": {
            "type": "string",
            "description": "Название стадии"
          },
          "outcome": {
            "type": "string",
            "enum": [
              "won",
              "lost",
              "done",
              "cancelled"
            ],
            "nullable": true,
            "description": "Исход: won/lost на терминальной стадии, иначе null"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок исполнения (ISO 8601)"
          },
          "scheduledAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Запланированное время (ISO 8601)"
          },
          "clientId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя заказчика"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон заказчика"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес выполнения"
          },
          "itemsCount": {
            "type": "number",
            "description": "Сумма qty по всем позициям"
          },
          "total": {
            "type": "number",
            "description": "Итог в копейках"
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость в копейках"
          },
          "budget": {
            "type": "number",
            "nullable": true,
            "description": "Бюджет (копейки)"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "assignedToName": {
            "type": "string",
            "nullable": true,
            "description": "Имя ответственного сотрудника"
          },
          "sourceId": {
            "type": "string",
            "nullable": true,
            "description": "ID источника лида из справочника"
          },
          "stageEnteredAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда вошла в текущую стадию (для «дней в стадии» на доске)."
          },
          "nextActionAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Дедлайн ближайшей незакрытой задачи; null — «без задачи»."
          },
          "boardOrder": {
            "type": "number",
            "nullable": true,
            "description": "Ручной порядок карточки в колонке доски; null — не сортировалась."
          },
          "lostReasonId": {
            "type": "string",
            "nullable": true,
            "description": "ID причины проигрыша (терминальный Lost), иначе null"
          }
        },
        "required": [
          "id",
          "number",
          "typeId",
          "typeName",
          "stageId",
          "stageName",
          "outcome",
          "createdAt",
          "dueAt",
          "scheduledAt",
          "clientId",
          "customerName",
          "customerPhone",
          "address",
          "itemsCount",
          "total",
          "cost",
          "budget",
          "assignedToId",
          "assignedToName",
          "sourceId",
          "stageEnteredAt",
          "nextActionAt",
          "boardOrder",
          "lostReasonId"
        ]
      },
      "DealLineResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID позиции"
          },
          "dealId": {
            "type": "string",
            "description": "ID сделки"
          },
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ],
            "description": "Товар или услуга"
          },
          "productId": {
            "type": "string",
            "nullable": true,
            "description": "ID товара"
          },
          "serviceId": {
            "type": "string",
            "nullable": true,
            "description": "ID услуги"
          },
          "name": {
            "type": "string",
            "description": "Название (snapshot на момент добавления)"
          },
          "qty": {
            "type": "number",
            "description": "Количество"
          },
          "unitPrice": {
            "type": "number",
            "description": "Цена за единицу в копейках"
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость за единицу в копейках"
          },
          "lineTotal": {
            "type": "number",
            "description": "Стоимость позиции в копейках"
          },
          "perGuestQty": {
            "type": "number",
            "nullable": true,
            "description": "Норма на одного гостя; null — количество от числа гостей не зависит"
          }
        },
        "required": [
          "id",
          "dealId",
          "kind",
          "productId",
          "serviceId",
          "name",
          "qty",
          "unitPrice",
          "cost",
          "lineTotal",
          "perGuestQty"
        ]
      },
      "DealResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID сделки"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "number": {
            "type": "number",
            "description": "Номер сделки (сквозной по компании)"
          },
          "typeId": {
            "type": "string",
            "description": "ID типа сделки"
          },
          "stageId": {
            "type": "string",
            "description": "ID текущей стадии"
          },
          "checklistDone": {
            "description": "Выполненные пункты чек-листа: ключи вида `<stageId>:<index>`",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "outcome": {
            "type": "string",
            "enum": [
              "won",
              "lost",
              "done",
              "cancelled"
            ],
            "nullable": true,
            "description": "Исход: won/lost на терминальной стадии, иначе null"
          },
          "clientId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "assetId": {
            "type": "string",
            "nullable": true,
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "addressId": {
            "type": "string",
            "nullable": true,
            "description": "ID адреса клиента (ClientAddress)"
          },
          "venueResourceId": {
            "type": "string",
            "nullable": true,
            "description": "ID площадки мероприятия (ресурс расписания)"
          },
          "addressLabel": {
            "type": "string",
            "nullable": true,
            "description": "Название адреса клиента (denorm по addressId)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя заказчика"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон заказчика"
          },
          "customerEmail": {
            "type": "string",
            "nullable": true,
            "description": "E-mail заказчика"
          },
          "customerNote": {
            "type": "string",
            "nullable": true,
            "description": "Пожелания заказчика"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Канал привлечения (manual|public_link|phone)"
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "Источник строкой (интеграция/форма)"
          },
          "sourceId": {
            "type": "string",
            "nullable": true,
            "description": "ID источника лида из справочника"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес выполнения (для field_job)"
          },
          "scheduledAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Запланированное время (ISO 8601)"
          },
          "dueAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Срок исполнения (ISO 8601)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "subtotal": {
            "type": "number",
            "description": "Сумма позиций до скидки, копейки"
          },
          "discountPercent": {
            "type": "number",
            "description": "Скидка на всю сделку, %"
          },
          "total": {
            "type": "number",
            "description": "Итог со скидкой, копейки"
          },
          "cost": {
            "type": "number",
            "description": "Себестоимость по позициям, копейки"
          },
          "budget": {
            "type": "number",
            "nullable": true,
            "description": "Бюджет (копейки)"
          },
          "budgetExceededAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда себестоимость превысила бюджет (ISO 8601)"
          },
          "headcount": {
            "type": "number",
            "nullable": true,
            "description": "Число гостей мероприятия"
          },
          "lostReasonId": {
            "type": "string",
            "nullable": true,
            "description": "ID причины проигрыша (терминальный Lost), иначе null."
          },
          "nextActionAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Дедлайн ближайшей незакрытой задачи (next-action); null — «без задачи»."
          },
          "stageEnteredAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда сделка вошла в текущую стадию (D1)."
          },
          "createdById": {
            "type": "string",
            "description": "ID сотрудника-автора"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID ответственного сотрудника"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lines": {
            "description": "Позиции сметы",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DealLineResponse"
            }
          }
        },
        "required": [
          "id",
          "companyId",
          "number",
          "typeId",
          "stageId",
          "checklistDone",
          "outcome",
          "clientId",
          "assetId",
          "addressId",
          "venueResourceId",
          "addressLabel",
          "customerName",
          "customerPhone",
          "customerEmail",
          "customerNote",
          "channel",
          "source",
          "sourceId",
          "address",
          "scheduledAt",
          "dueAt",
          "note",
          "subtotal",
          "discountPercent",
          "total",
          "cost",
          "budget",
          "budgetExceededAt",
          "headcount",
          "lostReasonId",
          "nextActionAt",
          "stageEnteredAt",
          "createdById",
          "assignedToId",
          "createdAt",
          "updatedAt",
          "lines"
        ]
      },
      "DealLineInputDto": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "product",
              "service",
              "package"
            ]
          },
          "refId": {
            "type": "string",
            "description": "ID товара или услуги"
          },
          "qty": {
            "type": "number",
            "example": 1
          },
          "unitPrice": {
            "type": "number",
            "description": "Цена за единицу в копейках"
          },
          "perGuestQty": {
            "type": "number",
            "description": "Норма на одного гостя: 1 порция сет-меню — 1, две закуски на гостя — 2. Задана — количество пересчитывается от числа гостей мероприятия.",
            "example": 2
          }
        },
        "required": [
          "kind",
          "refId",
          "qty",
          "unitPrice"
        ]
      },
      "DealIntakeDto": {
        "type": "object",
        "properties": {
          "deviceKind": {
            "type": "string",
            "nullable": true,
            "description": "Вид объекта (телефон, ноутбук, авто, обувь…)"
          },
          "brand": {
            "type": "string",
            "nullable": true,
            "description": "Марка/бренд"
          },
          "model": {
            "type": "string",
            "nullable": true,
            "description": "Модель"
          },
          "serial": {
            "type": "string",
            "nullable": true,
            "description": "Серийный номер / IMEI / VIN"
          },
          "defect": {
            "type": "string",
            "nullable": true,
            "description": "Заявленная неисправность"
          },
          "accessories": {
            "type": "string",
            "nullable": true,
            "description": "Комплектация (что принято вместе с устройством)"
          },
          "appearance": {
            "type": "string",
            "nullable": true,
            "description": "Внешний вид (царапины, сколы)"
          },
          "condition": {
            "type": "string",
            "nullable": true,
            "description": "Состояние при приёмке"
          },
          "agreedPrice": {
            "type": "number",
            "nullable": true,
            "description": "Согласованная цена работ в копейках"
          },
          "agreedTermDays": {
            "type": "number",
            "nullable": true,
            "description": "Согласованный срок, дней"
          },
          "prepayment": {
            "type": "number",
            "nullable": true,
            "description": "Предоплата в копейках"
          }
        }
      },
      "CreateDealDto": {
        "type": "object",
        "properties": {
          "typeId": {
            "type": "string",
            "description": "ID типа сделки"
          },
          "items": {
            "description": "Позиции сметы (товары и услуги)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DealLineInputDto"
            }
          },
          "clientId": {
            "type": "string",
            "description": "ID клиента из модуля Clients"
          },
          "assetId": {
            "type": "string",
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "addressId": {
            "type": "string",
            "description": "ID адреса клиента (ClientAddress)"
          },
          "customerName": {
            "type": "string",
            "description": "Имя заказчика (если без карточки клиента)"
          },
          "customerPhone": {
            "type": "string",
            "description": "Телефон заказчика"
          },
          "customerEmail": {
            "type": "string",
            "description": "E-mail заказчика"
          },
          "customerNote": {
            "type": "string",
            "description": "Пожелания заказчика"
          },
          "channel": {
            "type": "string",
            "description": "Канал привлечения (manual|public_link|phone)"
          },
          "source": {
            "type": "string",
            "description": "Источник (интеграция/форма)"
          },
          "sourceId": {
            "type": "string",
            "description": "ID источника лида из справочника (D7)"
          },
          "budget": {
            "type": "number",
            "description": "Плановый бюджет проекта в копейках (D4)"
          },
          "assignedToId": {
            "type": "string",
            "description": "ID ответственного сотрудника"
          },
          "address": {
            "type": "string",
            "description": "Адрес выполнения (для field_job)"
          },
          "venueResourceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Площадка мероприятия — ресурс расписания (зал, шатёр). По ней вешается бронь и сверяется вместимость; раньше зал угадывался по строке адреса."
          },
          "scheduledAt": {
            "type": "string",
            "description": "Запланированное время (ISO 8601)"
          },
          "dueAt": {
            "type": "string",
            "description": "Срок исполнения (ISO 8601)"
          },
          "headcount": {
            "type": "number",
            "description": "Число гостей мероприятия: множитель для позиций с нормой на гостя."
          },
          "note": {
            "type": "string",
            "description": "Внутренний комментарий"
          },
          "discountPercent": {
            "type": "number",
            "default": 0,
            "minimum": 0,
            "maximum": 100,
            "description": "Скидка на всю сделку, %"
          },
          "intake": {
            "description": "Снапшот приёмки (для типа intake)",
            "allOf": [
              {
                "$ref": "#/components/schemas/DealIntakeDto"
              }
            ]
          }
        },
        "required": [
          "typeId"
        ]
      },
      "UpdateDealDto": {
        "type": "object",
        "properties": {
          "items": {
            "description": "Полная замена позиций сметы",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DealLineInputDto"
            }
          },
          "clientId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID клиента (null — отвязать)"
          },
          "assetId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID объекта обслуживания (null — отвязать)"
          },
          "addressId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID адреса клиента (null — отвязать)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя заказчика"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон заказчика"
          },
          "customerEmail": {
            "type": "string",
            "nullable": true,
            "description": "E-mail заказчика"
          },
          "customerNote": {
            "type": "string",
            "nullable": true,
            "description": "Пожелания заказчика"
          },
          "assignedToId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID ответственного сотрудника (null — снять)"
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес выполнения (для field_job)"
          },
          "venueResourceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Площадка мероприятия — ресурс расписания (null — снять)."
          },
          "scheduledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Запланированное время (ISO 8601)"
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Срок исполнения (ISO 8601)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "discountPercent": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Скидка на всю сделку, %"
          },
          "sourceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID источника лида из справочника (D7), null — отвязать"
          },
          "budget": {
            "type": "number",
            "nullable": true,
            "description": "Плановый бюджет проекта в копейках (D4), null — снять"
          },
          "headcount": {
            "type": "number",
            "nullable": true,
            "description": "Число гостей мероприятия, null — снять. Позиции сметы с нормой на гостя пересчитываются под новое значение."
          }
        }
      },
      "ChangeDealStageDto": {
        "type": "object",
        "properties": {
          "stageId": {
            "type": "string",
            "format": "uuid",
            "description": "ID целевой стадии (в рамках того же типа сделки)"
          },
          "lostReasonId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID причины проигрыша — при переходе на терминальную стадию с исходом Lost."
          }
        },
        "required": [
          "stageId"
        ]
      },
      "ResourceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID ресурса"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "type": {
            "type": "string",
            "enum": [
              "staff",
              "seat",
              "unit",
              "equipment"
            ],
            "description": "Тип ресурса"
          },
          "name": {
            "type": "string",
            "description": "Название ресурса"
          },
          "capacity": {
            "type": "number",
            "description": "Сколько броней ресурс держит одновременно"
          },
          "seats": {
            "type": "number",
            "nullable": true,
            "description": "Сколько гостей вмещает площадка; null — неприменимо"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Цвет в календаре (HEX)"
          },
          "bufferMinutes": {
            "type": "number",
            "description": "Буфер между бронями, минут"
          },
          "minDurationMinutes": {
            "type": "number",
            "nullable": true,
            "description": "Минимальная длительность брони, минут; null — без ограничения"
          },
          "availability": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Окна доступности по дням недели: [{ weekday, from, to }]"
          },
          "isActive": {
            "type": "boolean",
            "description": "Ресурс активен и доступен для записи"
          },
          "housekeepingState": {
            "type": "string",
            "enum": [
              "ready",
              "dirty",
              "cleaning",
              "out_of_service"
            ],
            "description": "Состояние уборки юнита (для размещения)"
          },
          "userId": {
            "type": "string",
            "nullable": true,
            "description": "Учётка сотрудника за ресурсом (мастер)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "type",
          "name",
          "capacity",
          "seats",
          "color",
          "bufferMinutes",
          "minDurationMinutes",
          "availability",
          "isActive",
          "housekeepingState",
          "userId",
          "note",
          "createdAt",
          "updatedAt"
        ]
      },
      "ResourceAvailabilityWindowDto": {
        "type": "object",
        "properties": {
          "weekday": {
            "type": "number",
            "description": "День недели: 0=вс … 6=сб",
            "minimum": 0,
            "maximum": 6
          },
          "from": {
            "type": "string",
            "example": "09:00",
            "description": "Начало окна, HH:MM"
          },
          "to": {
            "type": "string",
            "example": "18:00",
            "description": "Конец окна, HH:MM"
          }
        },
        "required": [
          "weekday",
          "from",
          "to"
        ]
      },
      "CreateResourceDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "staff",
              "seat",
              "unit",
              "equipment"
            ],
            "description": "Тип ресурса"
          },
          "name": {
            "type": "string",
            "description": "Название ресурса"
          },
          "capacity": {
            "type": "number",
            "default": 1,
            "minimum": 1,
            "description": "Сколько броней ресурс держит одновременно"
          },
          "seats": {
            "type": "number",
            "description": "Сколько гостей вмещает площадка (зал, веранда, беседка). Отличается от `capacity`: та говорит, сколько броней ресурса идут одновременно.",
            "minimum": 1
          },
          "color": {
            "type": "string",
            "example": "#0ea5e9",
            "description": "Цвет в календаре (HEX)"
          },
          "bufferMinutes": {
            "type": "number",
            "default": 0,
            "minimum": 0,
            "description": "Буфер между бронями, минут"
          },
          "minDurationMinutes": {
            "type": "number",
            "minimum": 1,
            "description": "Минимальная длительность брони, минут"
          },
          "availability": {
            "description": "Окна доступности по дням недели",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResourceAvailabilityWindowDto"
            }
          },
          "userId": {
            "type": "string",
            "format": "uuid",
            "description": "Учётка сотрудника за ресурсом (мастер салона): из неё подставляется ответственный записи, чтобы комиссия считалась по тому же человеку."
          },
          "note": {
            "type": "string",
            "description": "Внутренняя заметка"
          }
        },
        "required": [
          "type",
          "name"
        ]
      },
      "UpdateResourceDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "staff",
              "seat",
              "unit",
              "equipment"
            ],
            "description": "Тип ресурса"
          },
          "name": {
            "type": "string",
            "description": "Название ресурса"
          },
          "capacity": {
            "type": "number",
            "minimum": 1,
            "description": "Сколько броней ресурс держит одновременно"
          },
          "seats": {
            "type": "number",
            "nullable": true,
            "minimum": 1,
            "description": "Число мест площадки; null — снять."
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Цвет в календаре (HEX)"
          },
          "bufferMinutes": {
            "type": "number",
            "minimum": 0,
            "description": "Буфер между бронями, минут"
          },
          "minDurationMinutes": {
            "type": "number",
            "nullable": true,
            "minimum": 1,
            "description": "Минимальная длительность брони, минут; null — без ограничения"
          },
          "availability": {
            "description": "Окна доступности по дням недели",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResourceAvailabilityWindowDto"
            }
          },
          "isActive": {
            "type": "boolean",
            "description": "Ресурс активен и доступен для записи"
          },
          "housekeepingState": {
            "type": "string",
            "enum": [
              "ready",
              "dirty",
              "cleaning",
              "out_of_service"
            ],
            "description": "Состояние уборки юнита (ручная установка)."
          },
          "userId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Учётка сотрудника за ресурсом (null — отвязать)."
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренняя заметка"
          }
        }
      },
      "BookingListItemResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID брони"
          },
          "number": {
            "type": "number",
            "description": "Номер брони"
          },
          "resourceId": {
            "type": "string",
            "description": "ID ресурса"
          },
          "resourceName": {
            "type": "string",
            "description": "Название ресурса"
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "description": "Начало (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "description": "Окончание (ISO 8601)"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "completed",
              "no_show",
              "cancelled"
            ],
            "description": "Статус брони"
          },
          "source": {
            "type": "string",
            "enum": [
              "admin",
              "public_link",
              "channel"
            ],
            "description": "Откуда создана бронь"
          },
          "clientId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя клиента"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон клиента"
          },
          "dealId": {
            "type": "string",
            "nullable": true,
            "description": "ID связанной сделки"
          },
          "serviceId": {
            "type": "string",
            "nullable": true,
            "description": "ID услуги"
          },
          "serviceName": {
            "type": "string",
            "nullable": true,
            "description": "Название услуги"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID исполнителя"
          },
          "assignedToName": {
            "type": "string",
            "nullable": true,
            "description": "Имя исполнителя"
          },
          "capacity": {
            "type": "number",
            "nullable": true,
            "description": "Мест в занятии. null — обычная бронь без ростера."
          },
          "depositAmount": {
            "type": "number",
            "description": "Залог в копейках"
          },
          "depositStatus": {
            "type": "string",
            "enum": [
              "none",
              "required",
              "received",
              "returned",
              "withheld"
            ],
            "description": "Статус залога"
          }
        },
        "required": [
          "id",
          "number",
          "resourceId",
          "resourceName",
          "startAt",
          "endAt",
          "status",
          "source",
          "clientId",
          "customerName",
          "customerPhone",
          "dealId",
          "serviceId",
          "serviceName",
          "assignedToId",
          "assignedToName",
          "capacity",
          "depositAmount",
          "depositStatus"
        ]
      },
      "BookingResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID брони"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "number": {
            "type": "number",
            "description": "Номер брони (сквозной по компании)"
          },
          "resourceId": {
            "type": "string",
            "description": "ID ресурса"
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "description": "Начало (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "format": "date-time",
            "description": "Окончание (ISO 8601)"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "completed",
              "no_show",
              "cancelled"
            ],
            "description": "Статус брони"
          },
          "source": {
            "type": "string",
            "enum": [
              "admin",
              "public_link",
              "channel"
            ],
            "description": "Откуда создана бронь"
          },
          "clientId": {
            "type": "string",
            "nullable": true,
            "description": "ID клиента"
          },
          "assetId": {
            "type": "string",
            "nullable": true,
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя клиента (если без карточки)"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон клиента"
          },
          "dealId": {
            "type": "string",
            "nullable": true,
            "description": "ID связанной сделки"
          },
          "serviceId": {
            "type": "string",
            "nullable": true,
            "description": "ID услуги каталога"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "description": "ID исполнителя"
          },
          "price": {
            "type": "number",
            "description": "Цена брони в копейках (P0.4)"
          },
          "saleId": {
            "type": "string",
            "nullable": true,
            "description": "ID чека, в который конвертирована бронь"
          },
          "depositAmount": {
            "type": "number",
            "description": "Залог в копейках"
          },
          "depositStatus": {
            "type": "string",
            "enum": [
              "none",
              "required",
              "received",
              "returned",
              "withheld"
            ],
            "description": "Статус залога"
          },
          "capacity": {
            "type": "number",
            "nullable": true,
            "description": "Мест в групповом занятии; null — обычная бронь"
          },
          "isOpenClass": {
            "type": "boolean",
            "description": "Открытое занятие: показывать на публичной странице записи и в кабинете клиента."
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес проведения (выездная смена)"
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "visitNote": {
            "type": "string",
            "nullable": true,
            "description": "Заметка мастера по визиту (формула, результат работы, пожелания)"
          },
          "clientPackageId": {
            "type": "string",
            "nullable": true,
            "description": "Абонемент, с которого списан визит за эту запись"
          },
          "packageConsumedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда списан визит с абонемента (ISO 8601)"
          },
          "recurrenceId": {
            "type": "string",
            "nullable": true,
            "description": "ID серии повторяющихся броней"
          },
          "rentalState": {
            "type": "string",
            "enum": [
              "reserved",
              "issued",
              "returned"
            ],
            "nullable": true,
            "description": "Состояние проката (выдано/возвращено); null — не прокат"
          },
          "issuedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда выдано в прокат (ISO 8601)"
          },
          "returnedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда возвращено из проката (ISO 8601)"
          },
          "returnNote": {
            "type": "string",
            "nullable": true,
            "description": "Заметка при возврате из проката"
          },
          "reminderSentAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда отправлено напоминание (ISO 8601)"
          },
          "confirmedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда клиент подтвердил визит (ISO 8601)"
          },
          "createdById": {
            "type": "string",
            "nullable": true,
            "description": "ID сотрудника-автора"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "companyId",
          "number",
          "resourceId",
          "startAt",
          "endAt",
          "status",
          "source",
          "clientId",
          "assetId",
          "customerName",
          "customerPhone",
          "dealId",
          "serviceId",
          "assignedToId",
          "price",
          "saleId",
          "depositAmount",
          "depositStatus",
          "capacity",
          "isOpenClass",
          "address",
          "note",
          "visitNote",
          "clientPackageId",
          "packageConsumedAt",
          "recurrenceId",
          "rentalState",
          "issuedAt",
          "returnedAt",
          "returnNote",
          "reminderSentAt",
          "confirmedAt",
          "createdById",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateBookingDto": {
        "type": "object",
        "properties": {
          "resourceId": {
            "type": "string",
            "description": "ID ресурса"
          },
          "startAt": {
            "type": "string",
            "description": "Начало интервала (ISO 8601)"
          },
          "endAt": {
            "type": "string",
            "description": "Конец интервала (ISO 8601). Опционален при serviceId — считается из длительности услуги."
          },
          "serviceId": {
            "type": "string",
            "description": "ID услуги каталога (запись на услугу)"
          },
          "clientId": {
            "type": "string",
            "description": "ID клиента из модуля Clients"
          },
          "assetId": {
            "type": "string",
            "description": "ID объекта обслуживания (ClientAsset)"
          },
          "customerName": {
            "type": "string",
            "description": "Имя клиента (если без карточки)"
          },
          "customerPhone": {
            "type": "string",
            "description": "Телефон клиента"
          },
          "dealId": {
            "type": "string",
            "description": "ID связанной сделки"
          },
          "assignedToId": {
            "type": "string",
            "description": "ID ответственного сотрудника"
          },
          "price": {
            "type": "number",
            "description": "Цена брони в копейках; не задана — авторасчёт по тарифу"
          },
          "depositAmount": {
            "type": "number",
            "description": "Депозит в копейках",
            "default": 0
          },
          "depositStatus": {
            "type": "string",
            "enum": [
              "none",
              "required",
              "received",
              "returned",
              "withheld"
            ],
            "description": "Статус залога"
          },
          "capacity": {
            "type": "number",
            "description": "Вместимость группового занятия (число мест); опускается для обычной брони.",
            "minimum": 1
          },
          "isOpenClass": {
            "type": "boolean",
            "description": "Открытое занятие: показывать на публичной странице записи и в кабинете клиента."
          },
          "extraResourceIds": {
            "description": "Доп.ресурсы мультиресурсной брони (S8); guard по каждому.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "address": {
            "type": "string",
            "description": "Адрес проведения (выезд). Не задан при привязке к сделке — подставляется адрес сделки."
          },
          "note": {
            "type": "string",
            "description": "Внутренний комментарий"
          }
        },
        "required": [
          "resourceId",
          "startAt"
        ]
      },
      "UpdateBookingDto": {
        "type": "object",
        "properties": {
          "resourceId": {
            "type": "string",
            "format": "uuid",
            "description": "ID ресурса"
          },
          "startAt": {
            "type": "string",
            "description": "ISO 8601"
          },
          "endAt": {
            "type": "string",
            "description": "ISO 8601"
          },
          "serviceId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID услуги каталога (null — снять)"
          },
          "clientId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID клиента (null — отвязать)"
          },
          "assetId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID объекта обслуживания (null — отвязать)"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Имя клиента (если без карточки)"
          },
          "customerPhone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон клиента"
          },
          "dealId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID связанной сделки (null — отвязать)"
          },
          "assignedToId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID исполнителя (null — снять)"
          },
          "price": {
            "type": "number",
            "description": "Цена брони в копейках",
            "minimum": 0
          },
          "depositAmount": {
            "type": "number",
            "minimum": 0,
            "description": "Залог в копейках"
          },
          "depositStatus": {
            "type": "string",
            "enum": [
              "none",
              "required",
              "received",
              "returned",
              "withheld"
            ],
            "description": "Статус залога"
          },
          "capacity": {
            "type": "number",
            "nullable": true,
            "minimum": 1,
            "description": "Вместимость группового занятия (null — снять групповой режим)."
          },
          "isOpenClass": {
            "type": "boolean",
            "description": "Открытое занятие: показывать на публичной странице записи и в кабинете клиента."
          },
          "extraResourceIds": {
            "description": "Полная замена доп.ресурсов мультиресурсной брони (S8).",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "address": {
            "type": "string",
            "nullable": true,
            "description": "Адрес проведения (выезд); null — снять адрес."
          },
          "note": {
            "type": "string",
            "nullable": true,
            "description": "Внутренний комментарий"
          },
          "visitNote": {
            "type": "string",
            "nullable": true,
            "description": "Заметка мастера по визиту (формула, результат работы, пожелания). Разрешена и после завершения записи — её пишут по факту приёма."
          }
        }
      },
      "ChangeBookingStatusDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "completed",
              "no_show",
              "cancelled"
            ],
            "description": "Целевой статус брони"
          }
        },
        "required": [
          "status"
        ]
      },
      "LeadResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID лида"
          },
          "source": {
            "type": "string",
            "description": "Источник: `api`, `public_form`, `telegram`…"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Канал внутри источника (например, имя формы или бота)"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Имя контакта"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "E-mail"
          },
          "message": {
            "type": "string",
            "nullable": true,
            "description": "Текст обращения"
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "in_progress",
              "converted",
              "spam"
            ],
            "description": "Статус обработки"
          },
          "externalId": {
            "type": "string",
            "nullable": true,
            "description": "Внешний id из источника (для дедупликации)"
          },
          "raw": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Сырой payload источника (для ручного разбора)."
          },
          "clientId": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "description": "ID клиента после конвертации"
          },
          "dealId": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "description": "ID сделки после конвертации"
          },
          "assignedToId": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "description": "ID ответственного сотрудника"
          },
          "assignedToName": {
            "type": "string",
            "nullable": true,
            "description": "Имя ответственного сотрудника"
          },
          "utm": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "string"
            },
            "description": "UTM-метки перехода."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Создан (ISO 8601)"
          }
        },
        "required": [
          "id",
          "source",
          "channel",
          "name",
          "phone",
          "email",
          "message",
          "status",
          "externalId",
          "raw",
          "clientId",
          "dealId",
          "assignedToId",
          "assignedToName",
          "utm",
          "createdAt"
        ]
      },
      "IntakeLeadDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Имя контакта"
          },
          "phone": {
            "type": "string",
            "description": "Телефон"
          },
          "email": {
            "type": "string",
            "description": "E-mail"
          },
          "message": {
            "type": "string",
            "description": "Текст обращения"
          },
          "source": {
            "type": "string",
            "description": "Источник (по умолчанию webhook)."
          },
          "externalId": {
            "type": "string",
            "description": "Внешний id для дедупа."
          },
          "utm": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "UTM-метки перехода: плоская карта строка → строка."
          }
        }
      },
      "UpdateLeadDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "new",
              "in_progress",
              "converted",
              "spam"
            ],
            "description": "Новый статус лида"
          }
        },
        "required": [
          "status"
        ]
      },
      "AssignLeadDto": {
        "type": "object",
        "properties": {
          "assigneeId": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "ID сотрудника или null для снятия ответственного."
          }
        },
        "required": [
          "assigneeId"
        ]
      },
      "ConvertLeadToDealDto": {
        "type": "object",
        "properties": {
          "typeId": {
            "type": "string",
            "description": "ID типа сделки; по умолчанию — тип-«лид»."
          }
        }
      },
      "AuditActorResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID сотрудника"
          },
          "firstName": {
            "type": "string",
            "description": "Имя"
          },
          "lastName": {
            "type": "string",
            "description": "Фамилия"
          },
          "email": {
            "type": "string",
            "description": "E-mail"
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName",
          "email"
        ]
      },
      "AuditLogResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID записи"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "actorId": {
            "type": "string",
            "nullable": true,
            "format": "uuid",
            "description": "ID сотрудника-инициатора; null — системное действие"
          },
          "actor": {
            "nullable": true,
            "description": "Сотрудник-инициатор; null — системное действие или сотрудник удалён",
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditActorResponse"
              }
            ]
          },
          "action": {
            "type": "string",
            "enum": [
              "create",
              "update",
              "delete",
              "login",
              "logout",
              "shift_open",
              "shift_close",
              "cash_movement_create",
              "sale",
              "refund_issue",
              "invitation_send",
              "order_create",
              "order_update",
              "order_status_change",
              "order_cancel",
              "order_payment",
              "order_payment_delete",
              "order_checkout",
              "order_line_fulfill",
              "order_template_create",
              "order_template_update",
              "order_template_delete",
              "deal_create",
              "deal_update",
              "deal_stage_change",
              "deal_checkout",
              "deal_share_enable",
              "deal_share_revoke",
              "deal_share_files",
              "deal_file_approval_request",
              "deal_file_approve",
              "deal_file_reject",
              "deal_type_create",
              "deal_type_update",
              "deal_type_delete",
              "expense_create",
              "expense_update",
              "expense_delete",
              "other_income_create",
              "other_income_update",
              "other_income_delete",
              "cash_account_create",
              "cash_account_update",
              "cash_account_delete",
              "cash_transaction_create",
              "cash_transaction_delete",
              "recurring_expense_create",
              "recurring_expense_update",
              "recurring_expense_delete",
              "budget_create",
              "budget_update",
              "budget_delete",
              "resource_create",
              "resource_update",
              "resource_delete",
              "booking_create",
              "booking_update",
              "booking_status_change",
              "booking_attendee_enroll",
              "booking_attendee_update",
              "booking_attendee_remove",
              "housekeeping_task_create",
              "housekeeping_task_update",
              "housekeeping_task_generate",
              "warehouse_create",
              "warehouse_update",
              "warehouse_delete",
              "warehouse_set_default",
              "branch_create",
              "branch_update",
              "branch_delete",
              "branch_set_default",
              "supplier_create",
              "supplier_update",
              "supplier_delete",
              "receipt_create",
              "receipt_cancel",
              "stock_adjustment",
              "product_bom_set",
              "production_run_create",
              "production_run_cancel",
              "product_variant_create",
              "product_variant_update",
              "product_variant_delete",
              "automation_rule_create",
              "automation_rule_update",
              "automation_rule_delete",
              "stock_write_off",
              "stock_reorder_set",
              "stocktake_create",
              "stocktake_apply",
              "stocktake_cancel",
              "purchase_order_create",
              "purchase_order_send",
              "purchase_order_cancel",
              "purchase_order_receive",
              "stock_bulk_reorder_set",
              "stock_bulk_adjust",
              "stock_transfer_ship",
              "stock_transfer_receive",
              "stock_transfer_cancel",
              "client_create",
              "client_update",
              "client_archive",
              "client_restore",
              "client_asset_create",
              "client_asset_update",
              "client_asset_delete",
              "client_address_create",
              "client_address_update",
              "client_address_delete",
              "client_balance_topup",
              "client_balance_charge",
              "client_package_create",
              "client_package_update",
              "client_package_delete",
              "client_package_use",
              "client_package_refund",
              "package_template_create",
              "package_template_update",
              "package_template_delete",
              "client_relation_create",
              "client_relation_delete",
              "student_group_create",
              "student_group_update",
              "student_group_delete",
              "student_group_schedule",
              "student_group_member_add",
              "student_group_member_update",
              "student_group_member_remove",
              "service_contract_create",
              "service_contract_update",
              "service_contract_delete",
              "service_contract_generate",
              "client_price_set",
              "client_price_delete",
              "price_list_create",
              "price_list_update",
              "price_list_delete",
              "price_list_fill",
              "client_group_create",
              "client_group_update",
              "client_group_delete",
              "shipment_create",
              "shipment_ship",
              "shipment_cancel",
              "client_portal_enable",
              "client_portal_disable",
              "b2b_portal_order_create",
              "interaction_create",
              "interaction_update",
              "interaction_delete",
              "calendar_event_create",
              "calendar_event_update",
              "calendar_event_delete",
              "product_bulk_reprice",
              "product_bulk_set_category",
              "product_bulk_set_brand",
              "product_bulk_hide",
              "product_bulk_restore",
              "product_duplicate",
              "client_merge",
              "client_import",
              "client_bulk_assign",
              "client_bulk_tag",
              "client_bulk_archive",
              "client_bulk_restore",
              "client_asset_service_done",
              "client_segment_create",
              "client_segment_update",
              "client_segment_delete",
              "client_segment_broadcast",
              "client_marketing_consent",
              "message_template_create",
              "message_template_update",
              "message_template_delete",
              "client_anonymize",
              "client_tag_set",
              "client_tag_delete",
              "loyalty_tier_set",
              "loyalty_tier_delete",
              "promo_code_create",
              "promo_code_update",
              "promo_code_delete",
              "promo_code_redeem",
              "deal_comment_create",
              "deal_comment_delete",
              "deal_task_create",
              "deal_task_update",
              "deal_task_delete",
              "deal_template_create",
              "deal_template_delete",
              "lead_source_create",
              "lead_source_update",
              "lead_source_delete",
              "deal_lost_reason_create",
              "deal_lost_reason_update",
              "deal_lost_reason_delete",
              "booking_issue",
              "booking_return",
              "waitlist_create",
              "waitlist_notify",
              "storefront_settings_update",
              "storefront_product_publish",
              "delivery_zone_create",
              "delivery_zone_update",
              "delivery_zone_delete",
              "storefront_payment_paid",
              "order_delivery_status_change",
              "restaurant_settings_update",
              "restaurant_menu_visibility",
              "restaurant_table_create",
              "restaurant_table_update",
              "restaurant_table_delete",
              "restaurant_session_close",
              "restaurant_session_cancel",
              "kds_ticket_status_change",
              "restaurant_payment_paid",
              "hardware_enrollment_issue",
              "hardware_agent_enroll",
              "hardware_agent_update",
              "hardware_agent_revoke",
              "hardware_command_dispatch",
              "crew_create",
              "crew_update",
              "crew_delete",
              "work_order_create",
              "work_order_update",
              "work_order_complete",
              "work_order_cancel",
              "deal_material_issue",
              "deal_material_return",
              "estimate_version_create",
              "estimate_version_approve",
              "user_ip_restriction_disable",
              "company_deletion_request",
              "company_deletion_cancel",
              "company_deletion_confirm",
              "company_restore",
              "data_export",
              "password_change",
              "two_factor_enable",
              "two_factor_disable",
              "ip_restriction_update",
              "user_create",
              "user_update",
              "user_role_change",
              "user_status_change",
              "user_password_reset",
              "user_delete",
              "sa_company_update",
              "sa_billing_update",
              "sa_user_update",
              "sa_session_revoke",
              "access_denied",
              "file_download",
              "file_delete"
            ],
            "description": "Действие"
          },
          "entity": {
            "type": "string",
            "description": "Имя сущности, к которой относится действие"
          },
          "entityId": {
            "type": "string",
            "nullable": true,
            "description": "ID затронутой сущности"
          },
          "payload": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Детали действия — произвольный JSON, состав зависит от действия"
          },
          "ip": {
            "type": "string",
            "nullable": true,
            "description": "IP-адрес инициатора"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Момент действия (ISO 8601)"
          }
        },
        "required": [
          "id",
          "companyId",
          "actorId",
          "actor",
          "action",
          "entity",
          "entityId",
          "payload",
          "ip",
          "createdAt"
        ]
      },
      "UserResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID сотрудника"
          },
          "firstName": {
            "type": "string",
            "description": "Имя"
          },
          "lastName": {
            "type": "string",
            "description": "Фамилия"
          },
          "email": {
            "type": "string",
            "description": "E-mail (логин)"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "manager",
              "employee",
              "director"
            ],
            "description": "Роль-персона (admin, manager, employee…)"
          },
          "roleId": {
            "type": "string",
            "nullable": true,
            "description": "Роль компании"
          },
          "roleName": {
            "type": "string",
            "nullable": true,
            "description": "Название роли"
          },
          "companyId": {
            "type": "string",
            "description": "ID компании"
          },
          "status": {
            "type": "number",
            "description": "Статус: 0=Registered, 1=Active, 2=Blocked, 3=Deleted"
          },
          "about": {
            "type": "string",
            "nullable": true,
            "description": "О себе"
          },
          "phone": {
            "type": "string",
            "nullable": true,
            "description": "Телефон"
          },
          "timezone": {
            "type": "string",
            "nullable": true,
            "description": "Часовой пояс (IANA, например Europe/Moscow)"
          },
          "avatarFileId": {
            "type": "string",
            "nullable": true,
            "description": "ID файла аватара"
          },
          "avatarUrl": {
            "type": "string",
            "nullable": true,
            "description": "URL аватара"
          },
          "twoFactorEnabled": {
            "type": "boolean",
            "description": "Включена двухфакторная аутентификация"
          },
          "ipRestrictionEnabled": {
            "type": "boolean",
            "description": "Сотрудник ограничил себе вход списком IP-адресов."
          },
          "emailVerifiedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Когда подтверждён e-mail (ISO 8601)"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "firstName",
          "lastName",
          "email",
          "role",
          "roleId",
          "roleName",
          "companyId",
          "status",
          "about",
          "phone",
          "timezone",
          "avatarFileId",
          "avatarUrl",
          "twoFactorEnabled",
          "ipRestrictionEnabled",
          "emailVerifiedAt",
          "createdAt",
          "updatedAt"
        ]
      }
    }
  },
  "security": [
    {
      "api-token": []
    }
  ]
}
