{
  "openapi": "3.0.3",
  "info": {
    "title": "b2b API",
    "description": "Authentication, user management, and repository time tracking API\n\n## Filtering\nAll filter parameters support the following operators by adding a suffix to the parameter name:\n\n### Comparison Operators\n\n| Suffix | Operator | Example | Description |\n|--------|----------|---------|-------------|\n| `_eq` | = | `product_id_eq=12` | Equals |\n| `_neq` | != | `active_neq=0` | Not equals |\n| `_gt` | > | `price_gt=100` | Greater than |\n| `_gte` | >= | `price_gte=10` | Greater than or equal |\n| `_lt` | < | `price_lt=500` | Less than |\n| `_lte` | <= | `price_lte=500` | Less than or equal |\n| `_in` | IN | `product_id_in=1,2,3,4` | IN clause (comma-separated values) |\n\n### Special Filters\n\n| Filter | Example | Description |\n|--------|---------|-------------|\n| `~` prefix | `name=~gold` | LIKE search - case-insensitive partial match on string values |\n| `[min,max]` | `price=[100,500]` | BETWEEN range - filters values between min and max (inclusive) |\n| `sort` | `sort=price,desc` | ORDER BY clause - field name and direction (asc/desc, default: desc) |\n| `p` | `p=1` | Page number - 1-based pagination (default: 1) |\n| `elems` | `elems=30` | Elements per page - results per page (max: 100, default: 30) |\n\n### Available Fields for Filtering\n\n**Products (`/api/v1/restricted/list-products/get-listing`):**\n\n| Field | Type | Example |\n|-------|------|---------|\n| `product_id` | integer | `product_id_eq=12`, `product_id_in=1,2,3` |\n| `name` | string | `name=~gold` (LIKE search) |\n| `reference` | string | `reference=ABC123` |\n| `category_name` | string | `category_name=~electronics` |\n| `id_category` | integer | `id_category_eq=5`, `id_category_in=1,2,3` |\n| `quantity` | integer | `quantity_gt=0` |\n| `variants_number` | integer | `variants_number_gte=1` |",
    "version": "1.0.0",
    "contact": {
      "name": "API Support",
      "email": "support@example.com"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "Development server on same host"
    }
  ],
  "tags": [
    {
      "name": "Health",
      "description": "Health check endpoints"
    },
    {
      "name": "Auth",
      "description": "Authentication endpoints (under /api/v1/public/auth)"
    },
    {
      "name": "Languages",
      "description": "Language and translation endpoints"
    },
    {
      "name": "Products",
      "description": "Product listing and description endpoints (under /api/v1/restricted, requires authentication)"
    },
    {
      "name": "Product Translation",
      "description": "Product description management and translation endpoints (under /api/v1/restricted/product-translation, requires authentication)"
    },
    {
      "name": "Menu",
      "description": "Menu and routing endpoints (under /api/v1/restricted/menu, requires authentication)"
    },
    {
      "name": "Search",
      "description": "MeiliSearch endpoints (under /api/v1/restricted/search, requires authentication)"
    },
    {
      "name": "Locale",
      "description": "Locale selection endpoints (under /api/v1/restricted/langs-and-countries, requires authentication)"
    },
    {
      "name": "Settings",
      "description": "Application settings and configuration endpoints"
    },
    {
      "name": "Carts",
      "description": "Shopping cart management endpoints (under /api/v1/restricted/carts, requires authentication)"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": ["Health"],
        "summary": "Health check",
        "description": "Returns the health status of the application",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "ok"
                    },
                    "app": {
                      "type": "string",
                      "example": "b2b"
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.0"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/langs": {
      "get": {
        "tags": ["Languages"],
        "summary": "Get active languages",
        "description": "Returns a list of all active languages",
        "operationId": "getLanguages",
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Language"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/translations": {
      "get": {
        "tags": ["Languages"],
        "summary": "Get translations",
        "description": "Returns translations from cache. Supports filtering by lang_id, scope, and components.",
        "operationId": "getTranslations",
        "parameters": [
          {
            "name": "lang_id",
            "in": "query",
            "description": "Filter by language ID",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "description": "Filter by scope (e.g., 'be', 'frontend')",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "components",
            "in": "query",
            "description": "Filter by component name",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "translations": {
                      "type": "object",
                      "description": "Translation data keyed by language ID, scope, component, and key"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/translations/reload": {
      "get": {
        "tags": ["Languages"],
        "summary": "Reload translations",
        "description": "Reloads translations from the database into the cache",
        "operationId": "reloadTranslations",
        "responses": {
          "200": {
            "description": "Translations reloaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "success"
                    },
                    "message": {
                      "type": "string",
                      "example": "Translations reloaded successfully"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Failed to reload translations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/login": {
      "post": {
        "tags": ["Auth"],
        "summary": "User login",
        "description": "Authenticate a user with email and password. Sets HTTPOnly cookies (access_token, refresh_token, is_authenticated) on success.",
        "operationId": "login",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            },
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "HTTPOnly cookies: access_token, refresh_token (opaque), is_authenticated (non-HTTPOnly flag)"
              }
            }
          },
          "400": {
            "description": "Invalid request body or missing fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account inactive or email not verified",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/register": {
      "post": {
        "tags": ["Auth"],
        "summary": "User registration",
        "description": "Register a new user account. Sends a verification email. first_name and last_name are required.",
        "operationId": "register",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Registration successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "registration successful, please verify your email"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, missing required fields, or invalid password format",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Email already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/complete-registration": {
      "post": {
        "tags": ["Auth"],
        "summary": "Complete registration",
        "description": "Complete registration after email verification using the token sent by email. Sets auth cookies on success.",
        "operationId": "completeRegistration",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteRegistrationRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Registration completed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            },
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "HTTPOnly cookies: access_token, refresh_token, is_authenticated"
              }
            }
          },
          "400": {
            "description": "Invalid or expired token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/forgot-password": {
      "post": {
        "tags": ["Auth"],
        "summary": "Request password reset",
        "description": "Request a password reset email. Always returns success to prevent email enumeration.",
        "operationId": "forgotPassword",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email"],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "User's email address"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset email sent if account exists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "if an account with that email exists, a password reset link has been sent"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request or missing email",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/reset-password": {
      "post": {
        "tags": ["Auth"],
        "summary": "Reset password",
        "description": "Reset password using reset token from email. Also revokes all existing refresh tokens for the user.",
        "operationId": "resetPassword",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "password reset successfully"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid or expired token, or invalid password format",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/logout": {
      "post": {
        "tags": ["Auth"],
        "summary": "User logout",
        "description": "Revokes the refresh token from the database and clears all authentication cookies.",
        "operationId": "logout",
        "responses": {
          "200": {
            "description": "Logout successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "logged out successfully"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/refresh": {
      "post": {
        "tags": ["Auth"],
        "summary": "Refresh access token",
        "description": "Get a new access token using the refresh token. The refresh token is read from the HTTPOnly cookie first, then from the request body as fallback. Rotates the refresh token on success.",
        "operationId": "refreshToken",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refresh_token": {
                    "type": "string",
                    "description": "Opaque refresh token (fallback if cookie not available)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token refreshed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            },
            "headers": {
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "Rotated HTTPOnly cookies: access_token, refresh_token, is_authenticated"
              }
            }
          },
          "400": {
            "description": "Refresh token required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired refresh token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/search/settings": {
      "post": {
        "tags": ["Search"],
        "summary": "Get MeiliSearch settings",
        "description": "Returns MeiliSearch index configuration and settings. Requires authentication.",
        "operationId": "getMeiliSearchSettings",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Settings retrieved successfully"
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/me": {
      "get": {
        "tags": ["Auth"],
        "summary": "Get current user",
        "description": "Returns the currently authenticated user's session information. Requires authentication via cookie.",
        "operationId": "getMe",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Current user info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/UserSession"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/update-choice": {
      "post": {
        "tags": ["Auth"],
        "summary": "Update JWT token choice",
        "description": "Updates the user's JWT token preference or refreshes the token. Requires authentication.",
        "operationId": "updateChoice",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Token choice updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/google": {
      "get": {
        "tags": ["Auth"],
        "summary": "Google OAuth2 login",
        "description": "Redirects the user to Google's OAuth2 consent page. Sets a short-lived oauth_state cookie for CSRF protection.",
        "operationId": "googleLogin",
        "responses": {
          "302": {
            "description": "Redirect to Google OAuth2 consent page",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "description": "Google OAuth2 authorization URL"
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "HTTPOnly oauth_state cookie for CSRF protection (10 min expiry)"
              }
            }
          },
          "500": {
            "description": "Failed to generate OAuth state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/auth/google/callback": {
      "get": {
        "tags": ["Auth"],
        "summary": "Google OAuth2 callback",
        "description": "Handles the OAuth2 callback from Google. Validates state, exchanges code for tokens, creates or updates user, sets auth cookies, and redirects to the app.",
        "operationId": "googleCallback",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "description": "Authorization code from Google",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "state",
            "in": "query",
            "description": "State token for CSRF validation",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to app after successful authentication",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "description": "Redirect to /{lang} (user's preferred language)"
              },
              "Set-Cookie": {
                "schema": {
                  "type": "string"
                },
                "description": "HTTPOnly cookies: access_token, refresh_token, is_authenticated"
              }
            }
          },
          "400": {
            "description": "Invalid state (CSRF) or missing authorization code",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Google OAuth callback processing error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/settings": {
      "get": {
        "tags": ["Settings"],
        "summary": "Get application settings",
        "description": "Returns public application settings and configuration",
        "operationId": "getSettings",
        "responses": {
          "200": {
            "description": "Settings retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/list-products/get-listing": {
      "get": {
        "tags": ["Products"],
        "summary": "Get product listing",
        "description": "Returns a paginated list of products with their basic information. Supports filtering via query parameters with operators (e.g., product_id_eq=12, name=~wałek, quantity_gt=0). Use sort parameter for ordering. Requires authentication.\n\n### Filterable Fields\n- `product_id` - Product ID (integer)\n- `name` - Product name (string, supports LIKE with ~ prefix)\n- `reference` - Product reference (string)\n- `category_name` - Category name (string, supports LIKE with ~ prefix)\n- `id_category` - Category ID (integer)\n- `quantity` - Stock quantity (integer)\n- `variants_number` - Number of variants (integer)\n\n### Example Requests\n```\nGET /api/v1/restricted/list-products/get-listing?product_id_eq=12\nGET /api/v1/restricted/list-products/get-listing?name=~wałek&sort=price,asc\nGET /api/v1/restricted/list-products/get-listing?quantity_gt=0&elems=50&p=2\n```",
        "operationId": "getProductListing",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "p",
            "in": "query",
            "description": "Page number (1-based, default: 1)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "elems",
            "in": "query",
            "description": "Number of items per page (max: 100, default: 30)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sort order: field,direction (direction: asc/desc, default: desc). Sortable fields: product_id, name, reference, category_name, id_category, quantity, variants_number",
            "required": false,
            "schema": {
              "type": "string",
              "example": "product_id,desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product listing retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/product-translation/get-product-description": {
      "get": {
        "tags": ["Product Translation"],
        "summary": "Get product description",
        "description": "Returns the product description for a given product ID and language. Requires authentication.",
        "operationId": "getProductDescription",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "productID",
            "in": "query",
            "description": "Product ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          },
          {
            "name": "productLangID",
            "in": "query",
            "description": "Language ID for the product description",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product description retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/product-translation/save-product-description": {
      "post": {
        "tags": ["Product Translation"],
        "summary": "Save product description",
        "description": "Saves the product description for a given product ID in the specified language. Requires authentication.",
        "operationId": "saveProductDescription",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "productID",
            "in": "query",
            "description": "Product ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          },
          {
            "name": "productLangID",
            "in": "query",
            "description": "Language ID for the product description",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductDescriptionUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Product description saved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters or body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/product-translation/translate-product-description": {
      "get": {
        "tags": ["Product Translation"],
        "summary": "Translate product description",
        "description": "Translates the product description from one language to another using AI (OpenAI or Google). Requires authentication.",
        "operationId": "translateProductDescription",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "productID",
            "in": "query",
            "description": "Product ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          },
          {
            "name": "productFromLangID",
            "in": "query",
            "description": "Source language ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          },
          {
            "name": "productToLangID",
            "in": "query",
            "description": "Target language ID",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "uint"
            }
          },
          {
            "name": "model",
            "in": "query",
            "description": "AI model to use for translation (OpenAI or Google)",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["OpenAI", "Google"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product description translated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/menu/get-menu": {
      "get": {
        "tags": ["Menu"],
        "summary": "Get menu structure",
        "description": "Returns the menu structure for the current language. Requires authentication.",
        "operationId": "getMenu",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Menu retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/menu/get-routes": {
      "get": {
        "tags": ["Menu"],
        "summary": "Get routes",
        "description": "Returns the routing structure for the current language.",
        "operationId": "getRoutes",
        "responses": {
          "200": {
            "description": "Routes retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/menu/get-top-menu": {
      "get": {
        "tags": ["Menu"],
        "summary": "Get top menu",
        "description": "Returns the top-level menu items for the current language. Requires authentication.",
        "operationId": "getTopMenu",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Top menu retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/search/search": {
      "post": {
        "tags": ["Search"],
        "summary": "Search products",
        "description": "Searches products using MeiliSearch. Requires authentication. Request body should contain MeiliSearch search parameters.",
        "operationId": "searchProducts",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "MeiliSearch search parameters (query, limit, filter, etc.)"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results retrieved successfully"
          },
          "400": {
            "description": "Invalid request body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/search/create-index": {
      "get": {
        "tags": ["Search"],
        "summary": "Create search index",
        "description": "Creates a MeiliSearch index for products. Must be removed before proper release.",
        "operationId": "createSearchIndex",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Index created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/langs-and-countries/get-languages": {
      "get": {
        "tags": ["Locale"],
        "summary": "Get available languages",
        "description": "Returns a list of available languages for the application. Requires authentication.",
        "operationId": "getAvailableLanguages",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Languages retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/langs-and-countries/get-countries": {
      "get": {
        "tags": ["Locale"],
        "summary": "Get countries and currencies",
        "description": "Returns a list of countries with their associated currencies. Requires authentication.",
        "operationId": "getCountriesAndCurrencies",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Countries and currencies retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/carts/add-new-cart": {
      "get": {
        "tags": ["Carts"],
        "summary": "Create a new cart",
        "description": "Creates a new shopping cart for the authenticated user. Requires authentication.",
        "operationId": "addNewCart",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Cart created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/carts/change-cart-name": {
      "get": {
        "tags": ["Carts"],
        "summary": "Change cart name",
        "description": "Updates the name of an existing cart. Requires authentication.",
        "operationId": "changeCartName",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cart_id",
            "in": "query",
            "description": "ID of the cart to rename",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "new_name",
            "in": "query",
            "description": "New name for the cart",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cart name updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/carts/retrieve-carts-info": {
      "get": {
        "tags": ["Carts"],
        "summary": "Retrieve all carts info",
        "description": "Returns information about all carts belonging to the authenticated user. Requires authentication.",
        "operationId": "retrieveCartsInfo",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Carts info retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/carts/retrieve-cart": {
      "get": {
        "tags": ["Carts"],
        "summary": "Retrieve cart details",
        "description": "Returns detailed contents of a specific cart. Requires authentication.",
        "operationId": "retrieveCart",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cart_id",
            "in": "query",
            "description": "ID of the cart to retrieve",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cart retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/restricted/carts/add-product-to-cart": {
      "get": {
        "tags": ["Carts"],
        "summary": "Add product to cart",
        "description": "Adds a product to the specified cart. Requires authentication.",
        "operationId": "addProductToCart",
        "security": [
          {
            "CookieAuth": [],
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "cart_id",
            "in": "query",
            "description": "ID of the cart to add product to",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "product_id",
            "in": "query",
            "description": "ID of the product to add",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "product_attribute_id",
            "in": "query",
            "description": "ID of the product attribute (optional, for product variants)",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "amount",
            "in": "query",
            "description": "Quantity to add",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product added to cart successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "LoginRequest": {
        "type": "object",
        "required": ["email", "password"],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "User's email address"
          },
          "password": {
            "type": "string",
            "format": "password",
            "description": "User's password"
          }
        }
      },
      "RegisterRequest": {
        "type": "object",
        "required": [
          "email",
          "password",
          "confirm_password",
          "first_name",
          "last_name"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "User's email address"
          },
          "password": {
            "type": "string",
            "format": "password",
            "description": "User's password (must meet complexity requirements: min 8 chars, uppercase, lowercase, digit)"
          },
          "confirm_password": {
            "type": "string",
            "format": "password",
            "description": "Password confirmation"
          },
          "first_name": {
            "type": "string",
            "description": "User's first name (required)"
          },
          "last_name": {
            "type": "string",
            "description": "User's last name (required)"
          },
          "lang": {
            "type": "string",
            "description": "User's preferred language ISO code (e.g., 'en', 'pl', 'cs')"
          }
        }
      },
      "CompleteRegistrationRequest": {
        "type": "object",
        "required": ["token"],
        "properties": {
          "token": {
            "type": "string",
            "description": "Email verification token received via email"
          }
        }
      },
      "ResetPasswordRequest": {
        "type": "object",
        "required": ["token", "password"],
        "properties": {
          "token": {
            "type": "string",
            "description": "Password reset token received via email"
          },
          "password": {
            "type": "string",
            "format": "password",
            "description": "New password (must meet complexity requirements)"
          }
        }
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "description": "JWT access token"
          },
          "token_type": {
            "type": "string",
            "example": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Access token expiration in seconds"
          },
          "user": {
            "$ref": "#/components/schemas/UserSession"
          }
        }
      },
      "UserSession": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "integer",
            "format": "uint",
            "description": "User ID"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "username": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": ["user", "admin"],
            "description": "User role"
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "lang": {
            "type": "string",
            "description": "User's preferred language ISO code (e.g., 'en', 'pl', 'cs')"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Translated error message"
          }
        }
      },
      "ApiResponse": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "description": "Response message"
          },
          "items": {
            "type": "object",
            "description": "Response data"
          },
          "count": {
            "type": "integer",
            "description": "Number of items returned"
          }
        }
      },
      "ProductDescriptionUpdate": {
        "type": "object",
        "description": "Map of fields to update for product description",
        "additionalProperties": {
          "type": "string"
        },
        "example": {
          "name": "Product Name",
          "description": "<p>Product description in HTML</p>",
          "description_short": "<p>Short description</p>",
          "meta_title": "Meta Title",
          "meta_description": "Meta description text",
          "available_now": "In Stock",
          "available_later": "Out of Stock",
          "usage": "<p>Usage instructions</p>"
        }
      },
      "ProductDescription": {
        "type": "object",
        "description": "Product description in a specific language",
        "properties": {
          "product_id": {
            "type": "integer",
            "format": "uint",
            "description": "Product ID"
          },
          "shop_id": {
            "type": "integer",
            "format": "uint",
            "description": "Shop ID"
          },
          "lang_id": {
            "type": "integer",
            "format": "uint",
            "description": "Language ID"
          },
          "name": {
            "type": "string",
            "description": "Product name"
          },
          "description": {
            "type": "string",
            "description": "Full product description (HTML)"
          },
          "description_short": {
            "type": "string",
            "description": "Short product description (HTML)"
          },
          "link_rewrite": {
            "type": "string",
            "description": "URL-friendly slug"
          },
          "meta_description": {
            "type": "string",
            "description": "Meta description"
          },
          "meta_keywords": {
            "type": "string",
            "description": "Meta keywords"
          },
          "meta_title": {
            "type": "string",
            "description": "Meta title"
          },
          "available_now": {
            "type": "string",
            "description": "Text shown when item is in stock"
          },
          "available_later": {
            "type": "string",
            "description": "Text shown when item is out of stock"
          },
          "delivery_in_stock": {
            "type": "string",
            "description": "Delivery in stock text"
          },
          "delivery_out_stock": {
            "type": "string",
            "description": "Delivery out of stock text"
          },
          "usage": {
            "type": "string",
            "description": "Usage instructions (HTML)"
          }
        }
      },
      "Country": {
        "type": "object",
        "description": "Country with its currency",
        "properties": {
          "id": {
            "type": "integer",
            "format": "uint",
            "description": "Country ID"
          },
          "name": {
            "type": "string",
            "description": "Country name"
          },
          "flag": {
            "type": "string",
            "description": "Flag emoji or code"
          },
          "currency_id": {
            "type": "integer",
            "format": "uint",
            "description": "Currency ID"
          },
          "currency_iso_code": {
            "type": "string",
            "description": "Currency ISO code (e.g., EUR, USD)"
          },
          "currency_name": {
            "type": "string",
            "description": "Currency name"
          }
        }
      },
      "MenuItem": {
        "type": "object",
        "description": "Menu item structure",
        "properties": {
          "category_id": {
            "type": "integer",
            "format": "uint",
            "description": "Category ID"
          },
          "label": {
            "type": "string",
            "description": "Menu item label"
          },
          "params": {
            "$ref": "#/components/schemas/MenuItemParams"
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MenuItem"
            },
            "description": "Child menu items"
          }
        }
      },
      "MenuItemParams": {
        "type": "object",
        "properties": {
          "category_id": {
            "type": "integer",
            "format": "uint"
          },
          "link_rewrite": {
            "type": "string"
          },
          "locale": {
            "type": "string"
          }
        }
      },
      "Route": {
        "type": "object",
        "description": "Application route",
        "properties": {
          "id": {
            "type": "integer",
            "format": "uint",
            "description": "Route ID"
          },
          "name": {
            "type": "string",
            "description": "Route name"
          },
          "path": {
            "type": "string",
            "description": "Route path"
          },
          "component": {
            "type": "string",
            "description": "Vue component path"
          },
          "layout": {
            "type": "string",
            "description": "Layout type"
          },
          "meta": {
            "type": "object",
            "description": "Route metadata"
          },
          "is_active": {
            "type": "boolean",
            "description": "Whether the route is active"
          },
          "sort_order": {
            "type": "integer",
            "description": "Sort order"
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Route"
            },
            "description": "Child routes"
          }
        }
      },
      "MeiliSearchResult": {
        "type": "object",
        "description": "MeiliSearch product result",
        "properties": {
          "id_product": {
            "type": "integer",
            "format": "uint",
            "description": "Product ID"
          },
          "name": {
            "type": "string",
            "description": "Product name"
          },
          "active": {
            "type": "integer",
            "description": "Active status"
          },
          "price": {
            "type": "number",
            "format": "double",
            "description": "Product price"
          },
          "description": {
            "type": "string",
            "description": "Product description"
          },
          "description_short": {
            "type": "string",
            "description": "Short description"
          },
          "reference": {
            "type": "string",
            "description": "Product reference"
          },
          "id_category": {
            "type": "integer",
            "format": "uint",
            "description": "Category ID"
          },
          "category_name": {
            "type": "string",
            "description": "Category name"
          }
        }
      },
      "Language": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "uint64",
            "description": "Language ID"
          },
          "name": {
            "type": "string",
            "description": "Language name"
          },
          "iso_code": {
            "type": "string",
            "description": "ISO 639-1 code (e.g., 'en', 'pl')"
          },
          "lang_code": {
            "type": "string",
            "description": "Full language code (e.g., 'en-US', 'pl-PL')"
          },
          "date_format": {
            "type": "string",
            "description": "Date format string"
          },
          "date_format_short": {
            "type": "string",
            "description": "Short date format string"
          },
          "rtl": {
            "type": "boolean",
            "description": "Right-to-left language"
          },
          "is_default": {
            "type": "boolean",
            "description": "Is default language"
          },
          "active": {
            "type": "boolean",
            "description": "Is active"
          },
          "flag": {
            "type": "string",
            "description": "Flag emoji or code"
          }
        }
      },
      "QuarterData": {
        "type": "object",
        "description": "Time tracked in a specific quarter",
        "properties": {
          "time": {
            "type": "number",
            "format": "double",
            "description": "Total hours tracked in this quarter"
          },
          "quarter": {
            "type": "string",
            "description": "Quarter identifier in format YYYY_QN (e.g., '2024_Q1')",
            "example": "2024_Q1"
          }
        }
      },
      "IssueTimeSummary": {
        "type": "object",
        "description": "Time tracking summary for a single issue",
        "properties": {
          "issue_id": {
            "type": "integer",
            "format": "uint",
            "description": "Issue ID"
          },
          "issue_name": {
            "type": "string",
            "description": "Issue title/name"
          },
          "user_id": {
            "type": "integer",
            "format": "uint",
            "description": "ID of the user who tracked time"
          },
          "initials": {
            "type": "string",
            "description": "Abbreviated initials of the user (e.g., 'J.D.')"
          },
          "created_date": {
            "type": "string",
            "format": "date",
            "description": "Date when time was tracked"
          },
          "total_hours_spent": {
            "type": "number",
            "format": "double",
            "description": "Total hours spent on this issue on the given date (rounded to 2 decimal places)"
          }
        }
      },
      "PaginatedIssues": {
        "type": "object",
        "description": "Paginated list of issue time summaries",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IssueTimeSummary"
            },
            "description": "List of issue time summaries for the current page"
          },
          "items_count": {
            "type": "integer",
            "format": "uint",
            "description": "Total number of items across all pages",
            "example": 56
          }
        }
      },
      "SettingsResponse": {
        "type": "object",
        "properties": {
          "app": {
            "$ref": "#/components/schemas/AppSettings"
          },
          "server": {
            "$ref": "#/components/schemas/ServerSettings"
          },
          "auth": {
            "$ref": "#/components/schemas/AuthSettings"
          },
          "features": {
            "$ref": "#/components/schemas/FeatureFlags"
          },
          "version": {
            "$ref": "#/components/schemas/VersionInfo"
          }
        }
      },
      "AppSettings": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Application name"
          },
          "environment": {
            "type": "string",
            "description": "Application environment (e.g., 'development', 'production')"
          },
          "base_url": {
            "type": "string",
            "description": "Base URL of the application"
          },
          "password_regex": {
            "type": "string",
            "description": "Regular expression for password validation"
          }
        }
      },
      "ServerSettings": {
        "type": "object",
        "properties": {
          "port": {
            "type": "integer",
            "description": "Server port"
          },
          "host": {
            "type": "string",
            "description": "Server host"
          }
        }
      },
      "AuthSettings": {
        "type": "object",
        "properties": {
          "jwt_expiration": {
            "type": "integer",
            "description": "JWT access token expiration in seconds"
          },
          "refresh_expiration": {
            "type": "integer",
            "description": "Refresh token expiration in seconds"
          }
        }
      },
      "FeatureFlags": {
        "type": "object",
        "properties": {
          "email_enabled": {
            "type": "boolean",
            "description": "Whether email functionality is enabled"
          },
          "oauth_google": {
            "type": "boolean",
            "description": "Whether Google OAuth is enabled"
          }
        }
      },
      "VersionInfo": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string",
            "description": "Application version (git tag or commit hash)"
          },
          "commit": {
            "type": "string",
            "description": "Short git commit hash"
          },
          "build_date": {
            "type": "string",
            "format": "date-time",
            "description": "Build date in RFC3339 format"
          }
        }
      }
    },
    "securitySchemes": {
      "CookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "access_token",
        "description": "HTTPOnly JWT access token cookie set during login, registration, or token refresh"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT token obtained from login response (alternative to cookie-based auth)"
      }
    }
  }
}
