Skip to content

Commit 2b56779

Browse files
authored
Create routes_atletas.py
1 parent c8c578d commit 2b56779

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

app/api/v1/routes_atletas.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from fastapi import APIRouter, Depends, Query, HTTPException
2+
from fastapi_pagination.limit_offset import LimitOffsetPage
3+
from fastapi_pagination import Params
4+
from sqlalchemy.ext.asyncio import AsyncSession
5+
from typing import List
6+
7+
from app.schemas.atleta import AtletaCreate, AtletaRead
8+
from app.repositories.atleta_repo import AtletaRepository
9+
from app.services.atleta_service import AtletaService
10+
from app.api.deps import get_session
11+
12+
router = APIRouter(prefix="/v1/atletas", tags=["Atletas"])
13+
14+
@router.get("/", response_model=LimitOffsetPage[AtletaRead])
15+
async def list_atletas(
16+
nome: str | None = Query(None, description="Filtrar por nome (contains)"),
17+
cpf: str | None = Query(None, description="Filtrar por CPF exato"),
18+
limit: int = Query(10, ge=1, description="Quantidade máxima de itens (limit)"),
19+
offset: int = Query(0, ge=0, description="Offset de paginação"),
20+
session: AsyncSession = Depends(get_session),
21+
):
22+
"""
23+
Lista atletas com filtros opcionais (nome, cpf) e paginação via limit e offset.
24+
Response customizada incluirá nome, centro_treinamento e categoria.
25+
"""
26+
repo = AtletaRepository(session)
27+
service = AtletaService(repo)
28+
total = await service.count(nome=nome, cpf=cpf)
29+
items = await service.list(nome=nome, cpf=cpf, limit=limit, offset=offset)
30+
31+
# Mapeia os objetos ORM para schema AtletaRead (Pydantic com orm_mode)
32+
# fastapi-pagination fornece create to build LimitOffsetPage
33+
return LimitOffsetPage.create(items=items, total=total, params=Params(limit=limit, offset=offset))
34+
35+
@router.post("/", response_model=AtletaRead, status_code=201)
36+
async def create_atleta(payload: AtletaCreate, session: AsyncSession = Depends(get_session)):
37+
"""
38+
Cria um atleta. Em caso de violação de integridade (CPF duplicado),
39+
um IntegrityError será lançado e tratado pelo handler global, retornando status 303.
40+
"""
41+
repo = AtletaRepository(session)
42+
service = AtletaService(repo)
43+
try:
44+
atleta = await service.create(payload)
45+
# prepara leitura com nome centro e categoria
46+
read = AtletaRead.from_orm(atleta)
47+
if atleta.categoria:
48+
read.categoria = atleta.categoria.nome
49+
if atleta.centro:
50+
read.centro_treinamento = atleta.centro.nome
51+
return read
52+
except Exception as exc:
53+
# IntegrityError será tratado pelo handler global; outros erros viram 400
54+
if hasattr(exc, "__cause__") and "IntegrityError" in str(type(exc.__cause__)):
55+
raise exc.__cause__
56+
raise HTTPException(status_code=400, detail=str(exc))

0 commit comments

Comments
 (0)