Files
vpn-control-panel/app/api/v1/users.py
smolkik-code 7c7c88621d Initial commit: VPN Control Panel
- 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
2026-07-05 17:50:11 +07:00

84 lines
2.5 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from app.api.deps import (
get_user_service,
get_billing_service,
)
from app.schemas.user import UserRead, UserUpdate
from app.services import UserService, BillingService
router = APIRouter(prefix="/users", tags=["Users"])
@router.get("/{user_id}", response_model=UserRead)
async def get_user(
user_id: int,
user_svc: UserService = Depends(get_user_service),
):
user = await user_svc.get_by_id(user_id)
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user
@router.patch("/{user_id}", response_model=UserRead)
async def update_user(
user_id: int,
body: UserUpdate,
user_svc: UserService = Depends(get_user_service),
):
user = await user_svc.update(user_id, **body.model_dump(exclude_unset=True))
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user
@router.post("/{user_id}/deactivate", response_model=UserRead)
async def deactivate_user(
user_id: int,
user_svc: UserService = Depends(get_user_service),
):
ok = await user_svc.deactivate(user_id)
if not ok:
raise HTTPException(status_code=404, detail="User not found")
return await user_svc.get_by_id(user_id)
@router.post("/{user_id}/activate", response_model=UserRead)
async def activate_user(
user_id: int,
user_svc: UserService = Depends(get_user_service),
):
ok = await user_svc.activate(user_id)
if not ok:
raise HTTPException(status_code=404, detail="User not found")
return await user_svc.get_by_id(user_id)
@router.get("/by-telegram/{telegram_id}", response_model=UserRead)
async def get_user_by_telegram(
telegram_id: int,
user_svc: UserService = Depends(get_user_service),
):
user = await user_svc.get_by_telegram_id(telegram_id)
if user is None:
raise HTTPException(status_code=404, detail="User not found")
return user
@router.get("/{user_id}/subscription")
async def get_user_subscription(
user_id: int,
billing_svc: BillingService = Depends(get_billing_service),
):
info = await billing_svc.get_active_subscription(user_id)
if info is None:
raise HTTPException(status_code=404, detail="User not found")
return {
"is_active": info.is_active,
"tariff_name": info.tariff.name if info.tariff else None,
"start_date": info.start_date,
"end_date": info.end_date,
"remaining_days": info.remaining_days,
}