""" Сервис для управления пользователями """ from datetime import datetime from typing import Optional, Tuple from aiogram.types import User as TelegramUser from models.user import User from services.infrastructure.database import DatabaseService from services.utils import UtilsService from services.infrastructure.logger import get_logger from services.infrastructure.metrics import get_metrics_service from services.infrastructure.logging_decorators import log_function_call, log_business_event from services.infrastructure.logging_utils import log_user_created, log_user_blocked logger = get_logger(__name__) class UserService: """Сервис для управления пользователями""" def __init__(self, database: DatabaseService, utils: UtilsService): self.database = database self.utils = utils self.metrics = get_metrics_service() @log_business_event("create_or_update_user", log_params=True, log_result=True) async def create_or_update_user(self, telegram_user: TelegramUser, chat_id: int) -> User: """ Создание или обновление пользователя Args: telegram_user: Объект пользователя из Telegram chat_id: ID чата Returns: Объект пользователя """ try: # Проверяем, существует ли пользователь existing_user = await self.database.get_user(telegram_user.id) if existing_user: # Обновляем существующего пользователя logger.info(f"👤 Обновление существующего пользователя {telegram_user.id}") self.metrics.increment_users("updated") return await self._update_existing_user(existing_user, telegram_user, chat_id) else: # Создаем нового пользователя logger.info(f"👤 Создание нового пользователя {telegram_user.id}") self.metrics.increment_users("created") return await self._create_new_user(telegram_user, chat_id) except Exception as e: logger.error(f"Ошибка при создании/обновлении пользователя {telegram_user.id}: {e}") raise @log_function_call(log_params=True, log_result=True) async def _update_existing_user(self, existing_user: User, telegram_user: TelegramUser, chat_id: int) -> User: """Обновление существующего пользователя""" existing_user.username = telegram_user.username existing_user.first_name = telegram_user.first_name or "Пользователь" existing_user.last_name = telegram_user.last_name existing_user.chat_id = chat_id existing_user.update_timestamp() return await self.database.update_user(existing_user) @log_function_call(log_params=True, log_result=True) async def _create_new_user(self, telegram_user: TelegramUser, chat_id: int) -> User: """Создание нового пользователя""" user = User( telegram_id=telegram_user.id, username=telegram_user.username, first_name=telegram_user.first_name or "Пользователь", last_name=telegram_user.last_name, chat_id=chat_id, profile_link=self.utils.generate_anonymous_id(), is_active=True, is_superuser=False, # Явно устанавливаем False для новых пользователей created_at=datetime.now(), updated_at=datetime.now() ) logger.info(f"👤 Создание нового пользователя {telegram_user.id} с is_superuser={user.is_superuser}") return await self.database.create_user(user) @log_function_call(log_params=True, log_result=True) async def get_user_by_profile_link(self, profile_link: str) -> Optional[User]: """ Получение пользователя по ссылке профиля Args: profile_link: Ссылка профиля Returns: Объект пользователя или None """ try: return await self.database.get_user_by_profile_link(profile_link) except Exception as e: logger.error(f"Ошибка при получении пользователя по ссылке {profile_link}: {e}") return None @log_function_call(log_params=True, log_result=True) async def get_user_by_telegram_id(self, telegram_id: int) -> Optional[User]: """ Получение пользователя по Telegram ID Args: telegram_id: ID пользователя в Telegram Returns: Объект пользователя или None """ try: return await self.database.get_user(telegram_id) except Exception as e: logger.error(f"Ошибка при получении пользователя {telegram_id}: {e}") return None @log_function_call(log_params=True, log_result=True) def generate_referral_link(self, bot_username: str, user: User) -> str: """ Генерация реферальной ссылки для пользователя Args: bot_username: Имя бота user: Объект пользователя Returns: Реферальная ссылка """ return self.utils.generate_referral_link(bot_username, user.profile_link) @log_function_call(log_params=True, log_result=True) async def is_user_blocked(self, blocker_id: int, blocked_id: int) -> bool: """ Проверка, заблокирован ли пользователь Args: blocker_id: ID пользователя, который блокирует blocked_id: ID пользователя, которого блокируют Returns: True если заблокирован, False иначе """ try: return await self.database.is_user_blocked(blocker_id, blocked_id) except Exception as e: logger.error(f"Ошибка при проверке блокировки {blocker_id} -> {blocked_id}: {e}") return False @log_business_event("block_user", log_params=True, log_result=True) async def block_user(self, blocker_id: int, blocked_id: int) -> bool: """ Блокировка пользователя Args: blocker_id: ID пользователя, который блокирует blocked_id: ID пользователя, которого блокируют Returns: True если успешно заблокирован """ try: await self.database.block_user(blocker_id, blocked_id) logger.info(f"Пользователь {blocked_id} заблокирован пользователем {blocker_id}") return True except Exception as e: logger.error(f"Ошибка при блокировке пользователя {blocked_id}: {e}") return False @log_business_event("unblock_user", log_params=True, log_result=True) async def unblock_user(self, blocker_id: int, blocked_id: int) -> bool: """ Разблокировка пользователя Args: blocker_id: ID пользователя, который разблокирует blocked_id: ID пользователя, которого разблокируют Returns: True если успешно разблокирован """ try: result = await self.database.unblock_user(blocker_id, blocked_id) if result: logger.info(f"Пользователь {blocked_id} разблокирован пользователем {blocker_id}") return result except Exception as e: logger.error(f"Ошибка при разблокировке пользователя {blocked_id}: {e}") return False @log_function_call(log_params=True, log_result=True) async def get_blocked_users(self, user_id: int) -> list: """ Получение списка заблокированных пользователей Args: user_id: ID пользователя Returns: Список ID заблокированных пользователей """ try: return await self.database.user_blocks.get_blocked_users(user_id) except Exception as e: logger.error(f"Ошибка при получении заблокированных пользователей для {user_id}: {e}") return []