""" API маршруты для работы с пользователями, сообщениями и настройками """ from fastapi import APIRouter, Depends, HTTPException, status, Query from sqlalchemy.orm import Session from typing import List, Optional import sys import os # Добавляем путь к корневой директории проекта sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from database.database import db from database.models import User, Message, BotSettings from api.schemas import ( UserCreate, UserUpdate, UserResponse, MessageCreate, MessageResponse, BotSettingCreate, BotSettingUpdate, BotSettingResponse, MessageResponseModel, ErrorResponse ) # Зависимость для получения сессии БД def get_db(): """Получение сессии базы данных""" session = db.get_session_sync() try: yield session finally: session.close() # Роутер для работы с пользователями users_router = APIRouter(prefix="/users", tags=["Users"]) @users_router.get("/{telegram_id}", response_model=UserResponse) async def get_user_by_telegram_id(telegram_id: int, db_session: Session = Depends(get_db)): """Получение пользователя по Telegram ID""" user = db_session.query(User).filter(User.telegram_id == telegram_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Пользователь не найден" ) return user @users_router.get("/", response_model=List[UserResponse]) async def get_all_users( limit: int = Query(default=100, ge=1, le=1000), offset: int = Query(default=0, ge=0), is_active: Optional[bool] = Query(default=None), db_session: Session = Depends(get_db) ): """Получение списка всех пользователей с фильтрацией""" query = db_session.query(User) if is_active is not None: query = query.filter(User.is_active == is_active) users = query.offset(offset).limit(limit).all() return users @users_router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED) async def create_user(user_data: UserCreate, db_session: Session = Depends(get_db)): """Создание нового пользователя""" # Проверяем, существует ли уже пользователь existing_user = db_session.query(User).filter(User.telegram_id == user_data.telegram_id).first() if existing_user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Пользователь уже существует" ) # Создаем нового пользователя new_user = User(**user_data.model_dump()) db_session.add(new_user) db_session.commit() db_session.refresh(new_user) return new_user @users_router.put("/{telegram_id}", response_model=UserResponse) async def update_user( telegram_id: int, user_data: UserUpdate, db_session: Session = Depends(get_db) ): """Обновление данных пользователя""" user = db_session.query(User).filter(User.telegram_id == telegram_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Пользователь не найден" ) # Обновляем только переданные поля update_data = user_data.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(user, field, value) db_session.commit() db_session.refresh(user) return user @users_router.delete("/{telegram_id}", response_model=MessageResponseModel) async def delete_user(telegram_id: int, db_session: Session = Depends(get_db)): """Деактивация пользователя (мягкое удаление)""" user = db_session.query(User).filter(User.telegram_id == telegram_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Пользователь не найден" ) user.is_active = False db_session.commit() return MessageResponseModel(message="Пользователь деактивирован") # Роутер для работы с сообщениями messages_router = APIRouter(prefix="/messages", tags=["Messages"]) @messages_router.get("/", response_model=List[MessageResponse]) async def get_messages( user_id: Optional[int] = Query(default=None), message_type: Optional[str] = Query(default=None), limit: int = Query(default=100, ge=1, le=1000), offset: int = Query(default=0, ge=0), db_session: Session = Depends(get_db) ): """Получение сообщений с фильтрацией""" query = db_session.query(Message) if user_id: query = query.filter(Message.user_id == user_id) if message_type: query = query.filter(Message.message_type == message_type) messages = query.order_by(Message.created_at.desc()).offset(offset).limit(limit).all() return messages @messages_router.get("/{message_id}", response_model=MessageResponse) async def get_message(message_id: int, db_session: Session = Depends(get_db)): """Получение конкретного сообщения по ID""" message = db_session.query(Message).filter(Message.id == message_id).first() if not message: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Сообщение не найдено" ) return message @messages_router.post("/", response_model=MessageResponse, status_code=status.HTTP_201_CREATED) async def create_message(message_data: MessageCreate, db_session: Session = Depends(get_db)): """Создание нового сообщения""" # Проверяем, существует ли пользователь user = db_session.query(User).filter(User.id == message_data.user_id).first() if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Пользователь не найден" ) new_message = Message(**message_data.model_dump()) db_session.add(new_message) db_session.commit() db_session.refresh(new_message) return new_message # Роутер для работы с настройками бота settings_router = APIRouter(prefix="/settings", tags=["Bot Settings"]) @settings_router.get("/", response_model=dict) async def get_all_settings(db_session: Session = Depends(get_db)): """Получение всех настроек бота в виде словаря""" settings = db_session.query(BotSettings).all() return {setting.key: setting.value for setting in settings} @settings_router.get("/list", response_model=List[BotSettingResponse]) async def get_all_settings_list(db_session: Session = Depends(get_db)): """Получение всех настроек бота в виде списка объектов""" settings = db_session.query(BotSettings).all() return settings @settings_router.get("/{key}", response_model=BotSettingResponse) async def get_setting(key: str, db_session: Session = Depends(get_db)): """Получение конкретной настройки по ключу""" setting = db_session.query(BotSettings).filter(BotSettings.key == key).first() if not setting: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Настройка не найдена" ) return setting @settings_router.post("/", response_model=BotSettingResponse, status_code=status.HTTP_201_CREATED) async def create_or_update_setting( setting_data: BotSettingCreate, db_session: Session = Depends(get_db) ): """Создание или обновление настройки""" existing_setting = db_session.query(BotSettings).filter(BotSettings.key == setting_data.key).first() if existing_setting: # Обновляем существующую настройку update_data = setting_data.model_dump(exclude={"key"}) for field, value in update_data.items(): if value is not None: setattr(existing_setting, field, value) db_session.commit() db_session.refresh(existing_setting) return existing_setting else: # Создаем новую настройку new_setting = BotSettings(**setting_data.model_dump()) db_session.add(new_setting) db_session.commit() db_session.refresh(new_setting) return new_setting @settings_router.put("/{key}", response_model=BotSettingResponse) async def update_setting( key: str, setting_data: BotSettingUpdate, db_session: Session = Depends(get_db) ): """Обновление существующей настройки""" setting = db_session.query(BotSettings).filter(BotSettings.key == key).first() if not setting: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Настройка не найдена" ) update_data = setting_data.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(setting, field, value) db_session.commit() db_session.refresh(setting) return setting @settings_router.delete("/{key}", response_model=MessageResponseModel) async def delete_setting(key: str, db_session: Session = Depends(get_db)): """Удаление настройки""" setting = db_session.query(BotSettings).filter(BotSettings.key == key).first() if not setting: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Настройка не найдена" ) db_session.delete(setting) db_session.commit() return MessageResponseModel(message=f"Настройка '{key}' удалена")