286 lines
8.8 KiB
Python
286 lines
8.8 KiB
Python
from typing import Any, List, Dict
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy import func
|
|
|
|
from app import crud, models, schemas
|
|
from app.api import deps
|
|
from app.services.bot_simulation import get_bot_simulation_stats
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/users", response_model=List[schemas.User])
|
|
def read_users(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
) -> Any:
|
|
"""
|
|
Retrieve all users (admin only).
|
|
"""
|
|
users = db.query(models.User).offset(skip).limit(limit).all()
|
|
return users
|
|
|
|
|
|
@router.get("/users/{user_id}", response_model=schemas.User)
|
|
def read_user(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
user_id: int,
|
|
) -> Any:
|
|
"""
|
|
Get a specific user by ID (admin only).
|
|
"""
|
|
user = crud.user.get(db, id=user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
return user
|
|
|
|
|
|
@router.put("/users/{user_id}/activate", response_model=schemas.User)
|
|
def activate_user(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
user_id: int,
|
|
) -> Any:
|
|
"""
|
|
Activate a user (admin only).
|
|
"""
|
|
user = crud.user.get(db, id=user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
if user.is_active:
|
|
return user
|
|
|
|
updated_user = crud.user.update(db, db_obj=user, obj_in={"is_active": True})
|
|
return updated_user
|
|
|
|
|
|
@router.put("/users/{user_id}/deactivate", response_model=schemas.User)
|
|
def deactivate_user(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
user_id: int,
|
|
) -> Any:
|
|
"""
|
|
Deactivate a user (admin only).
|
|
"""
|
|
if user_id == current_user.id:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="You cannot deactivate your own account",
|
|
)
|
|
|
|
user = crud.user.get(db, id=user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
if not user.is_active:
|
|
return user
|
|
|
|
updated_user = crud.user.update(db, db_obj=user, obj_in={"is_active": False})
|
|
return updated_user
|
|
|
|
|
|
@router.get("/wallets/{user_id}", response_model=List[schemas.Wallet])
|
|
def read_user_wallets(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
user_id: int,
|
|
) -> Any:
|
|
"""
|
|
Get a specific user's wallets (admin only).
|
|
"""
|
|
user = crud.user.get(db, id=user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
wallets = crud.wallet.get_by_user(db, user_id=user_id)
|
|
return wallets
|
|
|
|
|
|
@router.put("/wallets/{wallet_id}/adjust", response_model=schemas.Wallet)
|
|
def adjust_wallet_balance(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
wallet_id: int,
|
|
amount: float,
|
|
description: str,
|
|
) -> Any:
|
|
"""
|
|
Adjust a wallet's balance (admin only).
|
|
"""
|
|
wallet = crud.wallet.get(db, id=wallet_id)
|
|
if not wallet:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Wallet not found",
|
|
)
|
|
|
|
# Check if adjustment would make balance negative
|
|
if wallet.balance + amount < 0:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Adjustment would result in negative balance",
|
|
)
|
|
|
|
# Update wallet balance
|
|
updated_wallet = crud.wallet.update_balance(
|
|
db, wallet_id=wallet_id, amount=abs(amount), add=(amount > 0)
|
|
)
|
|
|
|
# Create transaction record
|
|
crud.transaction.create(
|
|
db,
|
|
obj_in=schemas.TransactionCreate(
|
|
user_id=wallet.user_id,
|
|
wallet_id=wallet.id,
|
|
amount=amount,
|
|
transaction_type=models.TransactionType.ADMIN_ADJUSTMENT,
|
|
description=f"Admin adjustment: {description}",
|
|
),
|
|
)
|
|
|
|
return updated_wallet
|
|
|
|
|
|
@router.get("/transactions", response_model=List[schemas.Transaction])
|
|
def read_all_transactions(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
) -> Any:
|
|
"""
|
|
Retrieve all transactions (admin only).
|
|
"""
|
|
transactions = crud.transaction.get_all(db, skip=skip, limit=limit)
|
|
return transactions
|
|
|
|
|
|
@router.get("/statistics", response_model=Dict)
|
|
def get_statistics(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
) -> Any:
|
|
"""
|
|
Get platform statistics (admin only).
|
|
"""
|
|
# User statistics
|
|
total_users = db.query(func.count(models.User.id)).scalar()
|
|
active_users = db.query(func.count(models.User.id)).filter(models.User.is_active).scalar()
|
|
verified_users = db.query(func.count(models.User.id)).filter(models.User.is_verified).scalar()
|
|
kyc_verified_users = db.query(func.count(models.User.id)).filter(models.User.is_kyc_verified).scalar()
|
|
|
|
# Wallet statistics
|
|
total_spot_balance = db.query(func.sum(models.Wallet.balance)).filter(
|
|
models.Wallet.wallet_type == models.WalletType.SPOT
|
|
).scalar() or 0
|
|
|
|
total_trading_balance = db.query(func.sum(models.Wallet.balance)).filter(
|
|
models.Wallet.wallet_type == models.WalletType.TRADING
|
|
).scalar() or 0
|
|
|
|
# Deposit statistics
|
|
total_deposits = db.query(func.count(models.Deposit.id)).scalar()
|
|
pending_deposits = db.query(func.count(models.Deposit.id)).filter(
|
|
models.Deposit.status == models.DepositStatus.PENDING
|
|
).scalar()
|
|
approved_deposits = db.query(func.count(models.Deposit.id)).filter(
|
|
models.Deposit.status == models.DepositStatus.APPROVED
|
|
).scalar()
|
|
total_deposit_amount = db.query(func.sum(models.Deposit.amount)).filter(
|
|
models.Deposit.status == models.DepositStatus.APPROVED
|
|
).scalar() or 0
|
|
|
|
# Withdrawal statistics
|
|
total_withdrawals = db.query(func.count(models.Withdrawal.id)).scalar()
|
|
pending_withdrawals = db.query(func.count(models.Withdrawal.id)).filter(
|
|
models.Withdrawal.status == models.WithdrawalStatus.PENDING
|
|
).scalar()
|
|
approved_withdrawals = db.query(func.count(models.Withdrawal.id)).filter(
|
|
models.Withdrawal.status == models.WithdrawalStatus.APPROVED
|
|
).scalar()
|
|
total_withdrawal_amount = db.query(func.sum(models.Withdrawal.amount)).filter(
|
|
models.Withdrawal.status == models.WithdrawalStatus.APPROVED
|
|
).scalar() or 0
|
|
|
|
# Bot statistics
|
|
total_bots = db.query(func.count(models.Bot.id)).scalar()
|
|
active_bots = db.query(func.count(models.Bot.id)).filter(models.Bot.is_active).scalar()
|
|
bot_stats = get_bot_simulation_stats(db)
|
|
|
|
# KYC statistics
|
|
total_kyc = db.query(func.count(models.KYC.id)).scalar()
|
|
pending_kyc = db.query(func.count(models.KYC.id)).filter(
|
|
models.KYC.status == models.KYCStatus.PENDING
|
|
).scalar()
|
|
approved_kyc = db.query(func.count(models.KYC.id)).filter(
|
|
models.KYC.status == models.KYCStatus.APPROVED
|
|
).scalar()
|
|
rejected_kyc = db.query(func.count(models.KYC.id)).filter(
|
|
models.KYC.status == models.KYCStatus.REJECTED
|
|
).scalar()
|
|
|
|
return {
|
|
"users": {
|
|
"total": total_users,
|
|
"active": active_users,
|
|
"verified": verified_users,
|
|
"kyc_verified": kyc_verified_users,
|
|
},
|
|
"wallets": {
|
|
"total_spot_balance": total_spot_balance,
|
|
"total_trading_balance": total_trading_balance,
|
|
"total_platform_balance": total_spot_balance + total_trading_balance,
|
|
},
|
|
"deposits": {
|
|
"total": total_deposits,
|
|
"pending": pending_deposits,
|
|
"approved": approved_deposits,
|
|
"total_amount": total_deposit_amount,
|
|
},
|
|
"withdrawals": {
|
|
"total": total_withdrawals,
|
|
"pending": pending_withdrawals,
|
|
"approved": approved_withdrawals,
|
|
"total_amount": total_withdrawal_amount,
|
|
},
|
|
"bots": {
|
|
"total": total_bots,
|
|
"active": active_bots,
|
|
**bot_stats,
|
|
},
|
|
"kyc": {
|
|
"total": total_kyc,
|
|
"pending": pending_kyc,
|
|
"approved": approved_kyc,
|
|
"rejected": rejected_kyc,
|
|
},
|
|
} |