{
  "openapi": "3.1.0",
  "info": {
    "title": "Portfolio Management API",
    "description": "A comprehensive API for portfolio management, transaction tracking, and tax reporting",
    "version": "1.0.0"
  },
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "summary": "Health Check",
        "description": "Health check endpoint to verify the API is running.",
        "operationId": "health_check_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "tags": [
          "Root"
        ],
        "summary": "Root",
        "description": "Root endpoint with API information.",
        "operationId": "root__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login-key": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Login For Api Key",
        "description": "Validate username/password and return the server API key.\n\nThe web client uses ``X-API-Key`` for all data endpoints. This bridges a\nusername/password login to that scheme: on valid credentials it returns the\nconfigured ``SERVER_API_KEY`` so the browser can use it for subsequent calls.",
        "operationId": "login_for_api_key_api_v1_auth_login_key_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserLoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginKeyResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/change-password-key": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Change Password With Key",
        "description": "Change a user's password from the web client.\n\nThe web logs in via ``/login-key`` (shared API key), so the session-based\n``/change-password`` doesn't apply. Here, knowing the current password is\nthe authorisation: we verify it via ``login`` (which sets the session),\nthen update to the new password.",
        "operationId": "change_password_with_key_api_v1_auth_change_password_key_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePasswordKeyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/register": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Register User",
        "description": "Register a new user.\n\nArgs:\n    user_data: User registration data\n    auth_manager: Authentication manager\n    db: Database instance\n\nReturns:\n    UserResponse: Created user information\n\nRaises:\n    HTTPException: If registration fails",
        "operationId": "register_user_api_v1_auth_register_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserRegistrationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Login User",
        "description": "Login user and create session.\n\nArgs:\n    login_data: Login credentials\n    auth_manager: Authentication manager\n    db: Database instance\n\nReturns:\n    LoginResponse: Login response with token and user info\n\nRaises:\n    HTTPException: If login fails",
        "operationId": "login_user_api_v1_auth_login_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserLoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Logout User",
        "description": "Logout current user and clear session.\n\nArgs:\n    auth_manager: Authentication manager\n    current_user: Current authenticated user\n\nReturns:\n    MessageResponse: Logout confirmation",
        "operationId": "logout_user_api_v1_auth_logout_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get Current User Info",
        "description": "Get current user information.\n\nArgs:\n    current_user: Current authenticated user\n    db: Database instance\n\nReturns:\n    UserResponse: Current user information",
        "operationId": "get_current_user_info_api_v1_auth_me_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/api/v1/auth/change-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Change Password",
        "description": "Change user password.\n\nArgs:\n    password_data: Password change data\n    auth_manager: Authentication manager\n    current_user: Current authenticated user\n\nReturns:\n    MessageResponse: Password change confirmation\n\nRaises:\n    HTTPException: If password change fails",
        "operationId": "change_password_api_v1_auth_change_password_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/api/v1/assets/": {
      "post": {
        "tags": [
          "Assets"
        ],
        "summary": "Create Asset",
        "description": "Create a new asset.\n\nArgs:\n    asset_data: Asset creation data\n    db: Database instance\n    current_user_id: Current user ID\n\nReturns:\n    AssetResponse: Created asset information",
        "operationId": "create_asset_api_v1_assets__post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssetCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "List Assets",
        "description": "Get all assets with optional filtering.\n\nArgs:\n    active_only: Whether to only return active assets\n    asset_type: Filter by asset type\n    sector: Filter by sector\n    db: Database instance\n\nReturns:\n    List[AssetWithPriceResponse]: List of assets with current prices",
        "operationId": "list_assets_api_v1_assets__get",
        "parameters": [
          {
            "name": "active_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only return active assets",
              "default": true,
              "title": "Active Only"
            },
            "description": "Only return active assets"
          },
          {
            "name": "asset_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by asset type",
              "title": "Asset Type"
            },
            "description": "Filter by asset type"
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by sector",
              "title": "Sector"
            },
            "description": "Filter by sector"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssetWithPriceResponse"
                  },
                  "title": "Response List Assets Api V1 Assets  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assets/{asset_id}": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get Asset",
        "description": "Get a specific asset by ID.\n\nArgs:\n    asset_id: Asset ID\n    db: Database instance\n\nReturns:\n    AssetWithPriceResponse: Asset information with current price",
        "operationId": "get_asset_api_v1_assets__asset_id__get",
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Asset Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetWithPriceResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Assets"
        ],
        "summary": "Update Asset",
        "description": "Update an asset.\n\nArgs:\n    asset_id: Asset ID\n    asset_data: Asset update data\n    db: Database instance\n    current_user_id: Current user ID\n\nReturns:\n    AssetResponse: Updated asset information",
        "operationId": "update_asset_api_v1_assets__asset_id__put",
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Asset Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssetUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Assets"
        ],
        "summary": "Delete Asset",
        "description": "Delete an asset (soft delete).\n\nArgs:\n    asset_id: Asset ID\n    db: Database instance\n    current_user_id: Current user ID",
        "operationId": "delete_asset_api_v1_assets__asset_id__delete",
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Asset Id"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assets/{asset_id}/prices": {
      "post": {
        "tags": [
          "Assets"
        ],
        "summary": "Add Price",
        "description": "Add a price record for an asset.\n\nArgs:\n    asset_id: Asset ID\n    price_data: Price data\n    db: Database instance\n    current_user_id: Current user ID\n\nReturns:\n    PriceResponse: Created price record",
        "operationId": "add_price_api_v1_assets__asset_id__prices_post",
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Asset Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get Asset Prices",
        "description": "Get price history for an asset.\n\nArgs:\n    asset_id: Asset ID\n    start_date: Start date for price history\n    end_date: End date for price history\n    price_type: Type of price\n    db: Database instance\n\nReturns:\n    List[PriceResponse]: Price history",
        "operationId": "get_asset_prices_api_v1_assets__asset_id__prices_get",
        "parameters": [
          {
            "name": "asset_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Asset Id"
            }
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Start date for price history",
              "title": "Start Date"
            },
            "description": "Start date for price history"
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "End date for price history",
              "title": "End Date"
            },
            "description": "End date for price history"
          },
          {
            "name": "price_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PriceType",
              "description": "Type of price",
              "default": "close"
            },
            "description": "Type of price"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PriceResponse"
                  },
                  "title": "Response Get Asset Prices Api V1 Assets  Asset Id  Prices Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "List Transactions",
        "description": "Get all transactions.",
        "operationId": "list_transactions_api_v1_transactions__get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Number of transactions to return",
              "default": 100,
              "title": "Limit"
            },
            "description": "Number of transactions to return"
          },
          {
            "name": "symbol",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by asset symbol",
              "title": "Symbol"
            },
            "description": "Filter by asset symbol"
          },
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by portfolio",
              "title": "Portfolio Id"
            },
            "description": "Filter by portfolio"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TransactionResponse"
                  },
                  "title": "Response List Transactions Api V1 Transactions  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Create Transaction",
        "description": "Create a new transaction.",
        "operationId": "create_transaction_api_v1_transactions__post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Create Transaction Api V1 Transactions  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/transactions/{transaction_id}": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get Transaction",
        "description": "Get a specific transaction by ID.",
        "operationId": "get_transaction_api_v1_transactions__transaction_id__get",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Transaction Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Transactions"
        ],
        "summary": "Update Transaction",
        "description": "Update a transaction.",
        "operationId": "update_transaction_api_v1_transactions__transaction_id__put",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Transaction Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update Transaction Api V1 Transactions  Transaction Id  Put"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Delete Transaction",
        "description": "Delete a transaction.",
        "operationId": "delete_transaction_api_v1_transactions__transaction_id__delete",
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Transaction Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete Transaction Api V1 Transactions  Transaction Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/portfolios/": {
      "get": {
        "tags": [
          "Portfolios"
        ],
        "summary": "List Portfolios",
        "description": "Get all portfolios (a portfolio doubles as a broker/account).\n\nIncludes the broker website/description (stored value, else a built-in\ndefault for known brokers) and the first/last transaction and booking dates\nso you can see what each broker already covers.",
        "operationId": "list_portfolios_api_v1_portfolios__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Portfolios"
        ],
        "summary": "Create Portfolio",
        "description": "Create a new portfolio.",
        "operationId": "create_portfolio_api_v1_portfolios__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/portfolios/values": {
      "get": {
        "tags": [
          "Portfolios"
        ],
        "summary": "Get Portfolio Values",
        "description": "Current EUR value, cost, and P&L per portfolio, plus a grand total.\n\nPowers the value column + totals footer on the Portfolios page. Detailed\npositions remain on the Holdings page.",
        "operationId": "get_portfolio_values_api_v1_portfolios_values_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/portfolios/holdings": {
      "get": {
        "tags": [
          "Portfolios"
        ],
        "summary": "Get Holdings",
        "description": "Get current holdings (positions with total value) computed from transactions.",
        "operationId": "get_holdings_api_v1_portfolios_holdings_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/portfolios/{portfolio_id}": {
      "put": {
        "tags": [
          "Portfolios"
        ],
        "summary": "Update Portfolio",
        "description": "Update a portfolio.",
        "operationId": "update_portfolio_api_v1_portfolios__portfolio_id__put",
        "parameters": [
          {
            "name": "portfolio_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Portfolio Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Portfolios"
        ],
        "summary": "Delete Portfolio",
        "description": "Delete a portfolio (soft-delete; its transactions keep their data).",
        "operationId": "delete_portfolio_api_v1_portfolios__portfolio_id__delete",
        "parameters": [
          {
            "name": "portfolio_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Portfolio Id"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/entities/": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "List Entities",
        "description": "Get all entities.",
        "operationId": "list_entities_api_v1_entities__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Entities"
        ],
        "summary": "Create Entity",
        "description": "Create a new entity.",
        "operationId": "create_entity_api_v1_entities__post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/sectors/": {
      "get": {
        "tags": [
          "Sectors"
        ],
        "summary": "Get All Sectors",
        "description": "Get all available GICS sectors.\n\nReturns:\n    List[str]: List of all unique sectors",
        "operationId": "get_all_sectors_api_v1_sectors__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array",
                  "title": "Response Get All Sectors Api V1 Sectors  Get"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sectors/{symbol}": {
      "get": {
        "tags": [
          "Sectors"
        ],
        "summary": "Get Asset Sector",
        "description": "Get the sector for a specific asset symbol.\n\nArgs:\n    symbol: Asset symbol\n\nReturns:\n    dict: Asset symbol and sector information",
        "operationId": "get_asset_sector_api_v1_sectors__symbol__get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llm/extract-transactions": {
      "post": {
        "tags": [
          "LLM"
        ],
        "summary": "Extract Transactions From Text",
        "description": "Extract transactions from broker statement text using LLM.",
        "operationId": "extract_transactions_from_text_api_v1_llm_extract_transactions_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionExtractionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionExtractionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llm/extract-bookings": {
      "post": {
        "tags": [
          "LLM"
        ],
        "summary": "Extract Bookings From Text",
        "description": "Extract cash deposits/withdrawals (bookings) from statement text via LLM.",
        "operationId": "extract_bookings_from_text_api_v1_llm_extract_bookings_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionExtractionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingExtractionResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llm/extract-async": {
      "post": {
        "tags": [
          "LLM"
        ],
        "summary": "Extract Async",
        "description": "Start an extraction job and return its id immediately (poll for the result).",
        "operationId": "extract_async_api_v1_llm_extract_async_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionExtractionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llm/extract-status/{job_id}": {
      "get": {
        "tags": [
          "LLM"
        ],
        "summary": "Extract Status",
        "description": "Return the status/result of an extraction job.",
        "operationId": "extract_status_api_v1_llm_extract_status__job_id__get",
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/llm/chat": {
      "post": {
        "tags": [
          "LLM"
        ],
        "summary": "Chat",
        "description": "Enhanced chat endpoint with integrated stock advice capabilities.\n\nThis endpoint now automatically detects the type of question you're asking and\nprovides appropriate analysis:\n\n- Portfolio questions: Uses your existing portfolio data\n- Stock screening: \"Find good dividend stocks\", \"Screen for growth stocks\"\n- Technical analysis: \"Should I buy AAPL?\", \"Technical analysis of TSLA\"\n- Fundamental analysis: \"Financial health of MSFT\", \"Is AMZN overvalued?\"\n- General questions: Basic market data and AI insights\n\nThe response includes both the AI answer and structured analysis data.",
        "operationId": "chat_api_v1_llm_chat_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tax/report": {
      "get": {
        "tags": [
          "Tax"
        ],
        "summary": "Generate Tax Report",
        "description": "Generate tax report in CSV or PDF format based on user portfolio and date range.\n\nThis endpoint calculates capital gains/losses using FIFO methodology and generates\na report for tax filing purposes.\n\nArgs:\n    start_date: Start date for sell transactions to include in report\n    end_date: End date for sell transactions to include in report\n    symbols: Optional comma-separated list of symbols to filter by\n    format: Output format ('csv' or 'pdf')\n    current_user_id: Current user ID\n    database: Database instance\n\nReturns:\n    CSV or PDF file with tax report data\n\nRaises:\n    HTTPException: If report generation fails",
        "operationId": "generate_tax_report_api_v1_tax_report_get",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "start_date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Start date for tax report (YYYY-MM-DD)",
              "title": "Start Date"
            },
            "description": "Start date for tax report (YYYY-MM-DD)"
          },
          {
            "name": "end_date",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "End date for tax report (YYYY-MM-DD)",
              "title": "End Date"
            },
            "description": "End date for tax report (YYYY-MM-DD)"
          },
          {
            "name": "symbols",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma-separated list of symbols to filter by",
              "title": "Symbols"
            },
            "description": "Comma-separated list of symbols to filter by"
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Output format: 'csv' or 'pdf'",
              "default": "csv",
              "title": "Format"
            },
            "description": "Output format: 'csv' or 'pdf'"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tax/": {
      "get": {
        "tags": [
          "Tax"
        ],
        "summary": "Tax Info",
        "description": "Tax reporting info and available endpoints.",
        "operationId": "tax_info_api_v1_tax__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/import/upload": {
      "post": {
        "tags": [
          "Import"
        ],
        "summary": "Upload Broker File",
        "description": "Parse a broker statement file and return a preview of extracted transactions.\nRows that already exist in the DB are flagged (``is_duplicate``).\nNo data is saved — call POST /save to commit.",
        "operationId": "upload_broker_file_api_v1_import_upload_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_broker_file_api_v1_import_upload_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadPreviewResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/import/save": {
      "post": {
        "tags": [
          "Import"
        ],
        "summary": "Save Imported Transactions",
        "description": "Save a list of preview transactions (and optional bookings) to the database.\nAssets are created automatically if they don't exist yet.",
        "operationId": "save_imported_transactions_api_v1_import_save_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaveResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/import/check-duplicates": {
      "post": {
        "tags": [
          "Import"
        ],
        "summary": "Check Duplicates",
        "description": "Flag which of the supplied transactions/bookings already exist (no write).\n\nLets the text/LLM import preview show duplicates before saving, the same way\nthe file-upload preview does.",
        "operationId": "check_duplicates_api_v1_import_check_duplicates_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/csv": {
      "get": {
        "tags": [
          "Export"
        ],
        "summary": "Export Transactions Csv",
        "description": "Download all transactions as a CSV file.",
        "operationId": "export_transactions_csv_api_v1_export_csv_get",
        "parameters": [
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by portfolio ID",
              "title": "Portfolio Id"
            },
            "description": "Filter by portfolio ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/pdt": {
      "get": {
        "tags": [
          "Export"
        ],
        "summary": "Export Pdt Xlsx",
        "description": "Download all transactions in Portfolio Dividend Tracker XLSX format.",
        "operationId": "export_pdt_xlsx_api_v1_export_pdt_get",
        "parameters": [
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by portfolio ID",
              "title": "Portfolio Id"
            },
            "description": "Filter by portfolio ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/export/backup": {
      "get": {
        "tags": [
          "Export"
        ],
        "summary": "Export Db Backup",
        "description": "Download a consistent snapshot of the SQLite database (online-safe backup).\n\nUses SQLite's backup API so it is safe to run against the live DB; the result\nis a normal .db file you can keep or restore by dropping it in place.",
        "operationId": "export_db_backup_api_v1_export_backup_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/bookings/": {
      "post": {
        "tags": [
          "Bookings"
        ],
        "summary": "Create Booking",
        "description": "Create a manual deposit or withdrawal booking.",
        "operationId": "create_booking_api_v1_bookings__post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Bookings"
        ],
        "summary": "List Bookings",
        "description": "Get all bookings (deposits and withdrawals).",
        "operationId": "list_bookings_api_v1_bookings__get",
        "parameters": [
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by portfolio ID",
              "title": "Portfolio Id"
            },
            "description": "Filter by portfolio ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BookingResponse"
                  },
                  "title": "Response List Bookings Api V1 Bookings  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/bookings/{booking_id}": {
      "delete": {
        "tags": [
          "Bookings"
        ],
        "summary": "Delete Booking",
        "description": "Delete a booking by ID.",
        "operationId": "delete_booking_api_v1_bookings__booking_id__delete",
        "parameters": [
          {
            "name": "booking_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Booking Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete Booking Api V1 Bookings  Booking Id  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sync/pdt-config": {
      "get": {
        "tags": [
          "Sync"
        ],
        "summary": "Get Sync Config",
        "description": "Return current Google Sheets sync configuration.",
        "operationId": "get_sync_config_api_v1_sync_pdt_config_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncConfigResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sync/pdt-pull": {
      "post": {
        "tags": [
          "Sync"
        ],
        "summary": "Pull From Sheets",
        "description": "Pull all data from a PDT-format Google Spreadsheet and save it to the DB.\nTransactions, dividends, and bookings are imported; assets and portfolios\nare auto-created where needed.",
        "operationId": "pull_from_sheets_api_v1_sync_pdt_pull_post",
        "parameters": [
          {
            "name": "spreadsheet_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Google Spreadsheet ID (falls back to GOOGLE_SPREADSHEET_ID env var)",
              "title": "Spreadsheet Id"
            },
            "description": "Google Spreadsheet ID (falls back to GOOGLE_SPREADSHEET_ID env var)"
          },
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Assign all imported records to this portfolio",
              "title": "Portfolio Id"
            },
            "description": "Assign all imported records to this portfolio"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PullResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sync/pdt-push": {
      "post": {
        "tags": [
          "Sync"
        ],
        "summary": "Push To Sheets",
        "description": "Push all portfolio data to a PDT-format Google Spreadsheet.\nOverwrites the Transactions, Dividends, and Bookings sheets.",
        "operationId": "push_to_sheets_api_v1_sync_pdt_push_post",
        "parameters": [
          {
            "name": "spreadsheet_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Google Spreadsheet ID (falls back to GOOGLE_SPREADSHEET_ID env var)",
              "title": "Spreadsheet Id"
            },
            "description": "Google Spreadsheet ID (falls back to GOOGLE_SPREADSHEET_ID env var)"
          },
          {
            "name": "portfolio_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Export only this portfolio (default: all)",
              "title": "Portfolio Id"
            },
            "description": "Export only this portfolio (default: all)"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushResponse"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/rebalance/targets": {
      "get": {
        "tags": [
          "Rebalance"
        ],
        "summary": "Get Targets",
        "description": "Return current allocation targets.",
        "operationId": "get_targets_api_v1_rebalance_targets_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Rebalance"
        ],
        "summary": "Set Targets",
        "description": "Bulk-set allocation targets (replaces all existing).",
        "operationId": "set_targets_api_v1_rebalance_targets_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/AllocationTarget"
                },
                "type": "array",
                "title": "Targets"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/rebalance/analysis": {
      "get": {
        "tags": [
          "Rebalance"
        ],
        "summary": "Get Rebalance Analysis",
        "description": "Compare current holdings allocation vs targets and return\nbuy/sell amounts needed to rebalance.",
        "operationId": "get_rebalance_analysis_api_v1_rebalance_analysis_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/research/compare": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Compare",
        "description": "Latest saved research per symbol: price, fair value, upside, conviction.",
        "operationId": "compare_api_v1_research_compare_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Get Report",
        "description": "Return the cached research report for a symbol, or 404 if not yet generated.",
        "operationId": "get_report_api_v1_research__symbol__get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/generate": {
      "post": {
        "tags": [
          "Research"
        ],
        "summary": "Generate Report",
        "description": "Run web-augmented LLM valuation. Works for any symbol (held or not).",
        "operationId": "generate_report_api_v1_research__symbol__generate_post",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/lookup": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Lookup",
        "description": "Snapshot for the research workbench (no LLM): price, position,\nfundamentals, news, existing targets and the latest saved research.",
        "operationId": "lookup_api_v1_research__symbol__lookup_get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/save": {
      "post": {
        "tags": [
          "Research"
        ],
        "summary": "Save Research",
        "description": "Save a versioned research record and (for held assets) push targets so\nprice alerts fire.",
        "operationId": "save_research_api_v1_research__symbol__save_post",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResearchSaveBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/history": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "History",
        "description": "Version history of saved research for a symbol.",
        "operationId": "history_api_v1_research__symbol__history_get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/report": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Research Report",
        "description": "Full research dossier for a symbol (position, fundamentals, targets,\nLLM analysis, and saved-note history). ``format=md`` returns an archivable\nMarkdown document; ``download=true`` sets a file-download header.",
        "operationId": "research_report_api_v1_research__symbol__report_get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "json",
              "title": "Format"
            }
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Download"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/{symbol}/targets": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Get Targets",
        "description": "Return price targets for a symbol.",
        "operationId": "get_targets_api_v1_research__symbol__targets_get",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Research"
        ],
        "summary": "Set Targets",
        "description": "Create or update price targets for a symbol.",
        "operationId": "set_targets_api_v1_research__symbol__targets_put",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceTargetBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research/alerts/check": {
      "get": {
        "tags": [
          "Research"
        ],
        "summary": "Check Alerts",
        "description": "Compare all price targets against latest stored prices.\nReturns triggered alerts (does NOT send Telegram — use the cron for that).",
        "operationId": "check_alerts_api_v1_research_alerts_check_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/dividends": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Dividends",
        "description": "Dividend income by year, month, symbol + projected forward annual income.",
        "operationId": "get_dividends_api_v1_analytics_dividends_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/performance": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Performance",
        "description": "Total return, money-weighted IRR, benchmark comparison, and period return.\n\n``total_return_pct`` / ``money_weighted_irr_pct`` are lifetime figures.\n``period_return_pct`` is the change over the selected window, derived from\ndaily snapshots (null when history is shorter than the window).",
        "operationId": "get_performance_api_v1_analytics_performance_get",
        "parameters": [
          {
            "name": "benchmark",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Benchmark ticker for comparison",
              "default": "^GSPC",
              "title": "Benchmark"
            },
            "description": "Benchmark ticker for comparison"
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Return window: ytd | 1m | 1y | all",
              "default": "all",
              "title": "Period"
            },
            "description": "Return window: ytd | 1m | 1y | all"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/networth-history": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Networth History",
        "description": "Daily portfolio value vs invested-cost snapshots.",
        "operationId": "get_networth_history_api_v1_analytics_networth_history_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/snapshot": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Take Snapshot",
        "description": "Record today's portfolio value/cost snapshot (called by the price cron).",
        "operationId": "take_snapshot_api_v1_analytics_snapshot_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/backfill-snapshots": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Backfill Snapshots",
        "description": "Start a background reconstruction of historical net-worth snapshots.",
        "operationId": "backfill_snapshots_api_v1_analytics_backfill_snapshots_post",
        "parameters": [
          {
            "name": "force",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Recompute/overwrite existing snapshots",
              "default": false,
              "title": "Force"
            },
            "description": "Recompute/overwrite existing snapshots"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/backfill-status": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Backfill Status",
        "description": "Progress of the historical backfill (poll while running).",
        "operationId": "backfill_status_api_v1_analytics_backfill_status_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/tax-estimate": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Tax Estimate",
        "description": "Spanish IRPF savings-base estimate: realised gains + dividends YTD, unrealised, harvest candidates.",
        "operationId": "get_tax_estimate_api_v1_analytics_tax_estimate_get",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Tax year (default current)",
              "title": "Year"
            },
            "description": "Tax year (default current)"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/diversification": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Diversification",
        "description": "Sector / country / currency / asset-type concentration + Herfindahl index.\n\nDefined as a sync handler (not async) so FastAPI runs it in a threadpool:\nthe per-holding yfinance ``.info`` lookups are blocking and would freeze\nthe event loop — stalling every other request — if awaited inline.",
        "operationId": "get_diversification_api_v1_analytics_diversification_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/risk": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Risk",
        "description": "Max drawdown, annualised volatility, and Sharpe ratio from snapshot history.",
        "operationId": "get_risk_api_v1_analytics_risk_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/fees": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Fees",
        "description": "Total fees + tax by broker/portfolio, fee drag as % of invested.",
        "operationId": "get_fees_api_v1_analytics_fees_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/analytics/tax-report": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get Tax Report",
        "description": "Per-lot realised gains (FIFO) + dividend withholding summary for a year.\n\nReuses the FIFO engine in TaxCalculator. Amounts are in each transaction's\nown currency as stored; withholding sums the per-transaction ``tax`` field.",
        "operationId": "get_tax_report_api_v1_analytics_tax_report_get",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Tax year (default current)",
              "title": "Year"
            },
            "description": "Tax year (default current)"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/watchlist/": {
      "get": {
        "tags": [
          "Watchlist"
        ],
        "summary": "List Watchlist",
        "description": "List watchlist entries with current price + distance to buy target.",
        "operationId": "list_watchlist_api_v1_watchlist__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Watchlist"
        ],
        "summary": "Add Watchlist",
        "description": "Add a symbol to the watchlist (auto-fills name/type from yfinance if omitted).",
        "operationId": "add_watchlist_api_v1_watchlist__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WatchlistAdd"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/watchlist/{symbol}": {
      "delete": {
        "tags": [
          "Watchlist"
        ],
        "summary": "Delete Watchlist",
        "description": "Remove a symbol from the watchlist.",
        "operationId": "delete_watchlist_api_v1_watchlist__symbol__delete",
        "parameters": [
          {
            "name": "symbol",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Symbol"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/watchlist/alerts/check": {
      "get": {
        "tags": [
          "Watchlist"
        ],
        "summary": "Check Watchlist Alerts",
        "description": "Return watchlist symbols that have dropped into their buy zone.",
        "operationId": "check_watchlist_alerts_api_v1_watchlist_alerts_check_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/api/v1/goals/": {
      "get": {
        "tags": [
          "Goals"
        ],
        "summary": "List Goals",
        "description": "List goals with progress and on-track projection.",
        "operationId": "list_goals_api_v1_goals__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Goals"
        ],
        "summary": "Create Goal",
        "description": "Create a savings goal.",
        "operationId": "create_goal_api_v1_goals__post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GoalCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/goals/{goal_id}": {
      "delete": {
        "tags": [
          "Goals"
        ],
        "summary": "Delete Goal",
        "description": "Delete a goal.",
        "operationId": "delete_goal_api_v1_goals__goal_id__delete",
        "parameters": [
          {
            "name": "goal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "title": "Goal Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/public/summary": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Public Summary",
        "description": "Return allocation percentages + lifetime return %. No absolute amounts.\n\nDisabled unless PORTF_PUBLIC_VIEW is truthy.",
        "operationId": "public_summary_api_v1_public_summary_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AllocationTarget": {
        "properties": {
          "asset_type": {
            "type": "string",
            "title": "Asset Type"
          },
          "target_pct": {
            "type": "number",
            "maximum": 100.0,
            "minimum": 0.0,
            "title": "Target Pct"
          }
        },
        "type": "object",
        "required": [
          "asset_type",
          "target_pct"
        ],
        "title": "AllocationTarget"
      },
      "AssetCreateRequest": {
        "properties": {
          "symbol": {
            "type": "string",
            "maxLength": 20,
            "title": "Symbol",
            "description": "Asset symbol (e.g., AAPL)"
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "title": "Name",
            "description": "Asset name"
          },
          "asset_type": {
            "$ref": "#/components/schemas/AssetType",
            "description": "Type of asset"
          },
          "exchange": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Exchange",
            "description": "Trading exchange"
          },
          "currency": {
            "type": "string",
            "maxLength": 3,
            "title": "Currency",
            "description": "Asset currency",
            "default": "USD"
          },
          "sector": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector",
            "description": "Asset sector"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Asset description"
          }
        },
        "type": "object",
        "required": [
          "symbol",
          "name",
          "asset_type"
        ],
        "title": "AssetCreateRequest",
        "description": "Schema for asset creation request."
      },
      "AssetResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "symbol": {
            "type": "string",
            "title": "Symbol"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "asset_type": {
            "$ref": "#/components/schemas/AssetType"
          },
          "exchange": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exchange"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "sector": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active"
          },
          "auto_price": {
            "type": "boolean",
            "title": "Auto Price",
            "default": true
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "symbol",
          "name",
          "asset_type",
          "currency",
          "is_active"
        ],
        "title": "AssetResponse",
        "description": "Schema for asset response."
      },
      "AssetType": {
        "type": "string",
        "enum": [
          "stock",
          "bond",
          "crypto",
          "etf",
          "index",
          "mutual_fund",
          "commodity",
          "cash"
        ],
        "title": "AssetType",
        "description": "Asset type enumeration."
      },
      "AssetUpdateRequest": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Asset name"
          },
          "asset_type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AssetType"
              },
              {
                "type": "null"
              }
            ],
            "description": "Type of asset"
          },
          "exchange": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Exchange",
            "description": "Trading exchange"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Asset currency"
          },
          "sector": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector",
            "description": "Asset sector"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Asset description"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active",
            "description": "Whether asset is active"
          }
        },
        "type": "object",
        "title": "AssetUpdateRequest",
        "description": "Schema for asset update request."
      },
      "AssetWithPriceResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "symbol": {
            "type": "string",
            "title": "Symbol"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "asset_type": {
            "$ref": "#/components/schemas/AssetType"
          },
          "exchange": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exchange"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "sector": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sector"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active"
          },
          "auto_price": {
            "type": "boolean",
            "title": "Auto Price",
            "default": true
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          },
          "current_price": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Price"
          },
          "price_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Date"
          }
        },
        "type": "object",
        "required": [
          "id",
          "symbol",
          "name",
          "asset_type",
          "currency",
          "is_active"
        ],
        "title": "AssetWithPriceResponse",
        "description": "Schema for asset response with current price."
      },
      "Body_upload_broker_file_api_v1_import_upload_post": {
        "properties": {
          "broker": {
            "type": "string",
            "title": "Broker",
            "description": "Broker type: indexacapital, coinbase, pdt, bookings"
          },
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "Broker statement file (CSV or XLSX)"
          }
        },
        "type": "object",
        "required": [
          "broker",
          "file"
        ],
        "title": "Body_upload_broker_file_api_v1_import_upload_post"
      },
      "BookingCreate": {
        "properties": {
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
          },
          "action": {
            "type": "string",
            "title": "Action"
          },
          "amount": {
            "type": "number",
            "title": "Amount"
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "default": "EUR"
          }
        },
        "type": "object",
        "required": [
          "date",
          "action",
          "amount"
        ],
        "title": "BookingCreate"
      },
      "BookingExtractionResponse": {
        "properties": {
          "bookings": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Bookings",
            "description": "Extracted deposits/withdrawals"
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of bookings extracted"
          }
        },
        "type": "object",
        "required": [
          "bookings",
          "count"
        ],
        "title": "BookingExtractionResponse",
        "description": "Schema for cash booking (deposit/withdrawal) extraction response."
      },
      "BookingResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "portfolio_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Name"
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
          },
          "action": {
            "type": "string",
            "title": "Action"
          },
          "amount": {
            "type": "number",
            "title": "Amount"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          }
        },
        "type": "object",
        "required": [
          "id",
          "date",
          "action",
          "amount",
          "currency"
        ],
        "title": "BookingResponse"
      },
      "ChangePasswordKeyRequest": {
        "properties": {
          "username": {
            "type": "string",
            "title": "Username"
          },
          "current_password": {
            "type": "string",
            "title": "Current Password"
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password",
            "description": "New password (min 8)"
          }
        },
        "type": "object",
        "required": [
          "username",
          "current_password",
          "new_password"
        ],
        "title": "ChangePasswordKeyRequest",
        "description": "Change-password for the API-key (web) auth model: the current password\nitself is the gate, so no Bearer session token is required."
      },
      "ChangePasswordRequest": {
        "properties": {
          "current_password": {
            "type": "string",
            "title": "Current Password",
            "description": "Current password"
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password",
            "description": "New password (min 8 characters)"
          }
        },
        "type": "object",
        "required": [
          "current_password",
          "new_password"
        ],
        "title": "ChangePasswordRequest",
        "description": "Schema for change password request."
      },
      "ChatRequest": {
        "properties": {
          "message": {
            "type": "string",
            "title": "Message"
          },
          "session_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Session Id"
          },
          "symbols": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Symbols"
          },
          "live": {
            "type": "boolean",
            "title": "Live",
            "default": true
          },
          "search": {
            "type": "boolean",
            "title": "Search",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "message"
        ],
        "title": "ChatRequest",
        "description": "Enhanced chat request with stock advice integration."
      },
      "ChatResponse": {
        "properties": {
          "session_id": {
            "type": "string",
            "title": "Session Id"
          },
          "answer": {
            "type": "string",
            "title": "Answer"
          },
          "context_summary": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Context Summary"
          },
          "recommendations": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": true,
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recommendations"
          },
          "warnings": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warnings"
          }
        },
        "type": "object",
        "required": [
          "session_id",
          "answer"
        ],
        "title": "ChatResponse",
        "description": "Enhanced chat response with stock advice context."
      },
      "GoalCreate": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "target_amount_eur": {
            "type": "number",
            "title": "Target Amount Eur"
          },
          "target_date": {
            "type": "string",
            "format": "date",
            "title": "Target Date"
          },
          "monthly_contribution_eur": {
            "type": "number",
            "title": "Monthly Contribution Eur",
            "default": 0
          },
          "expected_return_pct": {
            "type": "number",
            "title": "Expected Return Pct",
            "default": 7.0
          }
        },
        "type": "object",
        "required": [
          "name",
          "target_amount_eur",
          "target_date"
        ],
        "title": "GoalCreate"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "LoginKeyResponse": {
        "properties": {
          "api_key": {
            "type": "string",
            "title": "Api Key"
          },
          "username": {
            "type": "string",
            "title": "Username"
          }
        },
        "type": "object",
        "required": [
          "api_key",
          "username"
        ],
        "title": "LoginKeyResponse",
        "description": "Response for password login that returns the API key for data calls."
      },
      "LoginResponse": {
        "properties": {
          "access_token": {
            "type": "string",
            "title": "Access Token",
            "description": "Authentication token"
          },
          "token_type": {
            "type": "string",
            "title": "Token Type",
            "description": "Token type",
            "default": "bearer"
          },
          "user": {
            "$ref": "#/components/schemas/UserResponse"
          }
        },
        "type": "object",
        "required": [
          "access_token",
          "user"
        ],
        "title": "LoginResponse",
        "description": "Schema for login response."
      },
      "MessageResponse": {
        "properties": {
          "message": {
            "type": "string",
            "title": "Message",
            "description": "Response message"
          }
        },
        "type": "object",
        "required": [
          "message"
        ],
        "title": "MessageResponse",
        "description": "Schema for simple message responses."
      },
      "PortfolioCreate": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Portfolio name"
          },
          "base_currency": {
            "type": "string",
            "title": "Base Currency",
            "description": "Base currency",
            "default": "EUR"
          },
          "entity_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity Id",
            "description": "Linked entity/broker ID"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Portfolio description"
          },
          "website": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website",
            "description": "Broker website URL"
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "PortfolioCreate",
        "description": "Schema for creating a portfolio."
      },
      "PortfolioUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "base_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Currency"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "website": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website"
          }
        },
        "type": "object",
        "title": "PortfolioUpdate",
        "description": "Schema for updating a portfolio."
      },
      "PreviewBooking": {
        "properties": {
          "broker": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Broker"
          },
          "date": {
            "type": "string",
            "title": "Date"
          },
          "action": {
            "type": "string",
            "title": "Action"
          },
          "amount": {
            "type": "number",
            "title": "Amount"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "is_duplicate": {
            "type": "boolean",
            "title": "Is Duplicate",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "date",
          "action",
          "amount",
          "currency"
        ],
        "title": "PreviewBooking"
      },
      "PreviewTransaction": {
        "properties": {
          "symbol": {
            "type": "string",
            "title": "Symbol"
          },
          "name": {
            "type": "string",
            "title": "Name"
          },
          "asset_type": {
            "type": "string",
            "title": "Asset Type"
          },
          "tx_type": {
            "type": "string",
            "title": "Tx Type"
          },
          "date": {
            "type": "string",
            "title": "Date"
          },
          "quantity": {
            "type": "number",
            "title": "Quantity"
          },
          "price": {
            "type": "number",
            "title": "Price"
          },
          "currency": {
            "type": "string",
            "title": "Currency"
          },
          "fees": {
            "type": "number",
            "title": "Fees",
            "default": 0.0
          },
          "tax": {
            "type": "number",
            "title": "Tax",
            "default": 0.0
          },
          "exchange": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exchange"
          },
          "notes": {
            "type": "string",
            "title": "Notes",
            "default": ""
          },
          "broker": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Broker"
          },
          "is_duplicate": {
            "type": "boolean",
            "title": "Is Duplicate",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "symbol",
          "name",
          "asset_type",
          "tx_type",
          "date",
          "quantity",
          "price",
          "currency"
        ],
        "title": "PreviewTransaction"
      },
      "PriceCreateRequest": {
        "properties": {
          "price": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Price",
            "description": "Price value"
          },
          "price_date": {
            "type": "string",
            "format": "date",
            "title": "Price Date",
            "description": "Price date"
          },
          "price_type": {
            "$ref": "#/components/schemas/PriceType",
            "description": "Type of price",
            "default": "close"
          },
          "volume": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Volume",
            "description": "Trading volume"
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Price data source"
          }
        },
        "type": "object",
        "required": [
          "price",
          "price_date"
        ],
        "title": "PriceCreateRequest",
        "description": "Schema for price creation request."
      },
      "PriceResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "asset_id": {
            "type": "integer",
            "title": "Asset Id"
          },
          "price": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Price"
          },
          "price_date": {
            "type": "string",
            "format": "date",
            "title": "Price Date"
          },
          "price_type": {
            "$ref": "#/components/schemas/PriceType"
          },
          "volume": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Volume"
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "asset_id",
          "price",
          "price_date",
          "price_type"
        ],
        "title": "PriceResponse",
        "description": "Schema for price response."
      },
      "PriceTargetBody": {
        "properties": {
          "buy_below": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buy Below"
          },
          "sell_above": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sell Above"
          },
          "fair_value": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fair Value"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          }
        },
        "type": "object",
        "title": "PriceTargetBody"
      },
      "PriceType": {
        "type": "string",
        "enum": [
          "open",
          "high",
          "low",
          "close",
          "adjusted_close"
        ],
        "title": "PriceType",
        "description": "Price type enumeration."
      },
      "PullResponse": {
        "properties": {
          "spreadsheet_id": {
            "type": "string",
            "title": "Spreadsheet Id"
          },
          "imported_transactions": {
            "type": "integer",
            "title": "Imported Transactions"
          },
          "imported_dividends": {
            "type": "integer",
            "title": "Imported Dividends"
          },
          "imported_bookings": {
            "type": "integer",
            "title": "Imported Bookings"
          },
          "skipped": {
            "type": "integer",
            "title": "Skipped"
          },
          "errors": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Errors",
            "default": []
          }
        },
        "type": "object",
        "required": [
          "spreadsheet_id",
          "imported_transactions",
          "imported_dividends",
          "imported_bookings",
          "skipped"
        ],
        "title": "PullResponse"
      },
      "PushResponse": {
        "properties": {
          "spreadsheet_id": {
            "type": "string",
            "title": "Spreadsheet Id"
          },
          "transactions_written": {
            "type": "integer",
            "title": "Transactions Written"
          },
          "dividends_written": {
            "type": "integer",
            "title": "Dividends Written"
          },
          "bookings_written": {
            "type": "integer",
            "title": "Bookings Written"
          },
          "spreadsheet_url": {
            "type": "string",
            "title": "Spreadsheet Url"
          }
        },
        "type": "object",
        "required": [
          "spreadsheet_id",
          "transactions_written",
          "dividends_written",
          "bookings_written",
          "spreadsheet_url"
        ],
        "title": "PushResponse"
      },
      "ResearchSaveBody": {
        "properties": {
          "thesis": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thesis"
          },
          "conviction": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Conviction"
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method"
          },
          "assumptions": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assumptions"
          },
          "fair_value": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fair Value"
          },
          "buy_below": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buy Below"
          },
          "sell_above": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sell Above"
          },
          "llm_summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Llm Summary"
          },
          "sources": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sources"
          },
          "current_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Price"
          }
        },
        "type": "object",
        "title": "ResearchSaveBody"
      },
      "SaveRequest": {
        "properties": {
          "transactions": {
            "items": {
              "$ref": "#/components/schemas/PreviewTransaction"
            },
            "type": "array",
            "title": "Transactions"
          },
          "bookings": {
            "items": {
              "$ref": "#/components/schemas/PreviewBooking"
            },
            "type": "array",
            "title": "Bookings",
            "default": []
          },
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "duplicate_action": {
            "type": "string",
            "enum": [
              "skip",
              "add",
              "overwrite"
            ],
            "title": "Duplicate Action",
            "default": "skip"
          },
          "force": {
            "type": "boolean",
            "title": "Force",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "transactions"
        ],
        "title": "SaveRequest"
      },
      "SaveResponse": {
        "properties": {
          "saved": {
            "type": "integer",
            "title": "Saved"
          },
          "saved_bookings": {
            "type": "integer",
            "title": "Saved Bookings",
            "default": 0
          },
          "duplicates_skipped": {
            "type": "integer",
            "title": "Duplicates Skipped",
            "default": 0
          },
          "overwritten": {
            "type": "integer",
            "title": "Overwritten",
            "default": 0
          },
          "errors": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Errors"
          }
        },
        "type": "object",
        "required": [
          "saved",
          "errors"
        ],
        "title": "SaveResponse"
      },
      "SyncConfigResponse": {
        "properties": {
          "service_account_configured": {
            "type": "boolean",
            "title": "Service Account Configured"
          },
          "service_account_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Service Account Email"
          },
          "default_spreadsheet_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Spreadsheet Id"
          }
        },
        "type": "object",
        "required": [
          "service_account_configured"
        ],
        "title": "SyncConfigResponse"
      },
      "TransactionCreateRequest": {
        "properties": {
          "asset_id": {
            "type": "integer",
            "title": "Asset Id"
          },
          "transaction_type": {
            "type": "string",
            "title": "Transaction Type"
          },
          "quantity": {
            "type": "number",
            "title": "Quantity"
          },
          "price": {
            "type": "number",
            "title": "Price"
          },
          "total_amount": {
            "type": "number",
            "title": "Total Amount"
          },
          "transaction_date": {
            "type": "string",
            "title": "Transaction Date"
          },
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "fees": {
            "type": "number",
            "title": "Fees",
            "default": 0.0
          },
          "tax": {
            "type": "number",
            "title": "Tax",
            "default": 0.0
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "user_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          }
        },
        "type": "object",
        "required": [
          "asset_id",
          "transaction_type",
          "quantity",
          "price",
          "total_amount",
          "transaction_date"
        ],
        "title": "TransactionCreateRequest",
        "description": "Schema for creating a new transaction."
      },
      "TransactionExtractionRequest": {
        "properties": {
          "text": {
            "type": "string",
            "title": "Text",
            "description": "Raw broker statement text"
          }
        },
        "type": "object",
        "required": [
          "text"
        ],
        "title": "TransactionExtractionRequest",
        "description": "Schema for transaction extraction request."
      },
      "TransactionExtractionResponse": {
        "properties": {
          "transactions": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Transactions",
            "description": "Extracted transactions"
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of transactions extracted"
          }
        },
        "type": "object",
        "required": [
          "transactions",
          "count"
        ],
        "title": "TransactionExtractionResponse",
        "description": "Schema for transaction extraction response."
      },
      "TransactionResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "asset_id": {
            "type": "integer",
            "title": "Asset Id"
          },
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "portfolio_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Name"
          },
          "transaction_type": {
            "type": "string",
            "title": "Transaction Type"
          },
          "quantity": {
            "type": "number",
            "title": "Quantity"
          },
          "price": {
            "type": "number",
            "title": "Price"
          },
          "total_amount": {
            "type": "number",
            "title": "Total Amount"
          },
          "fees": {
            "type": "number",
            "title": "Fees",
            "default": 0.0
          },
          "transaction_date": {
            "type": "string",
            "format": "date",
            "title": "Transaction Date"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "symbol": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Symbol"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency"
          }
        },
        "type": "object",
        "required": [
          "id",
          "asset_id",
          "transaction_type",
          "quantity",
          "price",
          "total_amount",
          "transaction_date"
        ],
        "title": "TransactionResponse"
      },
      "TransactionUpdateRequest": {
        "properties": {
          "quantity": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity"
          },
          "price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price"
          },
          "fees": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fees"
          },
          "transaction_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Transaction Date"
          },
          "transaction_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Transaction Type"
          },
          "portfolio_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Portfolio Id"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          }
        },
        "type": "object",
        "title": "TransactionUpdateRequest",
        "description": "Schema for updating a transaction."
      },
      "UploadPreviewResponse": {
        "properties": {
          "broker": {
            "type": "string",
            "title": "Broker"
          },
          "transactions": {
            "items": {
              "$ref": "#/components/schemas/PreviewTransaction"
            },
            "type": "array",
            "title": "Transactions"
          },
          "bookings": {
            "items": {
              "$ref": "#/components/schemas/PreviewBooking"
            },
            "type": "array",
            "title": "Bookings",
            "default": []
          },
          "skipped_count": {
            "type": "integer",
            "title": "Skipped Count"
          },
          "skipped": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Skipped"
          },
          "duplicate_count": {
            "type": "integer",
            "title": "Duplicate Count",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "broker",
          "transactions",
          "skipped_count",
          "skipped"
        ],
        "title": "UploadPreviewResponse"
      },
      "UserLoginRequest": {
        "properties": {
          "username": {
            "type": "string",
            "title": "Username",
            "description": "Username or email address"
          },
          "password": {
            "type": "string",
            "title": "Password",
            "description": "User password"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "UserLoginRequest",
        "description": "Schema for user login request."
      },
      "UserRegistrationRequest": {
        "properties": {
          "username": {
            "type": "string",
            "maxLength": 50,
            "minLength": 3,
            "title": "Username",
            "description": "Unique username"
          },
          "email": {
            "type": "string",
            "format": "email",
            "title": "Email",
            "description": "User email address"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "title": "Password",
            "description": "User password (min 8 characters)"
          },
          "full_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Full Name",
            "description": "User's full name"
          }
        },
        "type": "object",
        "required": [
          "username",
          "email",
          "password"
        ],
        "title": "UserRegistrationRequest",
        "description": "Schema for user registration request."
      },
      "UserResponse": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id"
          },
          "username": {
            "type": "string",
            "title": "Username"
          },
          "email": {
            "type": "string",
            "title": "Email"
          },
          "full_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Full Name"
          },
          "is_active": {
            "type": "boolean",
            "title": "Is Active"
          },
          "last_login": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Login"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          }
        },
        "type": "object",
        "required": [
          "id",
          "username",
          "email",
          "is_active"
        ],
        "title": "UserResponse",
        "description": "Schema for user information response."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "WatchlistAdd": {
        "properties": {
          "symbol": {
            "type": "string",
            "title": "Symbol"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "asset_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asset Type"
          },
          "buy_below": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buy Below"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          }
        },
        "type": "object",
        "required": [
          "symbol"
        ],
        "title": "WatchlistAdd"
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  }
}