diff --git a/app/__pycache__/main.cpython-311.pyc b/app/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000..5572d01 Binary files /dev/null and b/app/__pycache__/main.cpython-311.pyc differ diff --git a/app/api/v1/__pycache__/api.cpython-311.pyc b/app/api/v1/__pycache__/api.cpython-311.pyc new file mode 100644 index 0000000..fe45d93 Binary files /dev/null and b/app/api/v1/__pycache__/api.cpython-311.pyc differ diff --git a/app/api/v1/endpoints/__pycache__/games.cpython-311.pyc b/app/api/v1/endpoints/__pycache__/games.cpython-311.pyc new file mode 100644 index 0000000..488cfb6 Binary files /dev/null and b/app/api/v1/endpoints/__pycache__/games.cpython-311.pyc differ diff --git a/app/api/v1/endpoints/games.py b/app/api/v1/endpoints/games.py index b3633cb..fdeaa56 100644 --- a/app/api/v1/endpoints/games.py +++ b/app/api/v1/endpoints/games.py @@ -1,28 +1,95 @@ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session +from sqlalchemy import or_, String from typing import List, Optional +import re +import unicodedata from app.schemas.game import GameCreate, GameUpdate, GameResponse, StandardResponse +from app.models.game import Game from app.db.database import get_db router = APIRouter() +def generate_slug(title: str) -> str: + # Remove acentos + text = unicodedata.normalize('NFKD', title).encode('ASCII', 'ignore').decode('utf-8') + # Transforma para lowercase e substitui espaços por hifens + text = text.lower() + # Remove caracteres especiais + text = re.sub(r'[^a-z0-9\-]', '-', text) + # Remove hifens duplicados + text = re.sub(r'-+', '-', text).strip('-') + return text + @router.get("/", response_model=StandardResponse) def read_games(skip: int = 0, limit: int = 100, genre: Optional[str] = None, platform: Optional[str] = None, db: Session = Depends(get_db)): - # Lógica de listagem e filtragem será implementada aqui - return {"success": True, "message": "Lista de jogos", "data": []} + query = db.query(Game) + + if genre: + query = query.filter(Game.genres.cast(String).ilike(f'%"{genre}"%')) + + if platform: + query = query.filter(Game.platforms.cast(String).ilike(f'%"{platform}"%')) + + games = query.offset(skip).limit(limit).all() + data = [GameResponse.model_validate(g).model_dump() for g in games] + + return {"success": True, "message": "Lista de jogos", "data": data} @router.post("/", response_model=StandardResponse, status_code=status.HTTP_201_CREATED) def create_game(game: GameCreate, db: Session = Depends(get_db)): - # Lógica de criação será implementada aqui - return {"success": True, "message": "Jogo criado com sucesso", "data": {}} + slug = generate_slug(game.title) + + # Verifica se já existe um jogo com esse slug + db_game = db.query(Game).filter(Game.slug == slug).first() + if db_game: + raise HTTPException(status_code=400, detail="Um jogo com este título/slug já existe.") + + # Cria o modelo no DB + game_data = game.model_dump() + db_game = Game(**game_data, slug=slug) + + db.add(db_game) + db.commit() + db.refresh(db_game) + + data = GameResponse.model_validate(db_game).model_dump() + return {"success": True, "message": "Jogo criado com sucesso", "data": data} @router.get("/{id_ou_slug}", response_model=StandardResponse) def read_game(id_ou_slug: str, db: Session = Depends(get_db)): - # Lógica de leitura de um único jogo será implementada aqui - return {"success": True, "message": "Detalhes do jogo", "data": {}} + db_game = db.query(Game).filter(or_(Game.id == id_ou_slug, Game.slug == id_ou_slug)).first() + + if not db_game: + raise HTTPException(status_code=404, detail="Jogo não encontrado.") + + data = GameResponse.model_validate(db_game).model_dump() + return {"success": True, "message": "Detalhes do jogo", "data": data} @router.patch("/{id}", response_model=StandardResponse) def update_game(id: str, game: GameUpdate, db: Session = Depends(get_db)): - # Lógica de atualização parcial será implementada aqui - return {"success": True, "message": "Jogo atualizado com sucesso", "data": {}} + db_game = db.query(Game).filter(Game.id == id).first() + + if not db_game: + raise HTTPException(status_code=404, detail="Jogo não encontrado.") + + update_data = game.model_dump(exclude_unset=True) + + if "title" in update_data: + new_slug = generate_slug(update_data["title"]) + # Verifica se o novo slug conflita com outro jogo existente + existing_slug = db.query(Game).filter(Game.slug == new_slug, Game.id != id).first() + if existing_slug: + raise HTTPException(status_code=400, detail="Um jogo com este título/slug já existe.") + db_game.slug = new_slug + + for key, value in update_data.items(): + setattr(db_game, key, value) + + db.add(db_game) + db.commit() + db.refresh(db_game) + + data = GameResponse.model_validate(db_game).model_dump() + return {"success": True, "message": "Jogo atualizado com sucesso", "data": data} diff --git a/app/core/__pycache__/config.cpython-311.pyc b/app/core/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000..066ba76 Binary files /dev/null and b/app/core/__pycache__/config.cpython-311.pyc differ diff --git a/app/db/__pycache__/database.cpython-311.pyc b/app/db/__pycache__/database.cpython-311.pyc new file mode 100644 index 0000000..23246f1 Binary files /dev/null and b/app/db/__pycache__/database.cpython-311.pyc differ diff --git a/app/models/__pycache__/game.cpython-311.pyc b/app/models/__pycache__/game.cpython-311.pyc new file mode 100644 index 0000000..9432483 Binary files /dev/null and b/app/models/__pycache__/game.cpython-311.pyc differ diff --git a/app/schemas/__pycache__/game.cpython-311.pyc b/app/schemas/__pycache__/game.cpython-311.pyc new file mode 100644 index 0000000..9f47806 Binary files /dev/null and b/app/schemas/__pycache__/game.cpython-311.pyc differ