Files
backend/app/routes/user_routes.py

211 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
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.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 = []
for tx in transactions:
# Проверяем, что транзакция существует и имеет created_at
if tx is None:
continue
if tx.status.value == "pending":
continue
# Обрабатываем created_at (может быть None)
created_at_str = None
if tx.created_at:
created_at_str = tx.created_at.isoformat()
else:
created_at_str = datetime.utcnow().isoformat() # или любое значение по умолчанию
response.append({
"id": tx.id,
"amount": float(tx.amount) if tx.amount else 0.0,
"created_at": created_at_str,
"type": tx.type.value if hasattr(tx.type, 'value') else str(tx.type),
})
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))
@router.get("/user/{telegram_id}/referrals", summary="Получить колво рефералов")
async def get_referral_count(
telegram_id: int,
db_manager: DatabaseManager = Depends(get_database_manager)
):
try:
result = await db_manager.get_referrals_count(telegram_id)
if result == "ERROR":
logger.error(f"Ошибка получения рефералов для пользователя: {telegram_id}")
raise HTTPException(status_code=500, detail="Failed to get referrals")
logger.info(f"Количество приглашённых {result}")
return {"invited_count": result}
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))