{
  "openapi": "3.0.3",
  "info": {
    "title": "EyesAsia REST API",
    "version": "1.3.0",
    "description": "Public catalog and authenticated commerce API for the EyesAsia eyewear storefront.",
    "termsOfService": "https://www.eyesasia.com/terms-and-conditions",
    "contact": {
      "name": "EyesAsia developer support",
      "url": "https://www.eyesasia.com/contact/",
      "email": "info@eyesasia.com"
    }
  },
  "servers": [
    {
      "url": "https://sunglasses-api.onrender.com",
      "description": "Production"
    },
    {
      "url": "http://localhost:3000",
      "description": "Local development"
    }
  ],
  "x-permissions-supported": [
    "analytics.read",
    "catalog.read",
    "catalog.write",
    "catalog.archive",
    "catalog.delete_permanently",
    "discounts.read",
    "discounts.write",
    "orders.read",
    "orders.update_status",
    "marketing.read",
    "marketing.test",
    "marketing.publish",
    "users.manage",
    "roles.manage",
    "permissions.manage",
    "admins.grant",
    "audit_log.read",
    "content.read",
    "content.write",
    "support.read",
    "support.reply",
    "support.manage"
  ],
  "x-rate-limit-policy": {
    "description": "Responses from rate-limited endpoints expose standard RateLimit fields. Legacy X-RateLimit fields remain available for compatibility.",
    "headers": [
      "RateLimit-Limit",
      "RateLimit-Remaining",
      "RateLimit-Reset",
      "Retry-After"
    ]
  },
  "tags": [
    {
      "name": "Auth"
    },
    {
      "name": "Products"
    },
    {
      "name": "Lens Packages"
    },
    {
      "name": "Prescriptions"
    },
    {
      "name": "Cart"
    },
    {
      "name": "Favorites"
    },
    {
      "name": "Thai Locations"
    },
    {
      "name": "Orders"
    },
    {
      "name": "Payments"
    },
    {
      "name": "Shipments"
    },
    {
      "name": "Admin"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Short-lived first-party EyesAsia access token. Staff operations also enforce the documented x-required-permission value."
      },
      "refreshSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Secure-refreshToken"
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "resolutionHint": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message",
              "resolutionHint"
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "error",
          "message"
        ]
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          }
        },
        "required": [
          "message"
        ]
      },
      "AuthRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string"
          }
        },
        "required": [
          "email",
          "password"
        ]
      },
      "GoogleAuthRequest": {
        "type": "object",
        "properties": {
          "idToken": {
            "type": "string"
          }
        },
        "required": [
          "idToken"
        ]
      },
      "ForgotPasswordRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          }
        },
        "required": [
          "email"
        ]
      },
      "ResetPasswordRequest": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          },
          "newPassword": {
            "type": "string",
            "format": "password",
            "minLength": 8,
            "description": "Must include uppercase, lowercase, number, and symbol."
          }
        },
        "required": [
          "token",
          "newPassword"
        ]
      },
      "AuthUser": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "isActive": {
            "type": "boolean"
          },
          "role": {
            "type": "string",
            "enum": [
              "CUSTOMER",
              "WORKER",
              "ADMIN"
            ]
          }
        },
        "required": [
          "id",
          "email",
          "isActive",
          "role"
        ]
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "accessToken": {
            "type": "string",
            "description": "Short-lived JWT access token sent as a Bearer token."
          },
          "sessionExpiresAt": {
            "type": "integer",
            "format": "int64",
            "description": "Effective idle or absolute session expiry as Unix epoch milliseconds."
          },
          "user": {
            "$ref": "#/components/schemas/AuthUser"
          }
        },
        "required": [
          "accessToken",
          "sessionExpiresAt",
          "user"
        ]
      },
      "CurrentUserResponse": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/AuthUser"
          }
        },
        "required": [
          "user"
        ]
      },
      "AddressInput": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "mobilePrimary": {
            "type": "string",
            "maxLength": 20
          },
          "postalCode": {
            "type": "string",
            "pattern": "^[0-9]{5}$"
          },
          "addressLine": {
            "type": "string",
            "maxLength": 200
          },
          "provinceCode": {
            "type": "string",
            "pattern": "^[0-9]{2}$"
          },
          "districtCode": {
            "type": "string",
            "pattern": "^[0-9]{4}$"
          },
          "subdistrictCode": {
            "type": "string",
            "pattern": "^[0-9]{6}$"
          }
        },
        "required": [
          "firstName",
          "lastName",
          "mobilePrimary",
          "postalCode",
          "addressLine",
          "provinceCode",
          "districtCode",
          "subdistrictCode"
        ]
      },
      "RawOrderAddress": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "integer"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "mobile_primary": {
            "type": "string"
          },
          "postal_code": {
            "type": "string"
          },
          "address_line": {
            "type": "string"
          },
          "province_code": {
            "type": "string",
            "pattern": "^[0-9]{2}$"
          },
          "district_code": {
            "type": "string",
            "pattern": "^[0-9]{4}$"
          },
          "subdistrict_code": {
            "type": "string",
            "pattern": "^[0-9]{6}$"
          },
          "subdistrict": {
            "type": "string"
          },
          "district": {
            "type": "string"
          },
          "province": {
            "type": "string"
          }
        },
        "required": [
          "order_id",
          "first_name",
          "last_name",
          "mobile_primary",
          "postal_code",
          "address_line",
          "province_code",
          "district_code",
          "subdistrict_code",
          "subdistrict",
          "district",
          "province"
        ]
      },
      "OrderShippingAddress": {
        "allOf": [
          {
            "$ref": "#/components/schemas/AddressInput"
          },
          {
            "type": "object",
            "properties": {
              "province": {
                "type": "string"
              },
              "district": {
                "type": "string"
              },
              "subdistrict": {
                "type": "string"
              }
            },
            "required": [
              "province",
              "district",
              "subdistrict"
            ]
          }
        ]
      },
      "ThaiLocationOption": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "name"
        ]
      },
      "ThaiSubdistrictOption": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ThaiLocationOption"
          },
          {
            "type": "object",
            "properties": {
              "postalCode": {
                "type": "string",
                "pattern": "^[0-9]{5}$"
              },
              "postalCodes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "pattern": "^[0-9]{5}$"
                }
              }
            },
            "required": [
              "postalCode",
              "postalCodes"
            ]
          }
        ]
      },
      "Prescription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "rightSphere": {
            "type": "number"
          },
          "rightCylinder": {
            "type": "number",
            "nullable": true
          },
          "rightAxis": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 180
          },
          "rightAddition": {
            "type": "number",
            "nullable": true
          },
          "leftSphere": {
            "type": "number"
          },
          "leftCylinder": {
            "type": "number",
            "nullable": true
          },
          "leftAxis": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 180
          },
          "leftAddition": {
            "type": "number",
            "nullable": true
          },
          "pdType": {
            "type": "string",
            "enum": [
              "SINGLE",
              "DUAL"
            ]
          },
          "pdSingle": {
            "type": "number",
            "nullable": true
          },
          "pdRight": {
            "type": "number",
            "nullable": true
          },
          "pdLeft": {
            "type": "number",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "rightSphere",
          "rightCylinder",
          "rightAxis",
          "rightAddition",
          "leftSphere",
          "leftCylinder",
          "leftAxis",
          "leftAddition",
          "pdType",
          "pdSingle",
          "pdRight",
          "pdLeft",
          "createdAt"
        ]
      },
      "CreatePrescriptionRequest": {
        "type": "object",
        "properties": {
          "rightSphere": {
            "type": "number"
          },
          "rightCylinder": {
            "type": "number",
            "nullable": true
          },
          "rightAxis": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 180
          },
          "rightAddition": {
            "type": "number",
            "nullable": true
          },
          "leftSphere": {
            "type": "number"
          },
          "leftCylinder": {
            "type": "number",
            "nullable": true
          },
          "leftAxis": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 180
          },
          "leftAddition": {
            "type": "number",
            "nullable": true
          },
          "pdType": {
            "type": "string",
            "enum": [
              "SINGLE",
              "DUAL"
            ]
          },
          "pdSingle": {
            "type": "number",
            "nullable": true
          },
          "pdRight": {
            "type": "number",
            "nullable": true
          },
          "pdLeft": {
            "type": "number",
            "nullable": true
          }
        },
        "required": [
          "rightSphere",
          "leftSphere",
          "pdType"
        ]
      },
      "LensPackage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "lensIndex": {
            "type": "number"
          },
          "feature": {
            "type": "string",
            "enum": [
              "CLEAR",
              "BLUE_LIGHT",
              "PHOTOCHROMIC"
            ]
          },
          "priceDelta": {
            "type": "number"
          },
          "minSphere": {
            "type": "number",
            "nullable": true
          },
          "maxSphere": {
            "type": "number",
            "nullable": true
          },
          "maxAbsCylinder": {
            "type": "number",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "lensIndex",
          "feature",
          "priceDelta",
          "minSphere",
          "maxSphere",
          "maxAbsCylinder"
        ]
      },
      "AdminLensPackage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "nameEn": {
            "type": "string"
          },
          "nameTh": {
            "type": "string"
          },
          "descriptionEn": {
            "type": "string",
            "nullable": true
          },
          "descriptionTh": {
            "type": "string",
            "nullable": true
          },
          "lensIndex": {
            "type": "number"
          },
          "feature": {
            "type": "string",
            "enum": [
              "CLEAR",
              "BLUE_LIGHT",
              "PHOTOCHROMIC"
            ]
          },
          "priceDelta": {
            "type": "number"
          },
          "minSphere": {
            "type": "number",
            "nullable": true
          },
          "maxSphere": {
            "type": "number",
            "nullable": true
          },
          "maxAbsCylinder": {
            "type": "number",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0
          },
          "isActive": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "nameEn",
          "nameTh",
          "descriptionEn",
          "descriptionTh",
          "lensIndex",
          "feature",
          "priceDelta",
          "minSphere",
          "maxSphere",
          "maxAbsCylinder",
          "sortOrder",
          "isActive",
          "createdAt",
          "updatedAt"
        ]
      },
      "AdminLensPackageInput": {
        "type": "object",
        "properties": {
          "nameEn": {
            "type": "string",
            "maxLength": 100
          },
          "nameTh": {
            "type": "string",
            "maxLength": 100
          },
          "descriptionEn": {
            "type": "string",
            "nullable": true
          },
          "descriptionTh": {
            "type": "string",
            "nullable": true
          },
          "lensIndex": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 9.99
          },
          "feature": {
            "type": "string",
            "enum": [
              "CLEAR",
              "BLUE_LIGHT",
              "PHOTOCHROMIC"
            ]
          },
          "priceDelta": {
            "type": "number",
            "minimum": 0
          },
          "minSphere": {
            "type": "number",
            "nullable": true
          },
          "maxSphere": {
            "type": "number",
            "nullable": true
          },
          "maxAbsCylinder": {
            "type": "number",
            "minimum": 0,
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0,
            "default": 0
          },
          "isActive": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "nameEn",
          "nameTh",
          "lensIndex",
          "feature",
          "priceDelta"
        ]
      },
      "AdminLensPackageUpdateRequest": {
        "type": "object",
        "properties": {
          "nameEn": {
            "type": "string",
            "maxLength": 100
          },
          "nameTh": {
            "type": "string",
            "maxLength": 100
          },
          "descriptionEn": {
            "type": "string",
            "nullable": true
          },
          "descriptionTh": {
            "type": "string",
            "nullable": true
          },
          "lensIndex": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 9.99
          },
          "feature": {
            "type": "string",
            "enum": [
              "CLEAR",
              "BLUE_LIGHT",
              "PHOTOCHROMIC"
            ]
          },
          "priceDelta": {
            "type": "number",
            "minimum": 0
          },
          "minSphere": {
            "type": "number",
            "nullable": true
          },
          "maxSphere": {
            "type": "number",
            "nullable": true
          },
          "maxAbsCylinder": {
            "type": "number",
            "minimum": 0,
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "minimum": 0
          },
          "isActive": {
            "type": "boolean"
          }
        },
        "minProperties": 1
      },
      "CartLensPackage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "lensIndex": {
            "type": "number"
          },
          "feature": {
            "type": "string",
            "enum": [
              "CLEAR",
              "BLUE_LIGHT",
              "PHOTOCHROMIC"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "lensIndex",
          "feature"
        ]
      },
      "ActiveDiscount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "PERCENTAGE",
              "FIXED"
            ]
          },
          "value": {
            "type": "number",
            "format": "float"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "value",
          "endDate"
        ]
      },
      "ProductImage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "cloudinaryPublicId": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "url"
        ]
      },
      "ProductImageInput": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "cloudinaryPublicId": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "url"
        ]
      },
      "ProductColor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "hexCode": {
            "type": "string",
            "nullable": true,
            "pattern": "^#[0-9A-Fa-f]{6}$"
          }
        },
        "required": [
          "id",
          "name",
          "code",
          "hexCode"
        ]
      },
      "ProductVariant": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "sku": {
            "type": "string"
          },
          "colors": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ProductColor"
            }
          },
          "colorName": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "format": "float"
          },
          "salePrice": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "isInStock": {
            "type": "boolean"
          },
          "stockQuantity": {
            "type": "integer"
          },
          "isDefault": {
            "type": "boolean"
          },
          "mainImageUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "sku",
          "colors",
          "colorName",
          "price",
          "salePrice",
          "isInStock",
          "stockQuantity",
          "isDefault",
          "mainImageUrl"
        ]
      },
      "ProductListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "sku": {
            "type": "string"
          },
          "modelId": {
            "type": "integer"
          },
          "modelCode": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "SUNGLASSES",
              "EYEGLASSES"
            ]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "color": {
            "$ref": "#/components/schemas/ProductColor"
          },
          "colors": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ProductColor"
            }
          },
          "colorName": {
            "type": "string"
          },
          "variants": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ProductVariant"
            }
          },
          "price": {
            "type": "number",
            "format": "float"
          },
          "salePrice": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "isInStock": {
            "type": "boolean"
          },
          "stockQuantity": {
            "type": "integer"
          },
          "isOnSale": {
            "type": "boolean"
          },
          "mainImageUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "sku",
          "modelId",
          "modelCode",
          "category",
          "name",
          "targetAudience",
          "color",
          "colors",
          "colorName",
          "variants",
          "price",
          "isInStock",
          "stockQuantity",
          "isOnSale"
        ]
      },
      "CartProductListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "modelId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "SUNGLASSES",
              "EYEGLASSES"
            ]
          },
          "colorName": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "format": "float"
          },
          "salePrice": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "isInStock": {
            "type": "boolean"
          },
          "mainImageUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "modelId",
          "name",
          "description",
          "targetAudience",
          "colorName",
          "price",
          "salePrice",
          "isInStock",
          "mainImageUrl"
        ]
      },
      "OrderProductListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "sku": {
            "type": "string"
          },
          "modelId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "colorName": {
            "type": "string"
          },
          "price": {
            "type": "number",
            "format": "float"
          },
          "salePrice": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "isInStock": {
            "type": "boolean"
          },
          "mainImageUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "sku",
          "modelId",
          "name",
          "description",
          "targetAudience",
          "colorName",
          "price",
          "salePrice",
          "isInStock",
          "mainImageUrl"
        ]
      },
      "ProductDetails": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProductListItem"
          },
          {
            "type": "object",
            "properties": {
              "images": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProductImage"
                }
              },
              "activeDiscounts": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ActiveDiscount"
                }
              },
              "specifications": {
                "$ref": "#/components/schemas/ProductSpecifications"
              },
              "size": {
                "$ref": "#/components/schemas/ProductSize"
              },
              "frameColors": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProductColor"
                }
              },
              "lensColors": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProductColor"
                }
              }
            },
            "required": [
              "images",
              "activeDiscounts",
              "specifications",
              "size",
              "frameColors",
              "lensColors"
            ]
          }
        ]
      },
      "ProductSpecifications": {
        "type": "object",
        "properties": {
          "brand": {
            "type": "string",
            "nullable": true
          },
          "primaryShape": {
            "type": "string",
            "nullable": true
          },
          "material": {
            "type": "string",
            "nullable": true
          },
          "rimType": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "brand",
          "primaryShape",
          "material",
          "rimType"
        ]
      },
      "ProductSize": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "fitLabel": {
            "type": "string",
            "nullable": true,
            "enum": [
              "NARROW",
              "AVERAGE",
              "WIDE",
              "EXTRA_WIDE",
              null
            ]
          },
          "lensWidthMm": {
            "type": "number",
            "nullable": true
          },
          "lensHeightMm": {
            "type": "number",
            "nullable": true
          },
          "bridgeWidthMm": {
            "type": "number",
            "nullable": true
          },
          "templeLengthMm": {
            "type": "number",
            "nullable": true
          }
        },
        "required": [
          "id",
          "fitLabel",
          "lensWidthMm",
          "lensHeightMm",
          "bridgeWidthMm",
          "templeLengthMm"
        ]
      },
      "AdminProductInput": {
        "type": "object",
        "properties": {
          "modelId": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "modelCode": {
            "type": "string"
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "SUNGLASSES",
              "EYEGLASSES"
            ]
          },
          "brand": {
            "type": "string"
          },
          "primaryShape": {
            "type": "string",
            "enum": [
              "AVIATOR",
              "RECTANGLE",
              "SQUARE",
              "CAT_EYE",
              "ROUND",
              "WRAP",
              "OVAL",
              "BROWLINE",
              "GEOMETRIC",
              "WAYFRAME"
            ]
          },
          "material": {
            "type": "string",
            "enum": [
              "ACETATE",
              "PLASTIC",
              "METAL",
              "ULTEM",
              "TITANIUM",
              "TR90",
              "STAINLESS_STEEL",
              "LIGHTWEIGHT"
            ]
          },
          "rimType": {
            "type": "string",
            "enum": [
              "FULL_RIM",
              "SEMI_RIMLESS",
              "RIMLESS"
            ]
          },
          "fitLabel": {
            "type": "string",
            "enum": [
              "NARROW",
              "AVERAGE",
              "WIDE",
              "EXTRA_WIDE"
            ]
          },
          "lensWidthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "lensHeightMm": {
            "type": "number",
            "minimum": 0.1
          },
          "bridgeWidthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "templeLengthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "componentColors": {
            "type": "array",
            "description": "One or more FRAME colors and one or more LENS colors. New names are created as reusable global colors.",
            "minItems": 2,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/ProductComponentColorInput"
            }
          },
          "price": {
            "type": "number",
            "format": "float",
            "minimum": 0.01
          },
          "stockQuantity": {
            "type": "integer",
            "minimum": 0
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductImageInput"
            }
          }
        },
        "required": [
          "componentColors",
          "price",
          "stockQuantity",
          "images"
        ]
      },
      "AdminProductUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "modelCode": {
            "type": "string"
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "SUNGLASSES",
              "EYEGLASSES"
            ]
          },
          "brand": {
            "type": "string"
          },
          "primaryShape": {
            "type": "string",
            "enum": [
              "AVIATOR",
              "RECTANGLE",
              "SQUARE",
              "CAT_EYE",
              "ROUND",
              "WRAP",
              "OVAL",
              "BROWLINE",
              "GEOMETRIC",
              "WAYFRAME"
            ]
          },
          "material": {
            "type": "string",
            "enum": [
              "ACETATE",
              "PLASTIC",
              "METAL",
              "ULTEM",
              "TITANIUM",
              "TR90",
              "STAINLESS_STEEL",
              "LIGHTWEIGHT"
            ]
          },
          "rimType": {
            "type": "string",
            "enum": [
              "FULL_RIM",
              "SEMI_RIMLESS",
              "RIMLESS"
            ]
          },
          "fitLabel": {
            "type": "string",
            "enum": [
              "NARROW",
              "AVERAGE",
              "WIDE",
              "EXTRA_WIDE"
            ]
          },
          "lensWidthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "lensHeightMm": {
            "type": "number",
            "minimum": 0.1
          },
          "bridgeWidthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "templeLengthMm": {
            "type": "number",
            "minimum": 0.1
          },
          "componentColors": {
            "type": "array",
            "description": "Complete replacement list containing at least one FRAME color and one LENS color.",
            "minItems": 2,
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/ProductComponentColorInput"
            }
          },
          "price": {
            "type": "number",
            "format": "float",
            "minimum": 0.01
          },
          "stockQuantity": {
            "type": "integer",
            "minimum": 0
          },
          "isActive": {
            "type": "boolean"
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductImageInput"
            }
          }
        },
        "minProperties": 1
      },
      "ReorderProductVariantsRequest": {
        "type": "object",
        "properties": {
          "productIds": {
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "required": [
          "productIds"
        ]
      },
      "ProductDraft": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "productId": {
            "type": "integer",
            "nullable": true
          },
          "action": {
            "type": "string",
            "enum": [
              "CREATE",
              "UPDATE",
              "ARCHIVE",
              "DELETE"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT"
            ]
          },
          "payload": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true
          },
          "targetName": {
            "type": "string",
            "nullable": true
          },
          "targetSku": {
            "type": "string",
            "nullable": true
          },
          "createdBy": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "productId",
          "action",
          "status",
          "targetName",
          "targetSku",
          "createdBy",
          "createdAt",
          "updatedAt"
        ]
      },
      "ProductDraftIdsRequest": {
        "type": "object",
        "properties": {
          "draftIds": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "required": [
          "draftIds"
        ]
      },
      "ProductDraftSaveRequest": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "CREATE",
              "UPDATE",
              "ARCHIVE",
              "DELETE"
            ]
          },
          "productId": {
            "type": "integer",
            "minimum": 1
          },
          "payload": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "action"
        ]
      },
      "ApplyProductDraftsResponse": {
        "type": "object",
        "properties": {
          "appliedCount": {
            "type": "integer"
          },
          "failedCount": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "draftId": {
                  "type": "integer"
                },
                "success": {
                  "type": "boolean"
                },
                "error": {
                  "type": "string"
                }
              },
              "required": [
                "draftId",
                "success"
              ]
            }
          }
        },
        "required": [
          "appliedCount",
          "failedCount",
          "results"
        ]
      },
      "ProductModelOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "modelCode": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "targetAudience": {
            "type": "string",
            "enum": [
              "MEN",
              "WOMEN",
              "UNISEX"
            ]
          },
          "specifications": {
            "$ref": "#/components/schemas/ProductSpecifications"
          },
          "sizes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductSize"
            }
          }
        },
        "required": [
          "id",
          "name",
          "modelCode",
          "targetAudience",
          "specifications",
          "sizes"
        ]
      },
      "ProductCatalogOptions": {
        "type": "object",
        "properties": {
          "colors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductColor"
            }
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductModelOption"
            }
          },
          "brands": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "frameShapes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "frameMaterials": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rimTypes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fitLabels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "colors",
          "models",
          "brands",
          "frameShapes",
          "frameMaterials",
          "rimTypes",
          "fitLabels"
        ]
      },
      "RawDiscount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "PERCENTAGE",
              "FIXED"
            ]
          },
          "value": {
            "type": "number",
            "format": "float"
          },
          "start_date": {
            "type": "string",
            "format": "date-time"
          },
          "end_date": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "productIds": {
            "type": "array",
            "description": "IDs of products assigned to this discount.",
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "value",
          "start_date",
          "end_date",
          "created_at",
          "productIds"
        ]
      },
      "AdminDiscountInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "PERCENTAGE",
              "FIXED"
            ]
          },
          "value": {
            "type": "number",
            "format": "float",
            "minimum": 0
          },
          "startDate": {
            "type": "string",
            "format": "date-time"
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "productIds": {
            "type": "array",
            "description": "Product IDs to assign to the new discount. An empty array creates an unassigned discount.",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "required": [
          "name",
          "type",
          "value",
          "startDate",
          "endDate",
          "productIds"
        ]
      },
      "AdminDiscountUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "type": {
            "type": "string",
            "enum": [
              "PERCENTAGE",
              "FIXED"
            ]
          },
          "value": {
            "type": "number",
            "format": "float",
            "minimum": 0
          },
          "endDate": {
            "type": "string",
            "format": "date-time"
          },
          "productIds": {
            "type": "array",
            "description": "Complete replacement list of product IDs assigned to the discount.",
            "uniqueItems": true,
            "items": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "minProperties": 1
      },
      "ProductComponentColorInput": {
        "type": "object",
        "properties": {
          "position": {
            "type": "string",
            "enum": [
              "FRAME",
              "LENS"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 1
          },
          "hexCode": {
            "type": "string",
            "pattern": "^#[0-9A-Fa-f]{6}$",
            "example": "#1267A5"
          }
        },
        "required": [
          "position",
          "name",
          "hexCode"
        ]
      },
      "CloudinaryUploadSignature": {
        "type": "object",
        "properties": {
          "apiKey": {
            "type": "string"
          },
          "cloudName": {
            "type": "string"
          },
          "folder": {
            "type": "string"
          },
          "signature": {
            "type": "string"
          },
          "timestamp": {
            "type": "integer"
          }
        },
        "required": [
          "apiKey",
          "cloudName",
          "folder",
          "signature",
          "timestamp"
        ]
      },
      "AddAdminByEmailRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email of an existing active registered user."
          }
        },
        "required": [
          "email"
        ]
      },
      "LoadMoreProductsResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductListItem"
            }
          },
          "hasMore": {
            "type": "boolean"
          },
          "nextOffset": {
            "type": "integer",
            "nullable": true
          },
          "totalCount": {
            "type": "integer"
          }
        },
        "required": [
          "items",
          "hasMore",
          "nextOffset",
          "totalCount"
        ]
      },
      "AddCartItemRequest": {
        "type": "object",
        "properties": {
          "quantity": {
            "type": "integer",
            "minimum": 1
          },
          "visionType": {
            "type": "string",
            "enum": [
              "NON_PRESCRIPTION",
              "DISTANCE",
              "READING",
              "PROGRESSIVE"
            ]
          },
          "prescriptionId": {
            "type": "integer",
            "minimum": 1
          },
          "lensPackageId": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "quantity"
        ]
      },
      "UpdateCartItemRequest": {
        "type": "object",
        "properties": {
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "quantity"
        ]
      },
      "MergeCartItem": {
        "type": "object",
        "properties": {
          "productId": {
            "type": "integer"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "productId",
          "quantity"
        ]
      },
      "MergeCartRequest": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MergeCartItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "CartItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "quantity": {
            "type": "integer"
          },
          "visionType": {
            "type": "string",
            "nullable": true,
            "enum": [
              "NON_PRESCRIPTION",
              "DISTANCE",
              "READING",
              "PROGRESSIVE"
            ]
          },
          "prescriptionId": {
            "type": "integer",
            "nullable": true
          },
          "lensPrice": {
            "type": "number",
            "format": "float"
          },
          "lensPackage": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/CartLensPackage"
              }
            ]
          },
          "product": {
            "$ref": "#/components/schemas/CartProductListItem"
          }
        },
        "required": [
          "id",
          "quantity",
          "visionType",
          "prescriptionId",
          "lensPrice",
          "lensPackage",
          "product"
        ]
      },
      "Cart": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "0 means no cart row exists yet."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CartItem"
            }
          },
          "totalItems": {
            "type": "integer"
          },
          "subtotal": {
            "type": "number",
            "format": "float"
          }
        },
        "required": [
          "id",
          "items",
          "totalItems",
          "subtotal"
        ]
      },
      "OrderItem": {
        "type": "object",
        "properties": {
          "unitPrice": {
            "type": "number",
            "format": "float"
          },
          "discountedUnitPrice": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "quantity": {
            "type": "integer"
          },
          "product": {
            "$ref": "#/components/schemas/OrderProductListItem"
          }
        },
        "required": [
          "unitPrice",
          "quantity",
          "product"
        ]
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "PREPARING",
              "REGISTERED",
              "READY_FOR_PICKUP",
              "PICKED_UP",
              "SHIPPED",
              "IN_TRANSIT",
              "OUT_FOR_DELIVERY",
              "DELIVERY_EXCEPTION",
              "REROUTED",
              "RETURN_IN_TRANSIT",
              "DELIVERED",
              "RETURNED",
              "LOST",
              "DAMAGED",
              "CANCELLED"
            ]
          },
          "subtotalAmount": {
            "type": "number",
            "format": "float"
          },
          "shippingAmount": {
            "type": "number",
            "format": "float"
          },
          "totalAmount": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "paymentStatus": {
            "type": "string",
            "enum": [
              "PENDING",
              "PAID",
              "FAILED",
              "REFUNDED"
            ]
          },
          "shippingAddress": {
            "$ref": "#/components/schemas/OrderShippingAddress"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderItem"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "status",
          "subtotalAmount",
          "shippingAmount",
          "totalAmount",
          "paymentStatus",
          "shippingAddress",
          "items",
          "createdAt"
        ]
      },
      "AdminKexShipment": {
        "type": "object",
        "properties": {
          "integrationStatus": {
            "type": "string"
          },
          "consignmentNumber": {
            "type": "string"
          },
          "trackingNumber": {
            "type": "string",
            "nullable": true
          },
          "providerStatusCode": {
            "type": "string",
            "nullable": true
          },
          "providerStatusDescription": {
            "type": "string",
            "nullable": true
          },
          "labelPdfUrl": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "acceptedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "integrationStatus",
          "consignmentNumber",
          "trackingNumber",
          "providerStatusCode",
          "providerStatusDescription",
          "labelPdfUrl",
          "acceptedAt"
        ]
      },
      "AdminOrderItem": {
        "allOf": [
          {
            "$ref": "#/components/schemas/OrderItem"
          },
          {
            "type": "object",
            "properties": {
              "orderItemId": {
                "type": "integer"
              },
              "packed": {
                "type": "boolean"
              }
            },
            "required": [
              "orderItemId",
              "packed"
            ]
          }
        ]
      },
      "AdminPackingWorker": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        },
        "required": [
          "id",
          "email"
        ]
      },
      "AdminPackingChecklist": {
        "type": "object",
        "properties": {
          "labelAttached": {
            "type": "boolean"
          },
          "allProductsPacked": {
            "type": "boolean"
          },
          "complete": {
            "type": "boolean"
          },
          "readyForPickupAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "packingStartedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "assignedWorker": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AdminPackingWorker"
              }
            ],
            "nullable": true
          }
        },
        "required": [
          "labelAttached",
          "allProductsPacked",
          "complete",
          "readyForPickupAt",
          "packingStartedAt",
          "assignedWorker"
        ]
      },
      "AdminOrder": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Order"
          },
          {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AdminOrderItem"
                }
              },
              "kexShipment": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/AdminKexShipment"
                  }
                ],
                "nullable": true
              },
              "packingChecklist": {
                "$ref": "#/components/schemas/AdminPackingChecklist"
              }
            },
            "required": [
              "items",
              "kexShipment",
              "packingChecklist"
            ]
          }
        ]
      },
      "RawOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "customer_id": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "PREPARING",
              "REGISTERED",
              "READY_FOR_PICKUP",
              "PICKED_UP",
              "SHIPPED",
              "IN_TRANSIT",
              "OUT_FOR_DELIVERY",
              "DELIVERY_EXCEPTION",
              "REROUTED",
              "RETURN_IN_TRANSIT",
              "DELIVERED",
              "RETURNED",
              "LOST",
              "DAMAGED",
              "CANCELLED"
            ]
          },
          "subtotal_amount": {
            "type": "number",
            "format": "float"
          },
          "shipping_amount": {
            "type": "number",
            "format": "float"
          },
          "total_amount": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "payment_status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PAID",
              "FAILED",
              "REFUNDED"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "customer_id",
          "status",
          "subtotal_amount",
          "shipping_amount",
          "total_amount",
          "payment_status",
          "created_at",
          "updated_at"
        ]
      },
      "AdminOrderListResponse": {
        "type": "object",
        "properties": {
          "orders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RawOrder"
            }
          },
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "totalOrders": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          }
        },
        "required": [
          "orders",
          "page",
          "limit",
          "totalOrders",
          "totalPages"
        ]
      },
      "AdminUpdateOrderStatusRequest": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "PREPARING",
              "REGISTERED",
              "READY_FOR_PICKUP",
              "PICKED_UP",
              "SHIPPED",
              "IN_TRANSIT",
              "OUT_FOR_DELIVERY",
              "DELIVERY_EXCEPTION",
              "REROUTED",
              "RETURN_IN_TRANSIT",
              "DELIVERED",
              "RETURNED",
              "LOST",
              "DAMAGED",
              "CANCELLED"
            ]
          }
        },
        "required": [
          "status"
        ]
      },
      "AdminPackingChecklistUpdate": {
        "type": "object",
        "description": "Updates one packing item or the label confirmation. The first update assigns the order to the authenticated worker.",
        "properties": {
          "orderItemId": {
            "type": "integer"
          },
          "packed": {
            "type": "boolean"
          },
          "labelAttached": {
            "type": "boolean"
          }
        }
      },
      "CreatePaymentIntentRequest": {
        "type": "object",
        "properties": {
          "orderId": {
            "type": "integer"
          }
        },
        "required": [
          "orderId"
        ]
      },
      "Payment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "orderId": {
            "type": "integer"
          },
          "provider": {
            "type": "string",
            "enum": [
              "STRIPE",
              "PAYPAL",
              "TRANZILA",
              "OTHER"
            ]
          },
          "method": {
            "type": "string",
            "enum": [
              "CARD",
              "PAYPAL",
              "BANK_TRANSFER",
              "OTHER"
            ]
          },
          "providerTransactionId": {
            "type": "string",
            "nullable": true
          },
          "amount": {
            "type": "number",
            "format": "float"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PAID",
              "FAILED",
              "REFUNDED"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "orderId",
          "provider",
          "method",
          "amount",
          "status",
          "createdAt"
        ]
      },
      "StripeWebhookResponse": {
        "type": "object",
        "properties": {
          "received": {
            "type": "boolean",
            "example": true
          },
          "eventType": {
            "type": "string",
            "example": "payment_intent.succeeded"
          },
          "paymentIntentId": {
            "type": "string",
            "example": "pi_123"
          },
          "orderId": {
            "type": "integer",
            "example": 42
          },
          "paymentStatus": {
            "type": "string",
            "enum": [
              "PENDING",
              "PAID",
              "FAILED",
              "REFUNDED",
              "IGNORED"
            ]
          },
          "orderStatus": {
            "type": "string",
            "enum": [
              "PREPARING",
              "REGISTERED",
              "READY_FOR_PICKUP",
              "PICKED_UP",
              "SHIPPED",
              "IN_TRANSIT",
              "OUT_FOR_DELIVERY",
              "DELIVERY_EXCEPTION",
              "REROUTED",
              "RETURN_IN_TRANSIT",
              "DELIVERED",
              "RETURNED",
              "LOST",
              "DAMAGED",
              "CANCELLED"
            ]
          },
          "message": {
            "type": "string",
            "example": "Payment succeeded"
          }
        },
        "required": [
          "received",
          "eventType",
          "paymentStatus",
          "message"
        ]
      },
      "Shipment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "order_id": {
            "type": "integer"
          },
          "tracking_number": {
            "type": "string",
            "nullable": true
          },
          "carrier": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "PREPARING",
              "REGISTERED",
              "READY_FOR_PICKUP",
              "PICKED_UP",
              "SHIPPED",
              "IN_TRANSIT",
              "OUT_FOR_DELIVERY",
              "DELIVERY_EXCEPTION",
              "REROUTED",
              "RETURN_IN_TRANSIT",
              "DELIVERED",
              "RETURNED",
              "LOST",
              "DAMAGED",
              "CANCELLED"
            ]
          },
          "shipped_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "order_id",
          "status",
          "created_at"
        ]
      }
    }
  },
  "paths": {
    "/admin/team": {
      "get": {
        "tags": [
          "Admin"
        ],
        "operationId": "getBackofficeTeam",
        "summary": "List backoffice team emails and roles",
        "description": "Requires admins.grant permission. Returns ADMIN and WORKER accounts, ordered by email.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Backoffice team",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "email",
                      "role"
                    ],
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "role": {
                        "type": "string",
                        "enum": [
                          "ADMIN",
                          "WORKER"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission denied"
          }
        }
      }
    },
    "/auth/register": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Register new customer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Customer registered successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Email is already in use",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAuthRegister",
        "description": "Register new customer."
      }
    },
    "/auth/login": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Login with email and password",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AuthRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAuthLogin",
        "description": "Login with email and password."
      }
    },
    "/auth/google": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Login or register with Google",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GoogleAuthRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Google authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "idToken is required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid Google token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAuthGoogle",
        "description": "Login or register with Google."
      }
    },
    "/auth/forgot-password": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Queue a password-reset request and return an account-neutral response",
        "description": "The request is persisted for asynchronous processing. Account lookup and Brevo delivery do not occur in the HTTP request path.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForgotPasswordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job queued; the same response is returned whether or not an active account exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid email",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAuthForgotPassword"
      }
    },
    "/auth/reset-password": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Consume a reset token and replace the customer password",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password changed and existing sessions revoked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Weak password or invalid, expired, or used token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAuthResetPassword",
        "description": "Consume a reset token and replace the customer password."
      }
    },
    "/auth/refresh": {
      "post": {
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "refreshSession": []
          }
        ],
        "summary": "Rotate the refresh session and issue a new access token",
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Protection",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session refreshed and refresh cookie rotated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, expired, revoked, or reused refresh session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Missing CSRF protection or untrusted origin"
          }
        },
        "operationId": "postAuthRefresh",
        "description": "Rotate the refresh session and issue a new access token."
      }
    },
    "/auth/logout": {
      "post": {
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "refreshSession": []
          }
        ],
        "summary": "Revoke the current refresh session",
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Protection",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Session revoked or already absent"
          }
        },
        "operationId": "postAuthLogout",
        "description": "Revoke the current refresh session."
      }
    },
    "/auth/logout-all": {
      "post": {
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Revoke all refresh sessions for the authenticated user",
        "parameters": [
          {
            "in": "header",
            "name": "X-CSRF-Protection",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All user sessions revoked"
          },
          "401": {
            "description": "Missing or invalid access token"
          }
        },
        "operationId": "postAuthLogoutAll",
        "description": "Revoke all refresh sessions for the authenticated user."
      }
    },
    "/auth/me": {
      "get": {
        "tags": [
          "Auth"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get the current active user",
        "responses": {
          "200": {
            "description": "Current active user",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getAuthMe",
        "description": "Get the current active user."
      }
    },
    "/admin/product-options": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get product models and colors for product administration",
        "responses": {
          "200": {
            "description": "Catalog options loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductCatalogOptions"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Admin access required"
          }
        },
        "operationId": "getAdminProductOptions",
        "description": "Get product models and colors for product administration."
      }
    },
    "/admin/lens-packages": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List all prescription lens packages, including inactive packages",
        "responses": {
          "200": {
            "description": "Lens packages loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AdminLensPackage"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Catalog read permission required"
          }
        },
        "operationId": "getAdminLensPackages",
        "description": "List all prescription lens packages, including inactive packages."
      },
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a prescription lens package",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminLensPackageInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lens package created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminLensPackage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid lens package request"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Catalog write permission required"
          }
        },
        "operationId": "postAdminLensPackages",
        "description": "Create a prescription lens package."
      }
    },
    "/admin/lens-packages/{id}": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update or deactivate a prescription lens package",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminLensPackageUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lens package updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminLensPackage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid lens package request"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Catalog write permission required"
          },
          "404": {
            "description": "Lens package not found"
          }
        },
        "operationId": "patchAdminLensPackagesById",
        "description": "Update or deactivate a prescription lens package."
      }
    },
    "/admin/products": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a product immediately",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminProductInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Product created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid product request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAdminProducts",
        "description": "Create a product immediately."
      }
    },
    "/admin/products/{id}": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update a product immediately",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminProductUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Product updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid product request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "patchAdminProductsById",
        "description": "Update a product immediately."
      },
      "delete": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Archive a product immediately",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product archived successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required"
          }
        },
        "operationId": "deleteAdminProductsById",
        "description": "Archive a product immediately."
      }
    },
    "/admin/uploads/signature": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create a signed Cloudinary product-image upload request",
        "description": "Returns short-lived signed parameters. The Cloudinary API secret is never returned to the browser.",
        "responses": {
          "200": {
            "description": "Signed upload parameters created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CloudinaryUploadSignature"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Admin access required"
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Cloudinary credentials are not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAdminUploadsSignature"
      }
    },
    "/admin/products/{id}/permanent": {
      "delete": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Permanently delete a product immediately",
        "description": "Products referenced by orders cannot be deleted.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product deleted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid product ID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Admin access required"
          },
          "404": {
            "description": "Product not found"
          },
          "409": {
            "description": "Product is referenced by an existing order",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "deleteAdminProductsByIdPermanent"
      }
    },
    "/admin/product-drafts": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List pending product drafts",
        "responses": {
          "200": {
            "description": "Pending drafts loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductDraft"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Catalog read permission required"
          }
        },
        "operationId": "getAdminProductDrafts",
        "description": "List pending product drafts."
      },
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Save an optional product-operation draft",
        "description": "Stores a create, update, archive, or permanent-delete operation without changing the published catalog.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductDraftSaveRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Product draft saved successfully"
          },
          "400": {
            "description": "Invalid draft action, target, or payload"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Permission required for the requested operation"
          },
          "404": {
            "description": "Product not found"
          },
          "409": {
            "description": "The product draft is currently being applied"
          }
        },
        "operationId": "postAdminProductDrafts"
      }
    },
    "/admin/product-drafts/apply": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Apply selected product drafts",
        "description": "Claims and executes selected drafts concurrently. Each result succeeds or fails independently.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductDraftIdsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Selected drafts processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplyProductDraftsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid draft IDs"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Permission required for one or more selected operations"
          },
          "409": {
            "description": "A selected draft is unavailable or already being applied"
          }
        },
        "operationId": "postAdminProductDraftsApply"
      }
    },
    "/admin/product-drafts/discard": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Discard selected product drafts",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductDraftIdsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Selected drafts discarded"
          },
          "400": {
            "description": "Invalid draft IDs"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Permission required for one or more selected operations"
          },
          "409": {
            "description": "A selected draft is unavailable"
          }
        },
        "operationId": "postAdminProductDraftsDiscard",
        "description": "Discard selected product drafts."
      }
    },
    "/admin/approval-settings": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List worker approval settings",
        "operationId": "getAdminApprovalSettings",
        "description": "Return the worker approval action catalog and effective settings for administrators.",
        "responses": {
          "200": {
            "description": "Approval action catalog with effective settings"
          },
          "403": {
            "description": "Administrator access required"
          }
        }
      },
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update worker approval settings",
        "operationId": "patchAdminApprovalSettings",
        "description": "Configure which worker actions require administrator approval.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "settings"
                ],
                "properties": {
                  "settings": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "actionKey",
                        "requiresApproval"
                      ],
                      "properties": {
                        "actionKey": {
                          "type": "string"
                        },
                        "requiresApproval": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Settings saved"
          },
          "403": {
            "description": "Administrator access required"
          }
        }
      }
    },
    "/admin/approval-requests": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "List approval requests",
        "operationId": "getAdminApprovalRequests",
        "description": "Administrators receive all requests; workers receive only requests they created.",
        "responses": {
          "200": {
            "description": "Approval request history"
          }
        }
      }
    },
    "/admin/approval-requests/unread-count": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get unread approval result count",
        "operationId": "getAdminApprovalRequestsUnreadCount",
        "description": "Return the unread approval count visible to the current administrator or worker.",
        "responses": {
          "200": {
            "description": "Unread count for the current role and user"
          }
        }
      }
    },
    "/admin/approval-requests/read": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Mark visible approval requests as read",
        "operationId": "patchAdminApprovalRequestsRead",
        "description": "Mark approval requests visible to the current user as read.",
        "responses": {
          "204": {
            "description": "Requests marked as read"
          }
        }
      }
    },
    "/admin/approval-requests/{id}/approve": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Approve and execute a pending request",
        "operationId": "postAdminApprovalRequestsByIdApprove",
        "description": "Allow an administrator to approve and execute a pending worker action.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Request approved and executed"
          },
          "403": {
            "description": "Administrator access required"
          },
          "409": {
            "description": "Request already reviewed"
          }
        }
      }
    },
    "/admin/approval-requests/{id}/cancel": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Cancel the current worker's pending request",
        "operationId": "postAdminApprovalRequestsByIdCancel",
        "description": "Cancel a pending approval request owned by the current worker.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Request cancelled"
          },
          "403": {
            "description": "The request belongs to another worker"
          },
          "409": {
            "description": "Request is no longer pending"
          }
        }
      }
    },
    "/admin/approval-requests/{id}/reject": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Reject a pending request",
        "operationId": "postAdminApprovalRequestsByIdReject",
        "description": "Allow an administrator to reject a pending worker action with an optional reason.",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rejectionReason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request rejected"
          },
          "403": {
            "description": "Administrator access required"
          },
          "409": {
            "description": "Request already reviewed"
          }
        }
      }
    },
    "/admin/admins": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Grant admin access by email",
        "description": "Changes an existing active registered user's role to ADMIN.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddAdminByEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Admin access granted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid email, or the user is inactive",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Admin access required"
          },
          "404": {
            "description": "No registered user found with this email"
          },
          "409": {
            "description": "User is already an admin"
          }
        },
        "operationId": "postAdminAdmins"
      }
    },
    "/admin/workers": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Grant worker access by email",
        "description": "Changes an existing active customer user's role to WORKER. User-management permission is required.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddAdminByEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Worker access granted successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid email, or the user is inactive"
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "User-management permission required"
          },
          "404": {
            "description": "No registered user found with this email"
          },
          "409": {
            "description": "User is already a worker or is an admin"
          }
        },
        "operationId": "postAdminWorkers"
      }
    },
    "/admin/discounts": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create discount",
        "description": "Admin-only endpoint for creating a discount and assigning products to it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminDiscountInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Discount created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid discount request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postAdminDiscounts"
      },
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get discounts",
        "description": "Admin-only endpoint for listing discounts and their assigned product IDs.",
        "responses": {
          "200": {
            "description": "Discounts loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RawDiscount"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getAdminDiscounts"
      }
    },
    "/admin/discounts/{id}": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update discount",
        "description": "Admin-only endpoint for updating discount details and replacing its assigned product list.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminDiscountUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Discount updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid discount request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Discount not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "patchAdminDiscountsById"
      }
    },
    "/admin/orders": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get all orders",
        "description": "Admin-only endpoint for listing orders with pagination and optional filters.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "PREPARING",
                "REGISTERED",
                "READY_FOR_PICKUP",
                "PICKED_UP",
                "SHIPPED",
                "IN_TRANSIT",
                "OUT_FOR_DELIVERY",
                "DELIVERY_EXCEPTION",
                "REROUTED",
                "RETURN_IN_TRANSIT",
                "DELIVERED",
                "RETURNED",
                "LOST",
                "DAMAGED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "paymentStatus",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "PAID",
                "FAILED",
                "REFUNDED"
              ]
            }
          },
          {
            "name": "customerId",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Orders loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminOrderListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getAdminOrders"
      }
    },
    "/admin/orders/{id}": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get order by id",
        "description": "Admin-only endpoint for reading a specific order.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminOrder"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getAdminOrdersById"
      }
    },
    "/admin/orders/{id}/shipping-label": {
      "get": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Preview an order shipping label",
        "description": "Retrieves the temporary KEX label through the authenticated API and serves it inline without storing the PDF.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Shipping label PDF",
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                },
                "description": "Inline filename for the PDF viewer."
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Order read permission required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Shipping label not available",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "KEX label retrieval failed or the temporary link expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getAdminOrderShippingLabel"
      }
    },
    "/admin/orders/{id}/packing-checklist": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update an order packing checklist",
        "description": "Updates the current checklist state. The first checklist update assigns the order to that worker and creates one assignment audit entry; later checkbox updates do not create audit entries.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminPackingChecklistUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated order and packing checklist",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminOrder"
                }
              }
            }
          },
          "400": {
            "description": "Invalid checklist update",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Order status update permission required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Order, shipment, or order item not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Shipment is not eligible or is assigned to another worker",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "updateAdminOrderPackingChecklist"
      }
    },
    "/admin/orders/{id}/ready-for-pickup": {
      "post": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Mark a packed order ready for pickup",
        "description": "Moves a registered shipment to the internal ready-for-pickup status after every item is packed and its label is attached.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order marked ready for pickup",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminOrder"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Order status update permission required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Order or shipment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Checklist incomplete, shipment ineligible, or assigned to another worker",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "markAdminOrderReadyForPickup"
      }
    },
    "/admin/orders/{id}/status": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update order status",
        "description": "Admin-only endpoint for changing an order status.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminUpdateOrderStatusRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order status updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order status request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Admin access required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "patchAdminOrdersByIdStatus"
      }
    },
    "/products": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get products with filters, sorting and load more pagination",
        "description": "Returns active products only. The server returns up to 12 products per request.",
        "parameters": [
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "SUNGLASSES",
                "EYEGLASSES"
              ],
              "default": "SUNGLASSES"
            }
          },
          {
            "name": "targetAudience",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "MEN",
                "WOMEN",
                "UNISEX"
              ]
            }
          },
          {
            "name": "rimType",
            "in": "query",
            "description": "Comma-separated frame rim types",
            "schema": {
              "type": "string",
              "example": "FULL_RIM,RIMLESS"
            }
          },
          {
            "name": "minPrice",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "maxPrice",
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "onSale",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "newArrivals",
            "in": "query",
            "description": "When true, returns only products created during the previous 30 days",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "inStockOnly",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "price",
                "name",
                "popularity"
              ],
              "default": "createdAt"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Products loaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadMoreProductsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getProducts"
      }
    },
    "/products/{id}": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get product details by id",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid product id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getProductsById",
        "description": "Get product details by id."
      }
    },
    "/favorites": {
      "get": {
        "tags": [
          "Favorites"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get favorite products",
        "responses": {
          "200": {
            "description": "Favorite products",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductListItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getFavorites",
        "description": "Get favorite products."
      }
    },
    "/favorites/{productId}": {
      "post": {
        "tags": [
          "Favorites"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Add product to favorites",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Added to favorites",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postFavoritesByProductId",
        "description": "Add product to favorites."
      },
      "delete": {
        "tags": [
          "Favorites"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Remove product from favorites",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Removed from favorites",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found or not in favorites",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "deleteFavoritesByProductId",
        "description": "Remove product from favorites."
      }
    },
    "/cart": {
      "get": {
        "tags": [
          "Cart"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get current authenticated customer's cart",
        "responses": {
          "200": {
            "description": "Current cart. If no cart row exists yet, id is 0 and items is empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Cart"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getCart",
        "description": "Get current authenticated customer's cart."
      }
    },
    "/cart/merge": {
      "post": {
        "tags": [
          "Cart"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Merge localStorage guest cart into authenticated customer's cart",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergeCartRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cart merged successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid merge request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postCartMerge",
        "description": "Merge localStorage guest cart into authenticated customer's cart."
      }
    },
    "/cart/items/{productId}": {
      "post": {
        "tags": [
          "Cart"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Add product to cart",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddCartItemRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Item added to cart successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid cart item request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Product not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postCartItemsByProductId",
        "description": "Add product to cart."
      }
    },
    "/admin/product-models/{modelId}/variant-order": {
      "patch": {
        "tags": [
          "Admin"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Reorder all variants within one product model",
        "description": "The first active variant becomes the model's storefront default. Every supplied product must belong to the requested model.",
        "parameters": [
          {
            "name": "modelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReorderProductVariantsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Variant order updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order or variants do not all belong to the model",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token"
          },
          "403": {
            "description": "Catalog write permission required"
          }
        },
        "operationId": "patchAdminProductModelsByModelIdVariantOrder"
      }
    },
    "/products/filter-options": {
      "get": {
        "tags": [
          "Products"
        ],
        "summary": "Get filter options for one product category",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "SUNGLASSES",
                "EYEGLASSES"
              ],
              "default": "SUNGLASSES"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Category-specific catalog filter options",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid category",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getProductsFilterOptions",
        "description": "Get filter options for one product category."
      }
    },
    "/lens-packages": {
      "get": {
        "tags": [
          "Lens Packages"
        ],
        "summary": "Get active lens packages in display order",
        "responses": {
          "200": {
            "description": "Active localized lens packages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LensPackage"
                  }
                }
              }
            }
          }
        },
        "operationId": "getLensPackages",
        "description": "Get active lens packages in display order."
      }
    },
    "/prescriptions": {
      "post": {
        "tags": [
          "Prescriptions"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Save a new immutable online prescription for the customer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePrescriptionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Prescription created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Prescription"
                }
              }
            }
          },
          "400": {
            "description": "Invalid prescription values",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postPrescriptions",
        "description": "Save a new immutable online prescription for the customer."
      }
    },
    "/cart/items/{itemId}": {
      "patch": {
        "tags": [
          "Cart"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Update a specific cart line quantity",
        "parameters": [
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCartItemRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cart item updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid cart update request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Cart item not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "patchCartItemsByItemId",
        "description": "Update a specific cart line quantity."
      },
      "delete": {
        "tags": [
          "Cart"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Remove a specific cart line",
        "parameters": [
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Item removed from cart",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Cart item not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "deleteCartItemsByItemId",
        "description": "Remove a specific cart line."
      }
    },
    "/locations/thailand/provinces": {
      "get": {
        "tags": [
          "Thai Locations"
        ],
        "summary": "List active Thai provinces",
        "responses": {
          "200": {
            "description": "Province options localized using the request locale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ThaiLocationOption"
                  }
                }
              }
            }
          }
        },
        "operationId": "getThaiProvinces",
        "description": "Return the active Thai provinces in the locale selected for the request."
      }
    },
    "/locations/thailand/provinces/{provinceCode}/districts": {
      "get": {
        "tags": [
          "Thai Locations"
        ],
        "summary": "List active districts in a Thai province",
        "parameters": [
          {
            "name": "provinceCode",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{2}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "District options localized using the request locale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ThaiLocationOption"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid province code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getThaiDistricts",
        "description": "Return the active districts that belong to the selected Thai province."
      }
    },
    "/locations/thailand/districts/{districtCode}/subdistricts": {
      "get": {
        "tags": [
          "Thai Locations"
        ],
        "summary": "List active subdistricts in a Thai district",
        "parameters": [
          {
            "name": "districtCode",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{4}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subdistrict options localized using the request locale",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ThaiSubdistrictOption"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid district code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getThaiSubdistricts",
        "description": "Return the active subdistricts that belong to the selected Thai district, including their valid postal codes."
      }
    },
    "/orders": {
      "get": {
        "tags": [
          "Orders"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get raw customer orders",
        "responses": {
          "200": {
            "description": "Customer orders in raw database shape",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RawOrder"
                  }
                }
              }
            }
          }
        },
        "operationId": "getOrders",
        "description": "Get raw customer orders."
      },
      "post": {
        "tags": [
          "Orders"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create order from current cart with shipping address snapshot",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddressInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Order created in pending payment state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "400": {
            "description": "Invalid order request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postOrders",
        "description": "Create order from current cart with shipping address snapshot."
      }
    },
    "/orders/last-address": {
      "get": {
        "tags": [
          "Orders"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get the raw shipping address from the customer's most recent order",
        "responses": {
          "200": {
            "description": "Last used shipping address or null",
            "content": {
              "application/json": {
                "schema": {
                  "nullable": true,
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/RawOrderAddress"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getOrdersLastAddress",
        "description": "Get the raw shipping address from the customer's most recent order."
      }
    },
    "/orders/last-prescription": {
      "get": {
        "tags": [
          "Orders",
          "Prescriptions"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get the customer's most recently saved prescription",
        "responses": {
          "200": {
            "description": "Latest saved prescription snapshot or null",
            "content": {
              "application/json": {
                "schema": {
                  "nullable": true,
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Prescription"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getOrdersLastPrescription",
        "description": "Get the customer's most recently saved prescription."
      }
    },
    "/orders/{id}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Get order details by id",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Order details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getOrdersById",
        "description": "Get order details by id."
      }
    },
    "/payments/create-intent": {
      "post": {
        "tags": [
          "Payments"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Create payment intent for order",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePaymentIntentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Payment intent created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "clientSecret": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "clientSecret"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payment intent request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postPaymentsCreateIntent",
        "description": "Create payment intent for order."
      }
    },
    "/payments/webhook": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Stripe webhook endpoint",
        "responses": {
          "200": {
            "description": "Webhook processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StripeWebhookResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid webhook payload or Stripe signature",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "postPaymentsWebhook",
        "description": "Stripe webhook endpoint."
      }
    },
    "/shipments/order/{orderId}": {
      "get": {
        "tags": [
          "Shipments"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "summary": "Get shipment by order id",
        "parameters": [
          {
            "name": "orderId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Shipment details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Shipment"
                }
              }
            }
          },
          "404": {
            "description": "Shipment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "operationId": "getShipmentsOrderByOrderId",
        "description": "Get shipment by order id."
      }
    },
    "/homepage": {
      "get": {
        "tags": [
          "Homepage"
        ],
        "summary": "Get published homepage content",
        "description": "Returns localized banners, managed section settings, localized FAQs, and catalog-backed homepage merchandising, including category tiles, featured brands, active promotion details, and prescription journey availability.",
        "operationId": "getHomepage",
        "parameters": [
          {
            "name": "Accept-Language",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Preferred locale. English and Thai are supported."
          }
        ],
        "responses": {
          "200": {
            "description": "Published homepage content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "banners": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "popup": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "First active scheduled POPUP by display order, or null. Separate from HERO banners."
                    },
                    "categoryTiles": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "sections": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "faqs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "question": {
                            "type": "string"
                          },
                          "answer": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "question",
                          "answer"
                        ]
                      }
                    }
                  },
                  "required": [
                    "banners",
                    "categoryTiles",
                    "sections",
                    "faqs"
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}
