{
  "openapi": "3.0.0",
  "paths": {
    "/items": {
      "get": {
        "operationId": "listItems",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by item name, barcode or item code",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "groupId",
            "required": false,
            "in": "query",
            "description": "Filter by group/category id(s) — array or CSV",
            "schema": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          },
          {
            "name": "brandId",
            "required": false,
            "in": "query",
            "description": "Filter by brand ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "taxId",
            "required": false,
            "in": "query",
            "description": "Filter by tax ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "stockStatus",
            "required": false,
            "in": "query",
            "description": "Filter by stock status: inStock, low, out",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "weighingScale",
            "required": false,
            "in": "query",
            "description": "Filter items flagged for weighing scale (1 = yes, 0 = no)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by item type (0 = standard, 1 = variant, 2 = combo)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List items",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "operationId": "createItem",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateProductDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an item",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/items/{id}": {
      "get": {
        "operationId": "getItem",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "storeId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an item",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "patch": {
        "operationId": "updateItem",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateProductDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update an item",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/categories": {
      "get": {
        "operationId": "listCategories",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by group name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List categories",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "operationId": "createCategory",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateCategoryDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a category",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/categories/{id}": {
      "get": {
        "operationId": "getCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a category",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "patch": {
        "operationId": "updateCategory",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateCategoryDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a category",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/brands": {
      "get": {
        "operationId": "listBrands",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by brand name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List brands",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createBrand",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateBrandDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a brand",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/brands/{id}": {
      "get": {
        "operationId": "getBrand",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a brand",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updateBrand",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateBrandDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a brand",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/menus": {
      "get": {
        "operationId": "listMenus",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by menu name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "delivery",
            "required": false,
            "in": "query",
            "description": "Delivery filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "takeaway",
            "required": false,
            "in": "query",
            "description": "Takeaway filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "online",
            "required": false,
            "in": "query",
            "description": "Online filter (1 = yes, 0 = no, 2/undefined = any)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List menus",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/menus/{id}/full": {
      "get": {
        "operationId": "getMenuFull",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a menu with its items and store assignments",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/menus/create-with-items": {
      "post": {
        "operationId": "createMenuWithItems",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMenuWithItemsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a menu together with its items and stores",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/menus/{id}/update-with-items": {
      "patch": {
        "operationId": "updateMenuWithItems",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMenuWithItemsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace a menu together with its items and stores",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/modifiers": {
      "get": {
        "operationId": "listModifiers",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by modifier name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "itemSearch",
            "required": false,
            "in": "query",
            "description": "Filter to modifiers applied to an item whose name matches (searches ItemSelectedModifier, Item.modifierId and the Item.Modifiers JSON column)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List modifier groups",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "operationId": "createModifier",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateModifierWithOptionsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a modifier group with its options",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/modifiers/{id}/full": {
      "get": {
        "operationId": "getModifierFull",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a modifier group with its options",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/modifiers/{id}": {
      "patch": {
        "operationId": "updateModifier",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateModifierWithOptionsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a modifier group with its options",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/purchase-orders": {
      "get": {
        "operationId": "listPurchaseOrders",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by order number, invoice, supplier, or narration",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Order-date lower bound (ISO date, inclusive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "Order-date upper bound (ISO date, inclusive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "supplierId",
            "required": false,
            "in": "query",
            "description": "Supplier ID filter (CSV allowed)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store ID filter (CSV allowed)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "purchStatus",
            "required": false,
            "in": "query",
            "description": "Purchase status (0 = draft, 1 = partial, 2 = received)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Row status (1 = active, 0 = voided)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "orderNos",
            "required": false,
            "in": "query",
            "description": "Specific order numbers to include (CSV)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "required": false,
            "in": "query",
            "description": "Provider filter (integration source)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeVoided",
            "required": false,
            "in": "query",
            "description": "Include voided rows in results (default = false)",
            "schema": {
              "$ref": "#/components/schemas/Object"
            }
          },
          {
            "name": "transactions",
            "required": false,
            "in": "query",
            "description": "When true, return the supplier TRANSACTIONS view (purchases + purchase returns unioned into one chronological list, each row stamped Type 0=purchase, 1=purchase return) instead of the plain PO list. Scoped by supplierId/storeId/date. Mirrors v1 supplier/transactions/:supplierId.",
            "schema": {
              "$ref": "#/components/schemas/Object"
            }
          },
          {
            "name": "storeIds",
            "required": false,
            "in": "query",
            "description": "Store IDs (array form)",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List purchase orders",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "description": "Pass `receive=true` to create and receive the order in a single call.",
        "operationId": "createPurchaseOrder",
        "parameters": [
          {
            "name": "receive",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePurchaseOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a purchase order",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/purchase-orders/{id}": {
      "get": {
        "operationId": "getPurchaseOrder",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a purchase order",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updatePurchaseOrder",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePurchaseOrderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a purchase order",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/purchase-orders/{id}/receive": {
      "patch": {
        "operationId": "receivePurchaseOrder",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceivePurchaseOrderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Receive stock against a purchase order",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stock-transfers": {
      "get": {
        "operationId": "listStockTransfers",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by transfer number, narration or store name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Date lower bound (ISO date, inclusive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "Date upper bound (ISO date, inclusive)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromStoreId",
            "required": false,
            "in": "query",
            "description": "From-store filter (CSV or single)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toStoreId",
            "required": false,
            "in": "query",
            "description": "To-store filter (CSV or single)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "transferStatus",
            "required": false,
            "in": "query",
            "description": "TransferStatus filter (0 draft, 1 partial, 2 done)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Row status (1 active, 0 voided). Void rows are hidden by default.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "includeVoided",
            "required": false,
            "in": "query",
            "description": "Include voided rows (default = false)",
            "schema": {
              "$ref": "#/components/schemas/Object"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List stock transfers",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "description": "Pass `receive=true` to create and receive the transfer in a single call.",
        "operationId": "createStockTransfer",
        "parameters": [
          {
            "name": "receive",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStockTransferDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a stock transfer",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stock-transfers/{id}": {
      "get": {
        "operationId": "getStockTransfer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a stock transfer",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updateStockTransfer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStockTransferDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a stock transfer",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stock-transfers/{id}/receive": {
      "patch": {
        "operationId": "receiveStockTransfer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiveStockTransferDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Receive stock against a stock transfer",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stock-adjustments": {
      "get": {
        "operationId": "listStockAdjustments",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Values above 100 are clamped to 100.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Free-text search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Start of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "End of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Comma-separated store ids, e.g. \"1,3\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Adjustment type",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Record status",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List stock adjustments",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "description": "Pass `post=false` to save the adjustment without posting it to stock.",
        "operationId": "createStockAdjustment",
        "parameters": [
          {
            "name": "post",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStockAdjustmentDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a stock adjustment",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stock-adjustments/{id}": {
      "get": {
        "operationId": "getStockAdjustment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a stock adjustment",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updateStockAdjustment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStockAdjustmentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a stock adjustment",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/productions": {
      "get": {
        "operationId": "listProductions",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Values above 100 are clamped to 100.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Free-text search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Start of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "End of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Comma-separated store ids, e.g. \"1,3\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Adjustment type",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Record status",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List production runs",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createProduction",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProductionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a production run",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/productions/{id}": {
      "get": {
        "operationId": "getProduction",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a production run",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/recipes": {
      "get": {
        "operationId": "listRecipes",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by recipe name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1=active, 0=inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "itemId",
            "required": false,
            "in": "query",
            "description": "Filter by item ID",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List recipes",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createRecipe",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRecipeWithIngredientsDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a recipe with its ingredients",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/recipes/{id}/full": {
      "get": {
        "operationId": "getRecipe",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a recipe with its ingredients",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/recipes/{id}": {
      "patch": {
        "operationId": "updateRecipe",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRecipeWithIngredientsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a recipe with its ingredients",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/combo-slots": {
      "get": {
        "operationId": "listComboSlots",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Values above 100 are clamped to 100.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Free-text search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Start of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "End of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Comma-separated store ids, e.g. \"1,3\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Adjustment type",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Record status",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List combo (meal) slots",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createComboSlot",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveComboSlotDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a combo (meal) slot",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/combo-slots/{id}": {
      "get": {
        "operationId": "getComboSlot",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a combo (meal) slot",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/items/{id}/meal": {
      "get": {
        "operationId": "getItemMeal",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the meal configuration of an item",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "put": {
        "operationId": "saveItemMeal",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveMealDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Replace the meal configuration of an item",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/customers": {
      "get": {
        "operationId": "listCustomers",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by name, email, mobile, or loyalty number",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "email",
            "required": false,
            "in": "query",
            "description": "Filter by email",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "mobile",
            "required": false,
            "in": "query",
            "description": "Filter by mobile",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List customers",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "operationId": "createCustomer",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/customers/{id}": {
      "get": {
        "operationId": "getCustomer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "patch": {
        "operationId": "updateCustomer",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateCustomerDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a customer",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/reservations": {
      "get": {
        "operationId": "listReservations",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Rows per page. Values above 100 are clamped to 100.",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Free-text search",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "Start of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "End of the date window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Reservation lifecycle status",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "confirmed",
                "seated",
                "completed",
                "cancelled"
              ]
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "description": "Filter by customer id",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Filter by store id",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List reservations",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createReservation",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReservationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a reservation",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/reservations/{id}": {
      "get": {
        "operationId": "getReservation",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a reservation",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updateReservation",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateReservationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a reservation",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/taxes": {
      "get": {
        "operationId": "listTaxes",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by tax name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (1 = active, 0 = inactive)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "department",
            "required": false,
            "in": "query",
            "description": "Filter by department",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List taxes",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "post": {
        "operationId": "createTax",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerCreateTaxDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a tax",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/taxes/{id}": {
      "get": {
        "operationId": "getTax",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get a tax",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      },
      "patch": {
        "operationId": "updateTax",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerUpdateTaxDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Update a tax",
        "tags": [
          "Partner",
          "Partner:FULL"
        ]
      }
    },
    "/stores": {
      "get": {
        "operationId": "listStores",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by name, code, or email",
            "schema": {
              "example": "Main Store",
              "type": "string"
            }
          },
          {
            "name": "isActive",
            "required": false,
            "in": "query",
            "description": "Filter by active status",
            "schema": {
              "example": true,
              "type": "boolean"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "1 = active only, 0 = inactive only",
            "schema": {
              "example": 1,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "description": "Restrict to archived (true) or non-archived (false) stores",
            "schema": {
              "example": false,
              "type": "boolean"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "0 = stores only, 1 = warehouses only; omit for both",
            "schema": {
              "example": 0,
              "type": "number",
              "enum": [
                0,
                1
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List stores",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER",
          "Partner:ADSR"
        ]
      }
    },
    "/online-orders": {
      "get": {
        "operationId": "listOrders",
        "parameters": [
          {
            "name": "order",
            "required": false,
            "in": "query",
            "description": "Sort order (asc or desc)",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "description": "Field to sort by",
            "schema": {
              "example": "entryDate",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (1-based)",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Number of items per page",
            "schema": {
              "minimum": 1,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "description": "Search by order number, customer name, mobile, or channel order ID",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store IDs. Pass 0 (or omit) for all. Supports repeated query keys (`storeId=1&storeId=2`) or a comma-joined string (`storeId=1,2`).",
            "schema": {
              "type": "array",
              "items": {
                "type": "number"
              }
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by order type (0=Standard, 1=DineIn, 2=Delivery, 3=Takeaway, 4=Provider)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (0=Failed, 1=Active, 2=Done, 3=Cancelled)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "customerId",
            "required": false,
            "in": "query",
            "description": "Filter by customer ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "fromDate",
            "required": false,
            "in": "query",
            "description": "From date (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "toDate",
            "required": false,
            "in": "query",
            "description": "To date (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List online orders",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      },
      "post": {
        "description": "Creates the order and notifies the store in realtime, exactly as the backoffice new-order screen does.",
        "operationId": "createOrder",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOnlineOrderDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/online-orders/{id}": {
      "get": {
        "operationId": "getOrder",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/online-orders/{id}/status": {
      "get": {
        "description": "Status values: `new`, `preparing`, `ready`, `completed`, `cancelled` — the same buckets the backoffice order counters use.",
        "operationId": "getOrderStatus",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get the current status of an online order",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ONLINE_ORDER"
        ]
      }
    },
    "/reports/business-summary": {
      "get": {
        "operationId": "businessSummaryReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Business summary report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/items": {
      "get": {
        "operationId": "itemsReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales by item report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/pay-types": {
      "get": {
        "operationId": "payTypesReport",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales by payment type report",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/sales": {
      "get": {
        "operationId": "salesList",
        "parameters": [
          {
            "name": "from",
            "required": false,
            "in": "query",
            "description": "Start of the reporting window (YYYY-MM-DD)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": false,
            "in": "query",
            "description": "End of the reporting window (YYYY-MM-DD), inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sales list",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    },
    "/reports/daily-sales": {
      "get": {
        "description": "One canonical row per calendar day. Field semantics (ported from the V1 ADSR summary):\n- `grossSales` — taxable + voucher + taxes + cess + rounding + KFC + charges + tips + item charges + all discounts (the pre-discount bill value).\n- `discountAmount` — the gross-to-net delta: bill and item discounts plus the rounding adjustment.\n- `refundAmount` — value refunded through sales returns, on the same net basis.\n- `taxAmount` — sale tax (tax1 + tax2 + cess + KFC + item-charge tax) net of tax refunded on returns.\n- `netSales` — `grossSales - discountAmount - refundAmount`, exactly.\n- `transactionCount` — sale invoices for the day; returns are counted in `refundAmount`, not here.\nVoided sales (`Avoid = 1`) are excluded. Maximum window: 31 days.",
        "operationId": "dailySales",
        "parameters": [
          {
            "name": "from",
            "required": true,
            "in": "query",
            "description": "First day of the feed window (YYYY-MM-DD)",
            "schema": {
              "example": "2026-07-01",
              "type": "string"
            }
          },
          {
            "name": "to",
            "required": true,
            "in": "query",
            "description": "Last day of the feed window (YYYY-MM-DD), inclusive. Maximum span: 31 days.",
            "schema": {
              "example": "2026-07-31",
              "type": "string"
            }
          },
          {
            "name": "storeId",
            "required": false,
            "in": "query",
            "description": "Store id, or a comma-separated list. Omit for every store the app may read.",
            "schema": {
              "example": "1,3",
              "type": "string"
            }
          },
          {
            "name": "hourly",
            "required": false,
            "in": "query",
            "description": "Include 24 hourly buckets per day.",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          },
          "401": {
            "description": "Missing, malformed or expired app token"
          },
          "403": {
            "description": "Token lacks the required scope (partner.scope_denied), is used against the wrong environment (partner.env_mismatch), or comes from a non-allowlisted IP (partner.ip_denied)"
          },
          "429": {
            "description": "Per-app rate limit exceeded (partner.rate_limited)"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "ADSR daily sales feed",
        "tags": [
          "Partner",
          "Partner:FULL",
          "Partner:ADSR"
        ]
      }
    }
  },
  "info": {
    "title": "LithosPOS FULL API",
    "description": "Complete LithosPOS partner surface: catalogue, inventory, purchasing, customers, reservations, taxes, online orders and reporting.\n\nAuthenticate with an app access token from `POST /api/v2/developer/token` (OAuth2 client credentials). Call every path below against `https://api-v2.lithospos.com/v1` — one gateway host for both sandbox and production, with the token itself selecting the environment and the merchant. The `api_base_url` in the token response is authoritative: prefer it over this document if the two differ.",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [
    {
      "url": "https://api-v2.lithospos.com/v1",
      "description": "Global API gateway — same host for sandbox and production; the token response api_base_url is authoritative"
    }
  ],
  "components": {
    "securitySchemes": {
      "appToken": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "PartnerCreateProductDto": {
        "type": "object",
        "properties": {
          "item": {
            "type": "string",
            "description": "Product/item name",
            "maxLength": 100
          },
          "groupId": {
            "type": "number",
            "description": "Group/category ID"
          },
          "uomId": {
            "type": "number",
            "description": "Unit of measure ID"
          },
          "brandId": {
            "type": "number",
            "description": "Brand ID"
          },
          "taxId": {
            "type": "number",
            "description": "Tax ID"
          },
          "item1": {
            "type": "string",
            "description": "Alternate item name",
            "maxLength": 100
          },
          "mrp": {
            "type": "number",
            "description": "Maximum retail price (Decimal 15,8)"
          },
          "rate": {
            "type": "number",
            "description": "Selling rate (Decimal 15,8)"
          },
          "PurchTaxId": {
            "type": "number",
            "description": "Purchase tax ID"
          },
          "cessId": {
            "type": "number",
            "description": "Cess ID"
          },
          "PurchCessId": {
            "type": "number",
            "description": "Purchase cess ID"
          },
          "Tax4Id": {
            "type": "number",
            "description": "Tax 4 ID (regional/special tax slot)"
          },
          "PurchTax4Id": {
            "type": "number",
            "description": "Purchase tax 4 ID"
          },
          "hsn": {
            "type": "string",
            "description": "HSN code",
            "maxLength": 35
          },
          "serialNo": {
            "type": "number",
            "description": "Serial number"
          },
          "stockable": {
            "type": "number",
            "description": "Stockable flag"
          },
          "eachItem": {
            "type": "boolean",
            "description": "Each item flag"
          },
          "favourite": {
            "type": "number",
            "description": "Favourite flag"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "type": {
            "type": "boolean",
            "description": "Item type flag"
          },
          "barcode": {
            "type": "string",
            "description": "Barcode"
          },
          "hasBatch": {
            "type": "number",
            "description": "Has batch flag"
          },
          "kitchenId": {
            "type": "number",
            "description": "Kitchen ID"
          },
          "weighingScale": {
            "type": "number",
            "description": "Weighing scale flag"
          },
          "canSale": {
            "type": "number",
            "description": "Can sale flag"
          },
          "modifierId": {
            "type": "number",
            "description": "Modifier ID"
          },
          "imageId": {
            "type": "string",
            "description": "Image ID"
          },
          "CanOnlineSale": {
            "type": "number",
            "description": "Can online sale flag"
          },
          "ExpiryTrack": {
            "type": "number",
            "description": "Expiry track flag"
          },
          "Modifiers": {
            "type": "string",
            "description": "Modifiers (text)"
          },
          "IsVeg": {
            "type": "boolean",
            "description": "Is vegetarian"
          },
          "IsService": {
            "type": "boolean",
            "description": "Is service item"
          },
          "IsEBT": {
            "type": "number",
            "description": "EBT eligible flag"
          },
          "Description": {
            "type": "string",
            "description": "Product description (long text)"
          },
          "Images": {
            "type": "string",
            "description": "Images"
          },
          "HealthyInfo": {
            "type": "string",
            "description": "Healthy info (long text)"
          },
          "ItemCode": {
            "type": "string",
            "description": "Item code"
          },
          "IsAlcahol": {
            "type": "boolean",
            "description": "Is alcohol"
          }
        },
        "required": [
          "item",
          "groupId",
          "uomId",
          "brandId",
          "taxId"
        ]
      },
      "PartnerUpdateProductDto": {
        "type": "object",
        "properties": {
          "item": {
            "type": "string",
            "description": "Product/item name",
            "maxLength": 100
          },
          "groupId": {
            "type": "number",
            "description": "Group/category ID"
          },
          "uomId": {
            "type": "number",
            "description": "Unit of measure ID"
          },
          "brandId": {
            "type": "number",
            "description": "Brand ID"
          },
          "taxId": {
            "type": "number",
            "description": "Tax ID"
          },
          "item1": {
            "type": "string",
            "description": "Alternate item name",
            "maxLength": 100
          },
          "mrp": {
            "type": "number",
            "description": "Maximum retail price (Decimal 15,8)"
          },
          "rate": {
            "type": "number",
            "description": "Selling rate (Decimal 15,8)"
          },
          "PurchTaxId": {
            "type": "number",
            "description": "Purchase tax ID"
          },
          "cessId": {
            "type": "number",
            "description": "Cess ID"
          },
          "PurchCessId": {
            "type": "number",
            "description": "Purchase cess ID"
          },
          "Tax4Id": {
            "type": "number",
            "description": "Tax 4 ID (regional/special tax slot)"
          },
          "PurchTax4Id": {
            "type": "number",
            "description": "Purchase tax 4 ID"
          },
          "hsn": {
            "type": "string",
            "description": "HSN code",
            "maxLength": 35
          },
          "serialNo": {
            "type": "number",
            "description": "Serial number"
          },
          "stockable": {
            "type": "number",
            "description": "Stockable flag"
          },
          "eachItem": {
            "type": "boolean",
            "description": "Each item flag"
          },
          "favourite": {
            "type": "number",
            "description": "Favourite flag"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "type": {
            "type": "boolean",
            "description": "Item type flag"
          },
          "barcode": {
            "type": "string",
            "description": "Barcode"
          },
          "hasBatch": {
            "type": "number",
            "description": "Has batch flag"
          },
          "kitchenId": {
            "type": "number",
            "description": "Kitchen ID"
          },
          "weighingScale": {
            "type": "number",
            "description": "Weighing scale flag"
          },
          "canSale": {
            "type": "number",
            "description": "Can sale flag"
          },
          "modifierId": {
            "type": "number",
            "description": "Modifier ID"
          },
          "imageId": {
            "type": "string",
            "description": "Image ID"
          },
          "CanOnlineSale": {
            "type": "number",
            "description": "Can online sale flag"
          },
          "ExpiryTrack": {
            "type": "number",
            "description": "Expiry track flag"
          },
          "Modifiers": {
            "type": "string",
            "description": "Modifiers (text)"
          },
          "IsVeg": {
            "type": "boolean",
            "description": "Is vegetarian"
          },
          "IsService": {
            "type": "boolean",
            "description": "Is service item"
          },
          "IsEBT": {
            "type": "number",
            "description": "EBT eligible flag"
          },
          "Description": {
            "type": "string",
            "description": "Product description (long text)"
          },
          "Images": {
            "type": "string",
            "description": "Images"
          },
          "HealthyInfo": {
            "type": "string",
            "description": "Healthy info (long text)"
          },
          "ItemCode": {
            "type": "string",
            "description": "Item code"
          },
          "IsAlcahol": {
            "type": "boolean",
            "description": "Is alcohol"
          }
        }
      },
      "PartnerCreateCategoryDto": {
        "type": "object",
        "properties": {
          "groupName": {
            "type": "string",
            "description": "Category/group name",
            "maxLength": 50
          },
          "priority": {
            "type": "number",
            "description": "Display priority",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "kitchenId": {
            "type": "number",
            "description": "Kitchen ID",
            "default": 0
          },
          "imageId": {
            "type": "string",
            "description": "Image ID",
            "maxLength": 45
          },
          "favourite": {
            "type": "number",
            "description": "Favourite flag",
            "default": 0
          },
          "IsEBT": {
            "type": "number",
            "description": "EBT eligible flag",
            "default": 0
          }
        },
        "required": [
          "groupName"
        ]
      },
      "PartnerUpdateCategoryDto": {
        "type": "object",
        "properties": {
          "groupName": {
            "type": "string",
            "description": "Category/group name",
            "maxLength": 50
          },
          "priority": {
            "type": "number",
            "description": "Display priority",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "kitchenId": {
            "type": "number",
            "description": "Kitchen ID",
            "default": 0
          },
          "imageId": {
            "type": "string",
            "description": "Image ID",
            "maxLength": 45
          },
          "favourite": {
            "type": "number",
            "description": "Favourite flag",
            "default": 0
          },
          "IsEBT": {
            "type": "number",
            "description": "EBT eligible flag",
            "default": 0
          }
        }
      },
      "PartnerCreateBrandDto": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "description": "Brand name",
            "maxLength": 50
          },
          "priority": {
            "type": "number",
            "description": "Display priority",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          }
        },
        "required": [
          "brand"
        ]
      },
      "PartnerUpdateBrandDto": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "description": "Brand name",
            "maxLength": 50
          },
          "priority": {
            "type": "number",
            "description": "Display priority",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          }
        }
      },
      "MenuItemSelection": {
        "type": "object",
        "properties": {
          "itemId": {
            "type": "number"
          },
          "variantId": {
            "type": "number"
          }
        },
        "required": [
          "itemId",
          "variantId"
        ]
      },
      "CreateMenuWithItemsDto": {
        "type": "object",
        "properties": {
          "Menu": {
            "type": "string",
            "description": "Menu name",
            "maxLength": 45
          },
          "Description": {
            "type": "string"
          },
          "Status": {
            "type": "boolean",
            "default": true
          },
          "Delivery": {
            "type": "boolean",
            "default": false
          },
          "Takeaway": {
            "type": "boolean",
            "default": false
          },
          "Online": {
            "type": "boolean",
            "default": false
          },
          "Timings": {
            "description": "Timings array",
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "StoreIds": {
            "description": "Store IDs — all stores if empty",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "Items": {
            "description": "Items to add to menu",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MenuItemSelection"
            }
          }
        },
        "required": [
          "Menu",
          "Description"
        ]
      },
      "MenuCategoryOrderEntry": {
        "type": "object",
        "properties": {}
      },
      "UpdateMenuWithItemsDto": {
        "type": "object",
        "properties": {
          "Menu": {
            "type": "string",
            "maxLength": 45
          },
          "Description": {
            "type": "string"
          },
          "Status": {
            "type": "boolean"
          },
          "Delivery": {
            "type": "boolean"
          },
          "Takeaway": {
            "type": "boolean"
          },
          "Online": {
            "type": "boolean"
          },
          "Timings": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "StoreIds": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "Items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MenuItemSelection"
            }
          },
          "CategoryOrder": {
            "description": "Menu-specific category display order",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MenuCategoryOrderEntry"
            }
          }
        }
      },
      "ModifierOptionDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Option row id (for updates)"
          },
          "item": {
            "type": "string",
            "description": "Option name (label)"
          },
          "cost": {
            "type": "number",
            "description": "Cost"
          },
          "rate": {
            "type": "number",
            "description": "Rate (price delta)"
          },
          "Rate1": {
            "type": "number",
            "description": "Takeaway price"
          },
          "Rate2": {
            "type": "number",
            "description": "Delivery price"
          },
          "PreDefault": {
            "type": "boolean",
            "description": "Is default option"
          },
          "ItemId": {
            "type": "number",
            "description": "Linked inventory item id"
          },
          "VariantId": {
            "type": "number",
            "description": "Linked variant id"
          },
          "Max": {
            "type": "number",
            "description": "Per-option max quantity"
          },
          "Qty": {
            "type": "number",
            "description": "Optional quantity default"
          },
          "ImageId": {
            "type": "string",
            "description": "Option image id"
          }
        },
        "required": [
          "item"
        ]
      },
      "CreateModifierWithOptionsDto": {
        "type": "object",
        "properties": {
          "modifier": {
            "type": "string",
            "description": "Modifier name",
            "maxLength": 45
          },
          "Description": {
            "type": "string",
            "description": "Free-text description"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)"
          },
          "Type": {
            "type": "number",
            "description": "Selection type (0 = single, 1 = multi)"
          },
          "Min": {
            "type": "number",
            "description": "Minimum selections"
          },
          "Max": {
            "type": "number",
            "description": "Maximum selections"
          },
          "HasMax": {
            "type": "number",
            "description": "Has maximum flag"
          },
          "IncludeQty": {
            "type": "number",
            "description": "Include qty flag (legacy)"
          },
          "DisplayOrder": {
            "type": "number",
            "description": "Display order"
          },
          "Options": {
            "description": "Modifier options",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModifierOptionDto"
            }
          },
          "ItemIds": {
            "description": "Item IDs this modifier applies to",
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        },
        "required": [
          "modifier",
          "Type",
          "Options"
        ]
      },
      "UpdateModifierWithOptionsDto": {
        "type": "object",
        "properties": {
          "modifier": {
            "type": "string",
            "description": "Modifier name",
            "maxLength": 45
          },
          "Description": {
            "type": "string",
            "description": "Free-text description"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)"
          },
          "Type": {
            "type": "number",
            "description": "Selection type (0 = single, 1 = multi)"
          },
          "Min": {
            "type": "number",
            "description": "Minimum selections"
          },
          "Max": {
            "type": "number",
            "description": "Maximum selections"
          },
          "HasMax": {
            "type": "number",
            "description": "Has maximum flag"
          },
          "IncludeQty": {
            "type": "number",
            "description": "Include qty flag (legacy)"
          },
          "DisplayOrder": {
            "type": "number",
            "description": "Display order"
          },
          "Options": {
            "description": "Modifier options",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModifierOptionDto"
            }
          },
          "ItemIds": {
            "description": "Item IDs this modifier applies to",
            "type": "array",
            "items": {
              "type": "number"
            }
          }
        }
      },
      "Object": {
        "type": "object",
        "properties": {}
      },
      "PurchaseOrderItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Existing purchaseItems row id (update only; 0/undef = new row)"
          },
          "itemId": {
            "type": "number",
            "description": "Item ID"
          },
          "variantId": {
            "type": "number",
            "description": "Variant ID (0 when none)"
          },
          "item": {
            "type": "string",
            "description": "Item display name (informational)"
          },
          "qty": {
            "type": "number",
            "description": "Quantity ordered (> 0)"
          },
          "rate": {
            "type": "number",
            "description": "Unit cost before tax"
          },
          "supplyPrice": {
            "type": "number",
            "description": "Supply price written back to items master"
          },
          "taxableAmount": {
            "type": "number",
            "description": "Rate × qty pre-tax"
          },
          "taxId": {
            "type": "number",
            "description": "Primary tax ID"
          },
          "cessId": {
            "type": "number",
            "description": "Cess tax ID"
          },
          "tax1": {
            "type": "number",
            "description": "Primary tax amount"
          },
          "tax2": {
            "type": "number",
            "description": "Secondary (GST) tax amount"
          },
          "cess": {
            "type": "number",
            "description": "Cess amount"
          },
          "note": {
            "type": "string",
            "description": "Line note"
          },
          "serialNo": {
            "description": "Optional pre-picked serial numbers (when itemType has SerialNo)",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "itemId",
          "qty",
          "rate",
          "taxableAmount"
        ]
      },
      "CreatePurchaseOrderDto": {
        "type": "object",
        "properties": {
          "orderNo": {
            "type": "number",
            "description": "Order number (usually orderMax + 1)"
          },
          "invoNo": {
            "type": "string",
            "description": "Supplier invoice number (required when receiveOnCreate is true)"
          },
          "date": {
            "type": "string",
            "description": "Order date (ISO or YYYY-MM-DD)"
          },
          "reciveDate": {
            "type": "string",
            "description": "Expected receive date"
          },
          "supplierId": {
            "type": "number",
            "description": "Supplier ID"
          },
          "storeId": {
            "type": "number",
            "description": "Destination store ID"
          },
          "narration": {
            "type": "string",
            "description": "Narration / notes for the supplier"
          },
          "currencyId": {
            "type": "number",
            "description": "Secondary currency ID (defaults to 1 — base)"
          },
          "exchangeRate": {
            "type": "number",
            "description": "Exchange rate against the base currency"
          },
          "roudOfAmount": {
            "type": "number",
            "description": "Round-off amount (after summing items + tax)"
          },
          "incTax": {
            "type": "boolean",
            "description": "Tax included in item cost flag"
          },
          "provider": {
            "type": "string",
            "description": "Integration provider (leave empty for manual PO)"
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PurchaseOrderItemDto"
            }
          }
        },
        "required": [
          "orderNo",
          "date",
          "reciveDate",
          "supplierId",
          "storeId",
          "items"
        ]
      },
      "UpdatePurchaseOrderDto": {
        "type": "object",
        "properties": {
          "orderNo": {
            "type": "number",
            "description": "Order number (usually orderMax + 1)"
          },
          "invoNo": {
            "type": "string",
            "description": "Supplier invoice number (required when receiveOnCreate is true)"
          },
          "date": {
            "type": "string",
            "description": "Order date (ISO or YYYY-MM-DD)"
          },
          "reciveDate": {
            "type": "string",
            "description": "Expected receive date"
          },
          "supplierId": {
            "type": "number",
            "description": "Supplier ID"
          },
          "storeId": {
            "type": "number",
            "description": "Destination store ID"
          },
          "narration": {
            "type": "string",
            "description": "Narration / notes for the supplier"
          },
          "currencyId": {
            "type": "number",
            "description": "Secondary currency ID (defaults to 1 — base)"
          },
          "exchangeRate": {
            "type": "number",
            "description": "Exchange rate against the base currency"
          },
          "roudOfAmount": {
            "type": "number",
            "description": "Round-off amount (after summing items + tax)"
          },
          "incTax": {
            "type": "boolean",
            "description": "Tax included in item cost flag"
          },
          "provider": {
            "type": "string",
            "description": "Integration provider (leave empty for manual PO)"
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PurchaseOrderItemDto"
            }
          }
        }
      },
      "ReceivePurchaseItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "PurchaseItem row ID"
          },
          "itemId": {
            "type": "number",
            "description": "Item ID (for stock register)"
          },
          "variantId": {
            "type": "number",
            "description": "Variant ID (0 when none)"
          },
          "recivedQty": {
            "type": "number",
            "description": "Quantity being received in this call"
          },
          "rate": {
            "type": "number",
            "description": "Unit cost (rate)"
          },
          "taxableAmount": {
            "type": "number",
            "description": "Line taxable amount"
          },
          "serialNo": {
            "description": "Pre-picked serial numbers",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "itemId",
          "recivedQty"
        ]
      },
      "ReceivePurchaseOrderDto": {
        "type": "object",
        "properties": {
          "invoNo": {
            "type": "string",
            "description": "Supplier invoice number (required to receive)"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceivePurchaseItemDto"
            }
          }
        },
        "required": [
          "invoNo",
          "items"
        ]
      },
      "StockTransferItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Existing stockTransferItems row id (update only; 0/undef = new row)"
          },
          "itemId": {
            "type": "number",
            "description": "Item ID"
          },
          "variantId": {
            "type": "number",
            "description": "Variant ID (0 when none)"
          },
          "item": {
            "type": "string",
            "description": "Item display name (informational)"
          },
          "qty": {
            "type": "number",
            "description": "Quantity to transfer"
          },
          "rate": {
            "type": "number",
            "description": "Unit cost"
          },
          "taxableAmount": {
            "type": "number",
            "description": "Rate × qty"
          },
          "serialNo": {
            "description": "Pre-picked serial numbers (when the item tracks serial numbers)",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "itemId",
          "qty",
          "rate"
        ]
      },
      "CreateStockTransferDto": {
        "type": "object",
        "properties": {
          "transferNo": {
            "type": "number",
            "description": "Transfer order number (usually orderMax + 1)"
          },
          "date": {
            "type": "string",
            "description": "Transfer date (ISO or YYYY-MM-DD)"
          },
          "reciveDate": {
            "type": "string",
            "description": "Expected receive date (defaults to transfer date)"
          },
          "fromStoreId": {
            "type": "number",
            "description": "Source store ID"
          },
          "toStoreId": {
            "type": "number",
            "description": "Destination store ID"
          },
          "narration": {
            "type": "string",
            "description": "Narration / reference notes"
          },
          "taxableAmount": {
            "type": "number",
            "description": "Cart total taxable (rate × qty). Recomputed server-side too."
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StockTransferItemDto"
            }
          }
        },
        "required": [
          "transferNo",
          "date",
          "fromStoreId",
          "toStoreId",
          "items"
        ]
      },
      "UpdateStockTransferDto": {
        "type": "object",
        "properties": {
          "transferNo": {
            "type": "number",
            "description": "Transfer order number (usually orderMax + 1)"
          },
          "date": {
            "type": "string",
            "description": "Transfer date (ISO or YYYY-MM-DD)"
          },
          "reciveDate": {
            "type": "string",
            "description": "Expected receive date (defaults to transfer date)"
          },
          "fromStoreId": {
            "type": "number",
            "description": "Source store ID"
          },
          "toStoreId": {
            "type": "number",
            "description": "Destination store ID"
          },
          "narration": {
            "type": "string",
            "description": "Narration / reference notes"
          },
          "taxableAmount": {
            "type": "number",
            "description": "Cart total taxable (rate × qty). Recomputed server-side too."
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StockTransferItemDto"
            }
          }
        }
      },
      "ReceiveStockTransferItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "stockTransferItems row id"
          },
          "itemId": {
            "type": "number",
            "description": "Item ID"
          },
          "variantId": {
            "type": "number",
            "description": "Variant ID (0 when none)"
          },
          "recivedQty": {
            "type": "number",
            "description": "Qty being received in this call"
          },
          "rate": {
            "type": "number",
            "description": "Unit cost (for the stock-in ledger row)"
          },
          "serialNo": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "itemId",
          "recivedQty"
        ]
      },
      "ReceiveStockTransferDto": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiveStockTransferItemDto"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "StockAdjustmentItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Existing stockAdjustmentItems row id (update only)"
          },
          "itemId": {
            "type": "number",
            "description": "Item ID"
          },
          "variantId": {
            "type": "number",
            "description": "Variant ID (0 when none)"
          },
          "item": {
            "type": "string",
            "description": "Item display name (informational)"
          },
          "qty": {
            "type": "number",
            "description": "Adjustment qty (absolute number, not delta-signed)"
          },
          "cost": {
            "type": "number",
            "description": "Unit cost (ignored for pure DECREASE)"
          },
          "stock": {
            "type": "number",
            "description": "Snapshot of the item stock at capture time (shown on the UI)"
          },
          "stockCost": {
            "type": "number",
            "description": "Snapshot of the weighted-avg cost at capture time"
          },
          "batchId": {
            "type": "number",
            "description": "Batch / lot id (for HasBatch items)"
          },
          "note": {
            "type": "string",
            "description": "Free-text note for the audit trail"
          }
        },
        "required": [
          "itemId",
          "qty"
        ]
      },
      "CreateStockAdjustmentDto": {
        "type": "object",
        "properties": {
          "no": {
            "type": "number",
            "description": "Adjustment number (usually nextNo + 1)"
          },
          "type": {
            "type": "number",
            "description": "Mode: 0 Decrease, 1 Increase, 2 Set to count",
            "enum": [
              0,
              1,
              2
            ]
          },
          "storeId": {
            "type": "number",
            "description": "Store the adjustment posts against"
          },
          "narration": {
            "type": "string",
            "description": "Narration / justification (not visible to customer)"
          },
          "date": {
            "type": "string",
            "description": "Adjustment date (ISO). Defaults to now."
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StockAdjustmentItemDto"
            }
          }
        },
        "required": [
          "no",
          "type",
          "storeId",
          "items"
        ]
      },
      "UpdateStockAdjustmentDto": {
        "type": "object",
        "properties": {
          "no": {
            "type": "number",
            "description": "Adjustment number (usually nextNo + 1)"
          },
          "type": {
            "type": "number",
            "description": "Mode: 0 Decrease, 1 Increase, 2 Set to count",
            "enum": [
              0,
              1,
              2
            ]
          },
          "storeId": {
            "type": "number",
            "description": "Store the adjustment posts against"
          },
          "narration": {
            "type": "string",
            "description": "Narration / justification (not visible to customer)"
          },
          "date": {
            "type": "string",
            "description": "Adjustment date (ISO). Defaults to now."
          },
          "items": {
            "description": "Line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StockAdjustmentItemDto"
            }
          }
        }
      },
      "ProductionIngredientDto": {
        "type": "object",
        "properties": {
          "itemId": {
            "type": "number",
            "description": "Ingredient item id"
          },
          "variantId": {
            "type": "number",
            "description": "Variant id (0 when none)"
          },
          "batchId": {
            "type": "number",
            "description": "Batch id (for tracked items)"
          },
          "qty": {
            "type": "number",
            "description": "Qty consumed for this production run"
          },
          "cost": {
            "type": "number",
            "description": "Per-unit cost for this ingredient. When omitted the server falls back to the weighted-avg store cost; when supplied (user edited it on the form) it is used verbatim for the cost roll-up and the stock ledger."
          },
          "item": {
            "type": "string",
            "description": "Display name for informational purposes"
          }
        },
        "required": [
          "itemId",
          "qty"
        ]
      },
      "CreateProductionDto": {
        "type": "object",
        "properties": {
          "no": {
            "type": "number",
            "description": "Batch number (usually nextNo + 1). Omit to let the server pick."
          },
          "storeId": {
            "type": "number",
            "description": "Store / kitchen the batch is produced at"
          },
          "itemId": {
            "type": "number",
            "description": "Product being produced (output item)"
          },
          "variantId": {
            "type": "number",
            "description": "Variant id of the output (0 when none)"
          },
          "batchId": {
            "type": "number",
            "description": "Output batch id (for HasBatch items)"
          },
          "qty": {
            "type": "number",
            "description": "Qty of the output produced"
          },
          "date": {
            "type": "string",
            "description": "Production date (ISO). Defaults to now."
          },
          "narration": {
            "type": "string",
            "description": "Narration / notes"
          },
          "items": {
            "description": "Ingredient lines consumed",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductionIngredientDto"
            }
          }
        },
        "required": [
          "storeId",
          "itemId",
          "qty",
          "items"
        ]
      },
      "RecipeIngredientDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Row id (for updates)"
          },
          "ItemId": {
            "type": "number"
          },
          "VariantId": {
            "type": "number"
          },
          "Qty": {
            "type": "number"
          },
          "Unit": {
            "type": "string"
          },
          "CostOverride": {
            "type": "number",
            "description": "Override the computed cost; null = use item cost"
          },
          "OrderIndex": {
            "type": "number",
            "description": "Order index for drag-reorder"
          }
        },
        "required": [
          "ItemId",
          "Qty"
        ]
      },
      "CreateRecipeWithIngredientsDto": {
        "type": "object",
        "properties": {
          "Recipe": {
            "type": "string",
            "maxLength": 45
          },
          "Description": {
            "type": "string"
          },
          "RecipeType": {
            "type": "number",
            "description": "0 = main recipe, 1 = sub-recipe"
          },
          "CategoryId": {
            "type": "number"
          },
          "ImageId": {
            "type": "string"
          },
          "ItemId": {
            "type": "number",
            "description": "Linked menu item id"
          },
          "VariantId": {
            "type": "number"
          },
          "Qty": {
            "type": "number",
            "description": "Yield quantity"
          },
          "YieldUnit": {
            "type": "string"
          },
          "Servings": {
            "type": "number"
          },
          "ServingSize": {
            "type": "number"
          },
          "ServingUnit": {
            "type": "string"
          },
          "PrepTime": {
            "type": "number"
          },
          "CookTime": {
            "type": "number"
          },
          "Difficulty": {
            "type": "string"
          },
          "KitchenStation": {
            "type": "string"
          },
          "Instructions": {
            "type": "string"
          },
          "Allergens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "DietaryLabels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "AutoDeduct": {
            "type": "boolean"
          },
          "AllowScaling": {
            "type": "boolean"
          },
          "ShowOnKds": {
            "type": "boolean"
          },
          "WasteFactorPct": {
            "type": "number",
            "description": "Waste factor in percent (0-100)"
          },
          "SellingPriceOverride": {
            "type": "number",
            "description": "Override the computed selling price (optional)"
          },
          "Status": {
            "type": "number"
          },
          "Ingredients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecipeIngredientDto"
            }
          }
        },
        "required": [
          "Recipe",
          "ItemId",
          "Ingredients"
        ]
      },
      "UpdateRecipeWithIngredientsDto": {
        "type": "object",
        "properties": {
          "Recipe": {
            "type": "string",
            "maxLength": 45
          },
          "Description": {
            "type": "string"
          },
          "RecipeType": {
            "type": "number",
            "description": "0 = main recipe, 1 = sub-recipe"
          },
          "CategoryId": {
            "type": "number"
          },
          "ImageId": {
            "type": "string"
          },
          "ItemId": {
            "type": "number",
            "description": "Linked menu item id"
          },
          "VariantId": {
            "type": "number"
          },
          "Qty": {
            "type": "number",
            "description": "Yield quantity"
          },
          "YieldUnit": {
            "type": "string"
          },
          "Servings": {
            "type": "number"
          },
          "ServingSize": {
            "type": "number"
          },
          "ServingUnit": {
            "type": "string"
          },
          "PrepTime": {
            "type": "number"
          },
          "CookTime": {
            "type": "number"
          },
          "Difficulty": {
            "type": "string"
          },
          "KitchenStation": {
            "type": "string"
          },
          "Instructions": {
            "type": "string"
          },
          "Allergens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "DietaryLabels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "AutoDeduct": {
            "type": "boolean"
          },
          "AllowScaling": {
            "type": "boolean"
          },
          "ShowOnKds": {
            "type": "boolean"
          },
          "WasteFactorPct": {
            "type": "number",
            "description": "Waste factor in percent (0-100)"
          },
          "SellingPriceOverride": {
            "type": "number",
            "description": "Override the computed selling price (optional)"
          },
          "Status": {
            "type": "number"
          },
          "Ingredients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecipeIngredientDto"
            }
          }
        }
      },
      "SaveComboSlotDto": {
        "type": "object",
        "properties": {}
      },
      "SaveMealDto": {
        "type": "object",
        "properties": {}
      },
      "PartnerCreateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Customer name",
            "maxLength": 150
          },
          "mobile": {
            "type": "string",
            "description": "Mobile number",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "description": "Email address",
            "maxLength": 65
          },
          "loyaltyNo": {
            "type": "string",
            "description": "Loyalty number",
            "maxLength": 20
          },
          "trn": {
            "type": "string",
            "description": "Tax Registration Number",
            "maxLength": 20
          },
          "countryId": {
            "type": "number",
            "description": "Country ID",
            "default": 0
          },
          "stateId": {
            "type": "number",
            "description": "State ID",
            "default": 0
          },
          "state": {
            "type": "string",
            "description": "State name",
            "maxLength": 45
          },
          "address": {
            "type": "string",
            "description": "Address"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "creditCust": {
            "type": "number",
            "description": "Credit customer flag",
            "default": 0
          },
          "creditLimit": {
            "type": "number",
            "description": "Credit limit"
          },
          "opening": {
            "type": "number",
            "description": "Opening balance"
          },
          "loyaltyPoint": {
            "type": "number",
            "description": "Loyalty points",
            "default": 0
          },
          "birthDate": {
            "type": "string",
            "description": "Birth date (YYYY-MM-DD)"
          },
          "anniversary": {
            "type": "string",
            "description": "Anniversary date (YYYY-MM-DD)"
          },
          "firebaseUserId": {
            "type": "string",
            "description": "Firebase user ID",
            "maxLength": 200
          },
          "latitude": {
            "type": "number",
            "description": "Latitude"
          },
          "longitude": {
            "type": "number",
            "description": "Longitude"
          },
          "landmark": {
            "type": "string",
            "description": "Landmark"
          },
          "ZIP": {
            "type": "string",
            "description": "ZIP code",
            "maxLength": 45
          },
          "StoreId": {
            "type": "number",
            "description": "Store ID",
            "default": 0
          },
          "TaxExempt": {
            "type": "number",
            "description": "Tax exempt flag",
            "default": 0
          }
        },
        "required": [
          "name"
        ]
      },
      "PartnerUpdateCustomerDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Customer name",
            "maxLength": 150
          },
          "mobile": {
            "type": "string",
            "description": "Mobile number",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "description": "Email address",
            "maxLength": 65
          },
          "loyaltyNo": {
            "type": "string",
            "description": "Loyalty number",
            "maxLength": 20
          },
          "trn": {
            "type": "string",
            "description": "Tax Registration Number",
            "maxLength": 20
          },
          "countryId": {
            "type": "number",
            "description": "Country ID",
            "default": 0
          },
          "stateId": {
            "type": "number",
            "description": "State ID",
            "default": 0
          },
          "state": {
            "type": "string",
            "description": "State name",
            "maxLength": 45
          },
          "address": {
            "type": "string",
            "description": "Address"
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "creditCust": {
            "type": "number",
            "description": "Credit customer flag",
            "default": 0
          },
          "creditLimit": {
            "type": "number",
            "description": "Credit limit"
          },
          "opening": {
            "type": "number",
            "description": "Opening balance"
          },
          "loyaltyPoint": {
            "type": "number",
            "description": "Loyalty points",
            "default": 0
          },
          "birthDate": {
            "type": "string",
            "description": "Birth date (YYYY-MM-DD)"
          },
          "anniversary": {
            "type": "string",
            "description": "Anniversary date (YYYY-MM-DD)"
          },
          "firebaseUserId": {
            "type": "string",
            "description": "Firebase user ID",
            "maxLength": 200
          },
          "latitude": {
            "type": "number",
            "description": "Latitude"
          },
          "longitude": {
            "type": "number",
            "description": "Longitude"
          },
          "landmark": {
            "type": "string",
            "description": "Landmark"
          },
          "ZIP": {
            "type": "string",
            "description": "ZIP code",
            "maxLength": 45
          },
          "StoreId": {
            "type": "number",
            "description": "Store ID",
            "default": 0
          },
          "TaxExempt": {
            "type": "number",
            "description": "Tax exempt flag",
            "default": 0
          }
        }
      },
      "CreateReservationDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "number",
            "description": "Customer ID"
          },
          "reservationDate": {
            "type": "string",
            "description": "Reservation date (YYYY-MM-DD)"
          },
          "reservationTime": {
            "type": "string",
            "description": "Reservation time (HH:mm or HH:mm:ss, 24h)"
          },
          "partySize": {
            "type": "number",
            "description": "Party size — number of guests"
          },
          "durationMinutes": {
            "type": "number",
            "description": "Duration in minutes (default 120)"
          },
          "status": {
            "type": "string",
            "description": "Booking status",
            "enum": [
              "pending",
              "confirmed",
              "seated",
              "completed",
              "cancelled"
            ],
            "default": "pending"
          },
          "occasion": {
            "type": "string",
            "description": "Occasion label (free text — \"Birthday\", \"Anniversary\", \"Date Night\"…)."
          },
          "storeId": {
            "type": "number",
            "description": "Store the reservation belongs to"
          },
          "note": {
            "type": "string",
            "description": "Free-text note for front-of-house"
          },
          "phone": {
            "type": "string",
            "description": "Guest phone (denormalized snapshot)"
          },
          "email": {
            "type": "string",
            "description": "Guest email (denormalized snapshot)"
          },
          "address": {
            "type": "string",
            "description": "Guest address"
          },
          "customerPreferences": {
            "type": "string",
            "description": "Guest preferences (allergies, seating, …)"
          },
          "customerPhotoUrl": {
            "type": "string",
            "description": "Guest photo URL (for VIPs / regulars)"
          },
          "preOrderedFoods": {
            "type": "array",
            "description": "Pre-ordered food lines — stored as JSON in the DB. Shape: [{ name, quantity, price, notes }]",
            "items": {
              "type": "object"
            }
          },
          "extra": {
            "type": "object",
            "description": "Raw pass-through JSON for extensions"
          }
        },
        "required": [
          "customerId",
          "reservationDate",
          "reservationTime",
          "partySize"
        ]
      },
      "UpdateReservationDto": {
        "type": "object",
        "properties": {
          "customerId": {
            "type": "number",
            "description": "Customer ID"
          },
          "reservationDate": {
            "type": "string",
            "description": "Reservation date (YYYY-MM-DD)"
          },
          "reservationTime": {
            "type": "string",
            "description": "Reservation time (HH:mm or HH:mm:ss, 24h)"
          },
          "partySize": {
            "type": "number",
            "description": "Party size — number of guests"
          },
          "durationMinutes": {
            "type": "number",
            "description": "Duration in minutes (default 120)"
          },
          "status": {
            "type": "string",
            "description": "Booking status",
            "enum": [
              "pending",
              "confirmed",
              "seated",
              "completed",
              "cancelled"
            ],
            "default": "pending"
          },
          "occasion": {
            "type": "string",
            "description": "Occasion label (free text — \"Birthday\", \"Anniversary\", \"Date Night\"…)."
          },
          "storeId": {
            "type": "number",
            "description": "Store the reservation belongs to"
          },
          "note": {
            "type": "string",
            "description": "Free-text note for front-of-house"
          },
          "phone": {
            "type": "string",
            "description": "Guest phone (denormalized snapshot)"
          },
          "email": {
            "type": "string",
            "description": "Guest email (denormalized snapshot)"
          },
          "address": {
            "type": "string",
            "description": "Guest address"
          },
          "customerPreferences": {
            "type": "string",
            "description": "Guest preferences (allergies, seating, …)"
          },
          "customerPhotoUrl": {
            "type": "string",
            "description": "Guest photo URL (for VIPs / regulars)"
          },
          "preOrderedFoods": {
            "type": "array",
            "description": "Pre-ordered food lines — stored as JSON in the DB. Shape: [{ name, quantity, price, notes }]",
            "items": {
              "type": "object"
            }
          },
          "extra": {
            "type": "object",
            "description": "Raw pass-through JSON for extensions"
          }
        }
      },
      "PartnerCreateTaxDto": {
        "type": "object",
        "properties": {
          "tax": {
            "type": "string",
            "description": "Tax name",
            "maxLength": 45
          },
          "taxRate": {
            "type": "number",
            "description": "Tax rate (percentage)"
          },
          "type": {
            "type": "number",
            "description": "Type: 0 = Exclusive, 1 = Inclusive",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "department": {
            "type": "string",
            "description": "Department grouping (free text)",
            "maxLength": 60
          },
          "applyTo": {
            "type": "number",
            "description": "Apply scope: 0 = all items, 1 = specific department, 2 = specific items",
            "default": 0
          },
          "compound": {
            "type": "boolean",
            "description": "Compound tax (applies on top of other taxes)",
            "default": false
          },
          "QuickbookTaxCode": {
            "type": "string",
            "description": "Quickbook Tax Code"
          },
          "ZMTaxCode": {
            "type": "string",
            "description": "ZM Tax Code"
          }
        },
        "required": [
          "tax",
          "taxRate"
        ]
      },
      "PartnerUpdateTaxDto": {
        "type": "object",
        "properties": {
          "tax": {
            "type": "string",
            "description": "Tax name",
            "maxLength": 45
          },
          "taxRate": {
            "type": "number",
            "description": "Tax rate (percentage)"
          },
          "type": {
            "type": "number",
            "description": "Type: 0 = Exclusive, 1 = Inclusive",
            "default": 0
          },
          "status": {
            "type": "number",
            "description": "Status (1 = active, 0 = inactive)",
            "default": 1
          },
          "department": {
            "type": "string",
            "description": "Department grouping (free text)",
            "maxLength": 60
          },
          "applyTo": {
            "type": "number",
            "description": "Apply scope: 0 = all items, 1 = specific department, 2 = specific items",
            "default": 0
          },
          "compound": {
            "type": "boolean",
            "description": "Compound tax (applies on top of other taxes)",
            "default": false
          },
          "QuickbookTaxCode": {
            "type": "string",
            "description": "Quickbook Tax Code"
          },
          "ZMTaxCode": {
            "type": "string",
            "description": "ZM Tax Code"
          }
        }
      },
      "CreateOnlineOrderItemDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number"
          },
          "item": {
            "type": "string"
          },
          "qty": {
            "type": "number"
          },
          "rate": {
            "type": "number"
          },
          "note": {
            "type": "string"
          },
          "variantId": {
            "type": "number",
            "description": "Variant master ID (0 for standard items)"
          },
          "itemModifiers": {
            "description": "Modifier group IDs selected on this line",
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "modifiers": {
            "type": "array",
            "description": "Selected modifier items"
          }
        },
        "required": [
          "id",
          "item",
          "qty",
          "rate"
        ]
      },
      "CreateOnlineOrderDto": {
        "type": "object",
        "properties": {
          "storeId": {
            "type": "number",
            "description": "Store the order belongs to"
          },
          "items": {
            "description": "Cart line items",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateOnlineOrderItemDto"
            }
          },
          "orderType": {
            "type": "number",
            "description": "2 = takeout, 3 = delivery",
            "enum": [
              2,
              3
            ]
          },
          "status": {
            "type": "number",
            "description": "0 = draft, 1 = new/confirmed (default)"
          },
          "customerId": {
            "type": "number"
          },
          "customerName": {
            "type": "string"
          },
          "customerPhone": {
            "type": "string"
          },
          "subtotal": {
            "type": "number"
          },
          "taxAmount": {
            "type": "number"
          },
          "cessAmount": {
            "type": "number",
            "description": "Total cess amount across the cart"
          },
          "tipAmount": {
            "type": "number"
          },
          "tipPercent": {
            "type": "number"
          },
          "totalAmount": {
            "type": "number"
          },
          "note": {
            "type": "string"
          },
          "takenBy": {
            "type": "string",
            "description": "Who took the order (free text)"
          },
          "cartList": {
            "type": "array",
            "description": "Rich v3 POS-style CartList payload. When provided, persisted verbatim into onlineOrders.CartList; the simpler `items` field is ignored."
          }
        },
        "required": [
          "storeId",
          "items"
        ]
      }
    }
  }
}
