From 01f5c330420c181757eb07746a4c5cca2280b71d Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Mon, 9 Feb 2026 14:39:56 +0100 Subject: [PATCH] feat: implement wallet and collection endpoints --- backend/app/dependencies.py | 28 ++++++++++++++++++++++++ backend/app/main.py | 3 ++- backend/app/routers/users.py | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 backend/app/dependencies.py create mode 100644 backend/app/routers/users.py diff --git a/backend/app/dependencies.py b/backend/app/dependencies.py new file mode 100644 index 0000000..5e16c55 --- /dev/null +++ b/backend/app/dependencies.py @@ -0,0 +1,28 @@ +from fastapi import Depends, HTTPException, status +from fastapi.security import OAuth2PasswordBearer +from jose import JWTError, jwt +from sqlalchemy.orm import Session +from app.database import get_db +from app import models, auth_utils +from app.config import settings + +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/login") + +def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)): + credentials_exception = HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Could not validate credentials", + headers={"WWW-Authenticate": "Bearer"}, + ) + try: + payload = jwt.decode(token, auth_utils.SECRET_KEY, algorithms=[auth_utils.ALGORITHM]) + username: str = payload.get("sub") + if username is None: + raise credentials_exception + except JWTError: + raise credentials_exception + + user = db.query(models.User).filter(models.User.email == username).first() + if user is None: + raise credentials_exception + return user diff --git a/backend/app/main.py b/backend/app/main.py index 90d2542..4b6b4a8 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -3,7 +3,7 @@ from sqlalchemy.orm import Session from sqlalchemy import text from app.database import get_db, engine from app import models, seed -from app.routers import auth +from app.routers import auth, users # Create all tables models.Base.metadata.create_all(bind=engine) @@ -11,6 +11,7 @@ models.Base.metadata.create_all(bind=engine) app = FastAPI(title="Card Game Backend") app.include_router(auth.router) +app.include_router(users.router) @app.on_event("startup") def startup_event(): diff --git a/backend/app/routers/users.py b/backend/app/routers/users.py new file mode 100644 index 0000000..5c85c6a --- /dev/null +++ b/backend/app/routers/users.py @@ -0,0 +1,41 @@ +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session +from app import models, dependencies +from typing import List +from pydantic import BaseModel + +router = APIRouter(prefix="/me", tags=["me"]) + +class WalletResponse(BaseModel): + balance: int + +class ProfileResponse(BaseModel): + nickname: str + is_collection_public: bool + + class Config: + orm_mode = True + +class CardResponse(BaseModel): + name: str + rarity: str + + class Config: + orm_mode = True + +@router.get("/wallet", response_model=WalletResponse) +def get_my_wallet(current_user: models.User = Depends(dependencies.get_current_user)): + return {"balance": current_user.wallet.balance if current_user.wallet else 0} + +@router.get("/profile", response_model=ProfileResponse) +def get_my_profile(current_user: models.User = Depends(dependencies.get_current_user)): + return current_user.profile + +@router.get("/collection", response_model=List[CardResponse]) +def get_my_collection(current_user: models.User = Depends(dependencies.get_current_user)): + # Returns list of Card objects owned by user + # current_user.cards is list of UserCard association objects. + # UserCard has .card relationship. + # We want to return the Card details. + # Let's verify what current_user.cards contains. + return [user_card.card for user_card in current_user.cards]