import sys from fastapi import APIRouter, Depends, HTTPException from fastapi.exceptions import HTTPException from app.services import DatabaseManager from sqlalchemy.exc import SQLAlchemyError from instance.configdb import get_database_manager from pydantic import BaseModel from typing import Optional from uuid import UUID import logging logger = logging.getLogger(__name__) if not logger.handlers: handler = logging.StreamHandler(sys.stdout) handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')) logger.addHandler(handler) logger.setLevel(logging.INFO) logger.propagate = False router = APIRouter() # Модели запросов и ответов class CreateUserRequest(BaseModel): telegram_id: int invited_by: Optional[int] = None class UserResponse(BaseModel): telegram_id: int username: Optional[str] balance: float invited_by: Optional[int] = None created_at: str updated_at: str class AddReferal(BaseModel): invited_id: int @router.post("/user/create", response_model=UserResponse, summary="Создать пользователя") async def create_user( request: CreateUserRequest, db_manager: DatabaseManager = Depends(get_database_manager) ): """ Создание пользователя через Telegram ID. """ try: user = await db_manager.create_user(request.telegram_id,request.invited_by) if user == None: raise HTTPException(status_code=500, detail="Failed to create user") return UserResponse( telegram_id=user.telegram_id, username=user.username, balance=user.balance, invited_by=user.invited_by if user.invited_by is not None else None, created_at=user.created_at.isoformat(), updated_at=user.updated_at.isoformat() ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/user/{telegram_id}", response_model=UserResponse, summary="Получить информацию о пользователе") async def get_user( telegram_id: int, db_manager: DatabaseManager = Depends(get_database_manager) ): """ Получение информации о пользователе. """ try: print(f"Получение пользователя с telegram_id: {telegram_id}") user = await db_manager.get_user_by_telegram_id(telegram_id) if not user: logger.warning(f"Пользователь с telegram_id {telegram_id} не найден.") raise HTTPException(status_code=404, detail="User not found") print(f"Пользователь найден: ID={user.telegram_id}, Username={user.username}") user_response = UserResponse( telegram_id=user.telegram_id, username=user.username, balance=user.balance, invited_by=user.invited_by if user.invited_by is not None else None, created_at=user.created_at.isoformat(), updated_at=user.updated_at.isoformat() ) return user_response except HTTPException as http_ex: # Позволяет обработать HTTPException отдельно raise http_ex except SQLAlchemyError as e: logger.error(f"Ошибка базы данных при получении пользователя с telegram_id {telegram_id}: {e}") raise HTTPException(status_code=500, detail="Database error") except Exception as e: logger.exception(f"Неожиданная ошибка при получении пользователя с telegram_id {telegram_id}: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/user/{telegram_id}/balance/{amount}", summary="Обновить баланс") async def update_balance( telegram_id: int, amount: float, db_manager: DatabaseManager = Depends(get_database_manager) ): """ Обновляет баланс пользователя. """ logger.info(f"Получен запрос на обновление баланса: telegram_id={telegram_id}, amount={amount}") try: result = await db_manager.update_balance(telegram_id, amount) if result == "ERROR": logger.error(f"Ошибка обновления баланса для пользователя {telegram_id}") raise HTTPException(status_code=500, detail="Failed to update balance") logger.info(f"Баланс пользователя {telegram_id} успешно обновлен на {amount}") return {"message": "Balance updated successfully"} except HTTPException as http_ex: logger.warning(f"HTTP ошибка: {http_ex.detail}") raise http_ex except SQLAlchemyError as db_ex: logger.error(f"Ошибка базы данных при обновлении баланса пользователя {telegram_id}: {db_ex}") raise HTTPException(status_code=500, detail="Database error") except Exception as e: logger.exception(f"Неожиданная ошибка при обновлении баланса пользователя {telegram_id}: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/user/{telegram_id}/transactions", summary="Последние транзакции пользователя") async def last_transactions( telegram_id: int, db_manager: DatabaseManager = Depends(get_database_manager) ): """ Возвращает список последних транзакций пользователя. """ logger.info(f"Получен запрос на транзакции для пользователя: {telegram_id}") try: logger.debug(f"Вызов метода get_transaction с user_id={telegram_id}") transactions = await db_manager.get_transaction(telegram_id) if transactions == "ERROR": logger.error(f"Ошибка при получении транзакций для пользователя: {telegram_id}") raise HTTPException(status_code=500, detail="Failed to fetch transactions") if transactions == None: response = [] logger.info(f"Формирование ответа для пользователя {telegram_id}: {response}") return response logger.debug(f"Транзакции для {telegram_id}: {transactions}") response = [ { "id": tx.id, "amount": tx.amount, "created_at": tx.created_at.isoformat(), "type": tx.type, } for tx in transactions ] logger.info(f"Формирование ответа для пользователя {telegram_id}: {response}") return response except HTTPException as http_ex: logger.warning(f"HTTP ошибка для {telegram_id}: {http_ex.detail}") raise http_ex except SQLAlchemyError as db_ex: logger.error(f"Ошибка базы данных для {telegram_id}: {db_ex}") raise HTTPException(status_code=500, detail="Database error") except Exception as e: logger.exception(f"Неожиданная ошибка для {telegram_id}: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/user/{referrer_id}/add_referral", summary="Обновить баланс") async def add_referal( referrer_id: int, request: AddReferal, db_manager: DatabaseManager = Depends(get_database_manager) ): """ Обновляет баланс пользователя. """ logger.info(f"Получен запрос на добавление реферала: telegram_id={referrer_id}") try: result = await db_manager.add_referal(referrer_id,request.invited_id) if result == "ERROR": logger.error(f"Ошибка добавления реферала для {referrer_id} c айди {request.invited_id}") raise HTTPException(status_code=500, detail="Failed to update balance") logger.info(f"Добавлен реферал для {referrer_id} c айди {request.invited_id}") return {"message": "Balance updated successfully"} except HTTPException as http_ex: logger.warning(f"HTTP ошибка: {http_ex.detail}") raise http_ex except SQLAlchemyError as db_ex: logger.error(f"Ошибка базы данных при добавлении рефералу {referrer_id}: {db_ex}") raise HTTPException(status_code=500, detail="Database error") except Exception as e: logger.exception(f"Неожиданная ошибка при добавлении рефералу {referrer_id}: {e}") raise HTTPException(status_code=500, detail=str(e))