This commit is contained in:
Artem Tsyrulnikov
2026-04-06 19:27:27 +03:00
commit 477ddb8bf9
38 changed files with 1916 additions and 0 deletions

127
app/routers/hackathons.py Normal file
View File

@@ -0,0 +1,127 @@
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