Skip to content

Commit

Permalink
add pagination and total count in user positions endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Teri-anric committed Jan 28, 2025
1 parent e36ac36 commit ee753c2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 15 deletions.
32 changes: 18 additions & 14 deletions web_app/api/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
AddPositionDepositData,
PositionFormData,
TokenMultiplierResponse,
UserPositionResponse,
UserPositionExtraDepositsResponse,
UserPositionHistoryResponse,
)
from web_app.api.serializers.transaction import (
LoopLiquidityData,
Expand Down Expand Up @@ -311,33 +311,37 @@ async def add_extra_deposit(position_id: UUID, data: AddPositionDepositData):
@router.get(
"/api/user-positions/{wallet_id}",
tags=["Position Operations"],
response_model=list[UserPositionResponse],
response_model=UserPositionHistoryResponse,
summary="Get all positions for a user",
response_description="Returns paginated list of positions for the given wallet ID",
response_description="Returns paginated of positions for the given wallet ID",
)
async def get_user_positions(
wallet_id: str,
start: Optional[int] = None,
start: int = Query(0, ge=0),
limit: int = Query(PAGINATION_STEP, ge=1, le=100),
) -> list:
) -> UserPositionHistoryResponse:
"""
Get all positions for a specific user by their wallet ID.
:param wallet_id: The wallet ID of the user
:param start: Optional starting index for pagination (0-based). If not provided, defaults to 0
:param limit: Optional number of records to return. min 1, max 100.
If not provided, defaults to PAGINATION_STEP
:return: UserPositionsListResponse containing paginated list of positions
:param wallet_id: Wallet ID of the user
:param start: Starting index for pagination (default: 0)
:param limit: Number of items per page (default: 10 from PAGINATION_STEP variable)
:return: UserPositionHistoryResponse with positions and total count
:raises: HTTPException: If wallet ID is empty or invalid
"""
if not wallet_id:
raise HTTPException(status_code=400, detail="Wallet ID is required")

start_index = max(0, start) if start is not None else 0

positions = position_db_connector.get_all_positions_by_wallet_id(
wallet_id, start_index, limit
wallet_id, start=start, limit=limit
)
total_positions = position_db_connector.get_count_positions_by_wallet_id(wallet_id)

return UserPositionHistoryResponse(
positions=positions,
total_count=total_positions
)
return positions


@router.get(
Expand Down
13 changes: 13 additions & 0 deletions web_app/api/serializers/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,16 @@ class UserPositionExtraDepositsResponse(BaseModel):
"""
main: UserPositionResponse
extra_deposits: list[UserExtraDeposit]


class UserPositionHistoryResponse(BaseModel):
"""
Response model for user position history with pagination.
### Attributes:
- **positions**: List of user positions
- **total_count**: Total number of positions for pagination
"""

positions: List[UserPositionResponse] = []
total_count: int = 0
26 changes: 25 additions & 1 deletion web_app/db/crud/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_positions_by_wallet_id(

def get_all_positions_by_wallet_id(
self, wallet_id: str, start: int, limit: int
) -> list:
) -> list[dict]:
"""
Retrieves paginated positions for a user by their wallet ID
and returns them as a list of dictionaries.
Expand Down Expand Up @@ -138,6 +138,30 @@ def get_all_positions_by_wallet_id(
except SQLAlchemyError as e:
logger.error(f"Failed to retrieve positions: {str(e)}")
return []

def get_count_positions_by_wallet_id(self, wallet_id: str) -> int:
"""
Counts total number of positions for a user.
:param wallet_id: Wallet ID of the user
:return: Total number of positions
"""
with self.Session() as db:
user = self._get_user_by_wallet_id(wallet_id)
if not user:
return 0

try:
total_positions = (
db.query(func.count(Position.id))
.filter(Position.user_id == user.id)
.scalar()
)
return total_positions or 0

except SQLAlchemyError as e:
logger.error(f"Failed to count user positions: {str(e)}")
return 0

def has_opened_position(self, wallet_id: str) -> bool:
"""
Expand Down

0 comments on commit ee753c2

Please sign in to comment.