from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession from api.deps import get_current_superuser from database.models import Seat, Tournament, User from database.session import get_db from schemas.tournament import SeatGenerateRequest, TournamentCreate, TournamentResponse router = APIRouter(prefix="/api/tournaments", tags=["tournaments"]) @router.post("", response_model=TournamentResponse, status_code=status.HTTP_201_CREATED) async def create_tournament( body: TournamentCreate, current_user: User = Depends(get_current_superuser), db: AsyncSession = Depends(get_db), ) -> Tournament: tournament = Tournament( title=body.title, description=body.description, event_date=body.event_date, ) db.add(tournament) await db.commit() await db.refresh(tournament) return tournament @router.post( "/{tournament_id}/generate-seats", status_code=status.HTTP_200_OK, ) async def generate_seats( tournament_id: int, request: SeatGenerateRequest, current_user: User = Depends(get_current_superuser), db: AsyncSession = Depends(get_db), ) -> dict[str, str]: # 1. Проверяем существование турнира result = await db.execute(select(Tournament).where(Tournament.id == tournament_id)) tournament: Tournament | None = result.scalar_one_or_none() if tournament is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Tournament not found") # 2. Проверяем, что места ещё не генерировались (защита от дублей) count_result = await db.execute( select(func.count()).where(Seat.tournament_id == tournament_id) ) existing_count: int = count_result.scalar_one() if existing_count > 0: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Места уже сгенерированы", ) # 3. Генерируем места для каждого сектора seats: list[Seat] = [] for sector_cfg in request.sectors: for row in range(1, sector_cfg.rows + 1): for number in range(1, sector_cfg.seats_per_row + 1): seats.append( Seat( tournament_id=tournament_id, sector=sector_cfg.sector_name, row=row, number=number, price=sector_cfg.price, ) ) # 4. Массовая вставка db.add_all(seats) await db.commit() return {"message": f"Generated {len(seats)} seats successfully"}