from fastapi import FastAPI, Depends, HTTPException from sqlalchemy.orm import Session from pydantic import BaseModel from typing import List, Optional import sys import os sys.path.append(os.path.join(os.path.dirname(__file__), "../../../shared")) from database.connection import get_db from database.models import Player, GameSession app = FastAPI(title="Player Service", version="1.0.0") class PlayerCreate(BaseModel): name: str email: Optional[str] = None class PlayerResponse(BaseModel): id: int name: str email: Optional[str] = None created_at: str class PlayerStats(BaseModel): player_id: int player_name: str total_games: int best_score: int average_score: float total_questions_answered: int @app.get("/health") def health_check(): return {"status": "healthy", "service": "player-service"} @app.post("/", response_model=PlayerResponse) def create_or_get_player(player_data: PlayerCreate, db: Session = Depends(get_db)): existing_player = db.query(Player).filter(Player.name == player_data.name).first() if existing_player: return PlayerResponse( id=existing_player.id, name=existing_player.name, email=existing_player.email, created_at=str(existing_player.created_at) ) player = Player(name=player_data.name, email=player_data.email) db.add(player) db.commit() db.refresh(player) return PlayerResponse( id=player.id, name=player.name, email=player.email, created_at=str(player.created_at) ) @app.get("/{player_id}", response_model=PlayerResponse) def get_player(player_id: int, db: Session = Depends(get_db)): player = db.query(Player).filter(Player.id == player_id).first() if not player: raise HTTPException(status_code=404, detail="Player not found") return PlayerResponse( id=player.id, name=player.name, email=player.email, created_at=str(player.created_at) ) @app.get("/{player_id}/stats", response_model=PlayerStats) def get_player_stats(player_id: int, db: Session = Depends(get_db)): player = db.query(Player).filter(Player.id == player_id).first() if not player: raise HTTPException(status_code=404, detail="Player not found") sessions = db.query(GameSession).filter( GameSession.player_id == player_id, GameSession.ended_at.isnot(None) ).all() if not sessions: return PlayerStats( player_id=player.id, player_name=player.name, total_games=0, best_score=0, average_score=0.0, total_questions_answered=0 ) total_games = len(sessions) best_score = max(session.total_score for session in sessions) average_score = sum(session.total_score for session in sessions) / total_games total_questions = sum(session.questions_answered for session in sessions) return PlayerStats( player_id=player.id, player_name=player.name, total_games=total_games, best_score=best_score, average_score=round(average_score, 2), total_questions_answered=total_questions ) @app.get("/", response_model=List[PlayerResponse]) def list_players(limit: int = 50, db: Session = Depends(get_db)): players = db.query(Player).limit(limit).all() return [ PlayerResponse( id=player.id, name=player.name, email=player.email, created_at=str(player.created_at) ) for player in players ] if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8003)