feat: add public profile and collection endpoints

This commit is contained in:
2026-02-09 15:24:09 +01:00
parent 572629e62f
commit a65496d1de
4 changed files with 116 additions and 1 deletions

View File

@@ -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, users, chests
from app.routers import auth, users, chests, profiles
from app.middleware import IdempotencyMiddleware
@@ -17,6 +17,7 @@ app.add_middleware(IdempotencyMiddleware)
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(chests.router)
app.include_router(profiles.router)
@app.on_event("startup")
def startup_event():

View File

@@ -0,0 +1,48 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from app import schemas, models, database
from typing import List
router = APIRouter(
prefix="/profiles",
tags=["profiles"],
)
@router.get("/{nickname}", response_model=schemas.UserProfilePublic)
def get_public_profile(nickname: str, db: Session = Depends(database.get_db)):
profile = db.query(models.UserProfile).filter(models.UserProfile.nickname == nickname).first()
if not profile:
raise HTTPException(status_code=404, detail="User not found")
# We return the profile directly, which matches UserProfilePublic schema (nickname).
# But UserProfile model has created_at?
# Let's check model. UserProfile has keys: user_id, nickname, created_at?
# Actually models.UserProfile might not have created_at. Let's check.
# If not, we should rely on User.created_at or add it.
# For now assuming UserProfile has what we need or we fetch from User.
return profile
@router.get("/{nickname}/collection", response_model=List[schemas.UserCardResponse])
def get_public_collection(nickname: str, db: Session = Depends(database.get_db)):
# 1. Get User ID from nickname
profile = db.query(models.UserProfile).filter(models.UserProfile.nickname == nickname).first()
if not profile:
raise HTTPException(status_code=404, detail="User not found")
# 2. Get Collection
# Note: Privacy check would go here.
cards = db.query(models.UserCard).filter(models.UserCard.user_id == profile.user_id).all()
if not cards:
return []
# We need to reshape to UserCardResponse (card_name, rarity, obtained_at)
# models.UserCard has 'card' relationship.
response = []
for user_card in cards:
response.append({
"card_id": user_card.card_id,
"card_name": user_card.card.name,
"rarity": user_card.card.rarity,
"obtained_at": user_card.obtained_at
})
return response

View File

@@ -1,4 +1,5 @@
from pydantic import BaseModel, EmailStr
from datetime import datetime
class UserRegister(BaseModel):
email: EmailStr
@@ -33,3 +34,20 @@ class ChestOpenResponse(BaseModel):
chest_open_id: str
spent_gold: int
items: List[ChestOpenItemResponse]
class UserProfilePublic(BaseModel):
nickname: str
created_at: datetime
# Add other public fields here if needed
class Config:
from_attributes = True
class UserCardResponse(BaseModel):
card_id: str
card_name: str
rarity: str
obtained_at: datetime
class Config:
from_attributes = True

48
verify_profiles.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
set -e
echo "Logging in..."
TOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{"email":"test@example.com", "password":"password123"}' http://localhost:8000/auth/login | jq -r .access_token)
echo "Getting My Profile to find nickname..."
MY_PROFILE=$(curl -s -H "Authorization: Bearer $TOKEN" http://localhost:8000/me/profile)
NICKNAME=$(echo $MY_PROFILE | jq -r .nickname)
echo "My Nickname: $NICKNAME"
echo "--- Testing Public Profile ($NICKNAME) ---"
PUBLIC_PROFILE=$(curl -s http://localhost:8000/profiles/$NICKNAME)
echo "Public Profile: $PUBLIC_PROFILE"
CHECK_NICK=$(echo $PUBLIC_PROFILE | jq -r .nickname)
if [ "$CHECK_NICK" == "$NICKNAME" ]; then
echo "SUCCESS: Public profile nickname matches."
else
echo "FAILURE: Public profile nickname mismatch."
exit 1
fi
echo "--- Testing Public Collection ($NICKNAME) ---"
COLLECTION=$(curl -s http://localhost:8000/profiles/$NICKNAME/collection)
COUNT=$(echo $COLLECTION | jq '. | length')
echo "Collection count: $COUNT"
if [ "$COUNT" -ge 0 ]; then
echo "SUCCESS: Collection retrieved."
else
echo "FAILURE: Collection failed."
exit 1
fi
echo "--- Testing Non-Existent Profile ---"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/profiles/nonexistent_user_123)
echo "HTTP Code: $HTTP_CODE"
if [ "$HTTP_CODE" == "404" ]; then
echo "SUCCESS: Non-existent profile returned 404."
else
# wait, could be 500 if DB error?
echo "FAILURE: Non-existent profile returned $HTTP_CODE"
exit 1
fi
echo "ALL TESTS PASSED"