- FastAPI REST API with JWT auth - aiogram 3 Telegram bot with admin middleware - APScheduler daily tasks (expiry, reminders, revoke, sync) - SQLAlchemy 2 async ORM with Alembic migrations - Jinja2 admin panel (Dashboard, Users, Payments, Servers, Tariffs) - VPN provider abstraction with MockProvider - Stats service with revenue/subscription analytics - Docker Compose (PostgreSQL + Redis + app) - Healthcheck endpoint
86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
from datetime import datetime
|
|
|
|
from loguru import logger
|
|
|
|
from app.models.user import User
|
|
from app.repositories.user import UserRepository
|
|
|
|
|
|
class UserService:
|
|
def __init__(self, user_repo: UserRepository):
|
|
self.user_repo = user_repo
|
|
|
|
async def register(
|
|
self,
|
|
telegram_id: int,
|
|
username: str | None,
|
|
full_name: str,
|
|
language_code: str,
|
|
) -> User:
|
|
user = await self.user_repo.get_by_telegram_id(telegram_id)
|
|
if user is not None:
|
|
user = await self.user_repo.update(
|
|
user.id,
|
|
username=username,
|
|
full_name=full_name,
|
|
language_code=language_code,
|
|
)
|
|
logger.debug("User profile updated: tg={}", telegram_id)
|
|
return user
|
|
|
|
user = await self.user_repo.create(
|
|
telegram_id=telegram_id,
|
|
username=username,
|
|
full_name=full_name,
|
|
language_code=language_code,
|
|
)
|
|
logger.info("New user registered: tg={} id={}", telegram_id, user.id)
|
|
return user
|
|
|
|
async def get_or_create(
|
|
self,
|
|
telegram_id: int,
|
|
username: str | None = None,
|
|
full_name: str = "",
|
|
language_code: str = "ru",
|
|
) -> User:
|
|
user = await self.user_repo.get_by_telegram_id(telegram_id)
|
|
if user is not None:
|
|
return user
|
|
return await self.user_repo.create(
|
|
telegram_id=telegram_id,
|
|
username=username,
|
|
full_name=full_name or str(telegram_id),
|
|
language_code=language_code,
|
|
)
|
|
|
|
async def get_by_id(self, user_id: int) -> User | None:
|
|
return await self.user_repo.get(user_id)
|
|
|
|
async def get_by_telegram_id(self, telegram_id: int) -> User | None:
|
|
return await self.user_repo.get_by_telegram_id(telegram_id)
|
|
|
|
async def update(self, user_id: int, **kwargs) -> User | None:
|
|
return await self.user_repo.update(user_id, **kwargs)
|
|
|
|
async def deactivate(self, user_id: int) -> bool:
|
|
user = await self.user_repo.update(user_id, is_active=False)
|
|
if user:
|
|
logger.info("User deactivated: id={}", user_id)
|
|
return True
|
|
return False
|
|
|
|
async def activate(self, user_id: int) -> bool:
|
|
user = await self.user_repo.update(user_id, is_active=True)
|
|
if user:
|
|
logger.info("User activated: id={}", user_id)
|
|
return True
|
|
return False
|
|
|
|
async def get_active_count(self) -> int:
|
|
users = await self.user_repo.get_active_users()
|
|
return len(users)
|
|
|
|
async def get_registered_since(self, since: datetime) -> list[User]:
|
|
return await self.user_repo.get_by_created_range(since, datetime.utcnow())
|