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 sqlalchemy import text
from app.database import get_db, engine from app.database import get_db, engine
from app import models, seed 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 from app.middleware import IdempotencyMiddleware
@@ -17,6 +17,7 @@ app.add_middleware(IdempotencyMiddleware)
app.include_router(auth.router) app.include_router(auth.router)
app.include_router(users.router) app.include_router(users.router)
app.include_router(chests.router) app.include_router(chests.router)
app.include_router(profiles.router)
@app.on_event("startup") @app.on_event("startup")
def startup_event(): 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 pydantic import BaseModel, EmailStr
from datetime import datetime
class UserRegister(BaseModel): class UserRegister(BaseModel):
email: EmailStr email: EmailStr
@@ -33,3 +34,20 @@ class ChestOpenResponse(BaseModel):
chest_open_id: str chest_open_id: str
spent_gold: int spent_gold: int
items: List[ChestOpenItemResponse] 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"