from fastapi import APIRouter, Depends, HTTPException, status from sqlmodel import Session, select from app.connection import get_session from app.models.hackathon import Hackathon from app.models.hackathon_participant import HackathonParticipant from app.models.user import User from app.schemas.hackathon import ( HackathonCreate, HackathonRead, HackathonReadWithOrganizer, ParticipantRegistration, ParticipantRead, ParticipantConfirm, ) from app.auth.dependencies import get_current_user, get_current_organizer router = APIRouter(prefix="/hackathons", tags=["Hackathons"]) # ── CRUD ──────────────────────────────────────────────────────────────────── @router.post("/", response_model=HackathonRead, status_code=status.HTTP_201_CREATED) def create_hackathon( data: HackathonCreate, session: Session = Depends(get_session), organizer: User = Depends(get_current_organizer), ) -> Hackathon: hackathon = Hackathon(**data.model_dump(), organizer_id=organizer.id) session.add(hackathon) session.commit() session.refresh(hackathon) return hackathon @router.get("/", response_model=list[HackathonRead]) def list_hackathons(session: Session = Depends(get_session)) -> list[Hackathon]: return list(session.exec(select(Hackathon)).all()) @router.get("/{hackathon_id}", response_model=HackathonReadWithOrganizer) def get_hackathon(hackathon_id: int, session: Session = Depends(get_session)) -> Hackathon: hackathon = session.get(Hackathon, hackathon_id) if not hackathon: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Хакатон не найден") return hackathon @router.delete("/{hackathon_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_hackathon( hackathon_id: int, session: Session = Depends(get_session), organizer: User = Depends(get_current_organizer), ) -> None: hackathon = session.get(Hackathon, hackathon_id) if not hackathon: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Хакатон не найден") session.delete(hackathon) session.commit() # ── Регистрация участников ────────────────────────────────────────────────── @router.post("/{hackathon_id}/register", response_model=ParticipantRead, status_code=status.HTTP_201_CREATED) def register_for_hackathon( hackathon_id: int, session: Session = Depends(get_session), current_user: User = Depends(get_current_user), ) -> HackathonParticipant: hackathon = session.get(Hackathon, hackathon_id) if not hackathon: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Хакатон не найден") existing = session.exec( select(HackathonParticipant).where( HackathonParticipant.user_id == current_user.id, HackathonParticipant.hackathon_id == hackathon_id, ) ).first() if existing: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Вы уже зарегистрированы") participant = HackathonParticipant( user_id=current_user.id, hackathon_id=hackathon_id, ) session.add(participant) session.commit() session.refresh(participant) return participant @router.get("/{hackathon_id}/participants", response_model=list[ParticipantRead]) def list_participants( hackathon_id: int, session: Session = Depends(get_session), ) -> list[HackathonParticipant]: return list( session.exec( select(HackathonParticipant).where(HackathonParticipant.hackathon_id == hackathon_id) ).all() ) @router.patch("/{hackathon_id}/confirm", response_model=ParticipantRead) def confirm_participant( hackathon_id: int, data: ParticipantConfirm, session: Session = Depends(get_session), organizer: User = Depends(get_current_organizer), ) -> HackathonParticipant: """Организатор подтверждает регистрацию участника.""" participant = session.exec( select(HackathonParticipant).where( HackathonParticipant.user_id == data.user_id, HackathonParticipant.hackathon_id == hackathon_id, ) ).first() if not participant: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Регистрация не найдена") participant.is_confirmed = True session.add(participant) session.commit() session.refresh(participant) return participant