/
tsps
/
core
Обзор
Документация
Войти
/
tsps
/
core
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
app/api/admin/judges.py
150 строк
5 KB
Василий Петров
Разделение ролей - защита delete
24 мар 2026, 17:43
24 мар 2026, 17:43
8523537
Код
Авторство
О чём код?
from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session, joinedload from typing import Optional from app.database import get_db from app.models.judge import Judge from app.models.court import Court from app.schemas.judge import JudgeCreate, JudgeRead, JudgeUpdate from app.schemas.common import PaginationOut from app.core.security import get_current_admin_id, require_superadmin import logging logger = logging.getLogger(__name__) router = APIRouter( prefix="/judges", tags=["admin", "judges"], dependencies=[Depends(get_current_admin_id)] # защищаем все методы роутера ) def _get_judge_with_court(db: Session, judge_id: int) -> Judge: judge = db.query(Judge).options(joinedload(Judge.current_court)).filter(Judge.id == judge_id).first() return judge @router.post("", response_model=JudgeRead, status_code=status.HTTP_201_CREATED) def create_judge( judge_in: JudgeCreate, admin_id: int = Depends(get_current_admin_id), db: Session = Depends(get_db) ): if judge_in.current_court_id is not None: court = db.get(Court, judge_in.current_court_id) if not court: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Указанный суд не существует" ) judge = Judge(**judge_in.model_dump()) db.add(judge) try: db.commit() db.refresh(judge) logger.info(f"Админ {admin_id} создал судью: {judge.last_name} {judge.first_name} (ID={judge.id})") except IntegrityError: db.rollback() raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Ошибка целостности данных при создании судьи" ) # Загружаем с судом для ответа return _get_judge_with_court(db, judge.id) @router.get("", response_model=PaginationOut[JudgeRead]) def read_judges( skip: int = 0, limit: int = 100, last_name: Optional[str] = None, first_name: Optional[str] = None, court_id: Optional[int] = None, db: Session = Depends(get_db) ): query = db.query(Judge).options(joinedload(Judge.current_court)) if last_name: query = query.filter(Judge.last_name.ilike(f"%{last_name}%")) if first_name: query = query.filter(Judge.first_name.ilike(f"%{first_name}%")) if court_id is not None: query = query.filter(Judge.current_court_id == court_id) total = query.count() judges = query.order_by(Judge.id).offset(skip).limit(limit).all() return { "items": judges, "total": total, "skip": skip, "limit": limit } @router.get("/{judge_id}", response_model=JudgeRead) def read_judge(judge_id: int, db: Session = Depends(get_db)): judge = _get_judge_with_court(db, judge_id) if not judge: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Судья не найден" ) return judge @router.patch("/{judge_id}", response_model=JudgeRead) def update_judge( judge_id: int, judge_update: JudgeUpdate, admin_id: int = Depends(get_current_admin_id), db: Session = Depends(get_db) ): judge = db.get(Judge, judge_id) if not judge: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Судья не найден" ) update_data = judge_update.model_dump(exclude_unset=True) # обновляем только переданные поля if not update_data: return _get_judge_with_court(db, judge_id) if "current_court_id" in update_data and update_data["current_court_id"] is not None: court = db.get(Court, update_data["current_court_id"]) if not court: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Указанный суд не существует" ) try: for field, value in update_data.items(): setattr(judge, field, value) db.commit() db.refresh(judge) logger.info(f"Админ {admin_id} обновил судью: {judge.last_name} {judge.first_name} (ID={judge.id})") except IntegrityError: db.rollback() raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Ошибка целостности данных при обновлении судьи" ) return _get_judge_with_court(db, judge_id) @router.delete("/{judge_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_judge( judge_id: int, admin_id: int = Depends(require_superadmin), db: Session = Depends(get_db) ): judge = db.get(Judge, judge_id) if not judge: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Судья не найден" ) try: db.delete(judge) db.commit() logger.info(f"Админ {admin_id} удалил судью: {judge.last_name} {judge.first_name} (ID={judge.id})") except IntegrityError: db.rollback() raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Невозможно удалить судью: существуют связанные записи" ) return