207 lines
6.0 KiB
Python
207 lines
6.0 KiB
Python
from typing import Any, List
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app import crud, models, schemas
|
|
from app.api import deps
|
|
from app.models.transaction import TransactionType
|
|
from app.models.wallet import WalletType
|
|
from app.services.file_upload import save_deposit_proof
|
|
from app.core.email import send_deposit_confirmation
|
|
from app.core.config import settings
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/request", response_model=schemas.Deposit)
|
|
async def create_deposit_request(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_active_verified_user),
|
|
amount: float = Form(...),
|
|
transaction_hash: str = Form(...),
|
|
proof_image: UploadFile = File(...),
|
|
) -> Any:
|
|
"""
|
|
Create a new deposit request.
|
|
"""
|
|
# Validate minimum deposit amount
|
|
if amount < settings.MIN_DEPOSIT_AMOUNT:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Minimum deposit amount is {settings.MIN_DEPOSIT_AMOUNT} USDT",
|
|
)
|
|
|
|
# Save proof image
|
|
proof_image_path = save_deposit_proof(current_user.id, proof_image)
|
|
|
|
# Create deposit request
|
|
deposit_in = schemas.DepositCreate(
|
|
user_id=current_user.id,
|
|
amount=amount,
|
|
transaction_hash=transaction_hash,
|
|
)
|
|
deposit = crud.deposit.create(db, obj_in=deposit_in)
|
|
|
|
# Update deposit with proof image path
|
|
crud.deposit.update(db, db_obj=deposit, obj_in={"proof_image_path": proof_image_path})
|
|
|
|
return deposit
|
|
|
|
|
|
@router.get("/", response_model=List[schemas.Deposit])
|
|
def read_deposits(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_active_verified_user),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
) -> Any:
|
|
"""
|
|
Retrieve user's deposit requests.
|
|
"""
|
|
deposits = crud.deposit.get_by_user(db, user_id=current_user.id, skip=skip, limit=limit)
|
|
return deposits
|
|
|
|
|
|
@router.get("/{deposit_id}", response_model=schemas.Deposit)
|
|
def read_deposit(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_active_verified_user),
|
|
deposit_id: int,
|
|
) -> Any:
|
|
"""
|
|
Get a specific deposit by ID.
|
|
"""
|
|
deposit = crud.deposit.get(db, id=deposit_id)
|
|
if not deposit:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Deposit not found",
|
|
)
|
|
|
|
if deposit.user_id != current_user.id and current_user.role != "admin":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Access denied",
|
|
)
|
|
|
|
return deposit
|
|
|
|
|
|
# Admin endpoints
|
|
@router.get("/admin/pending", response_model=List[schemas.Deposit])
|
|
def read_pending_deposits(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
) -> Any:
|
|
"""
|
|
Retrieve all pending deposit requests (admin only).
|
|
"""
|
|
deposits = crud.deposit.get_all_pending(db, skip=skip, limit=limit)
|
|
return deposits
|
|
|
|
|
|
@router.put("/admin/{deposit_id}/approve", response_model=schemas.Deposit)
|
|
def approve_deposit_request(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
deposit_id: int,
|
|
deposit_data: schemas.DepositApprove,
|
|
) -> Any:
|
|
"""
|
|
Approve a deposit request (admin only).
|
|
"""
|
|
deposit = crud.deposit.get(db, id=deposit_id)
|
|
if not deposit:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Deposit not found",
|
|
)
|
|
|
|
if deposit.status != "pending":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Deposit is already {deposit.status}",
|
|
)
|
|
|
|
# Get user's spot wallet
|
|
spot_wallet = crud.wallet.get_by_user_and_type(
|
|
db, user_id=deposit.user_id, wallet_type=WalletType.SPOT
|
|
)
|
|
if not spot_wallet:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="User's spot wallet not found",
|
|
)
|
|
|
|
# Update wallet balance
|
|
crud.wallet.update_balance(db, wallet_id=spot_wallet.id, amount=deposit.amount, add=True)
|
|
|
|
# Approve deposit
|
|
updated_deposit = crud.deposit.approve(
|
|
db, db_obj=deposit, admin_notes=deposit_data.admin_notes
|
|
)
|
|
|
|
# Create transaction record
|
|
transaction = crud.transaction.create(
|
|
db,
|
|
obj_in=schemas.TransactionCreate(
|
|
user_id=deposit.user_id,
|
|
wallet_id=spot_wallet.id,
|
|
amount=deposit.amount,
|
|
transaction_type=TransactionType.DEPOSIT,
|
|
description=f"Deposit - {deposit.transaction_hash}",
|
|
deposit_id=deposit.id,
|
|
),
|
|
)
|
|
|
|
# Send confirmation email to user
|
|
user = crud.user.get(db, id=deposit.user_id)
|
|
if user:
|
|
send_deposit_confirmation(
|
|
email_to=user.email,
|
|
amount=deposit.amount,
|
|
transaction_id=str(transaction.id),
|
|
)
|
|
|
|
return updated_deposit
|
|
|
|
|
|
@router.put("/admin/{deposit_id}/reject", response_model=schemas.Deposit)
|
|
def reject_deposit_request(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
deposit_id: int,
|
|
deposit_data: schemas.DepositReject,
|
|
) -> Any:
|
|
"""
|
|
Reject a deposit request (admin only).
|
|
"""
|
|
deposit = crud.deposit.get(db, id=deposit_id)
|
|
if not deposit:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Deposit not found",
|
|
)
|
|
|
|
if deposit.status != "pending":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Deposit is already {deposit.status}",
|
|
)
|
|
|
|
# Reject deposit
|
|
updated_deposit = crud.deposit.reject(
|
|
db, db_obj=deposit, admin_notes=deposit_data.admin_notes
|
|
)
|
|
|
|
return updated_deposit |