201 lines
5.6 KiB
Python
201 lines
5.6 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.services.file_upload import save_kyc_document
|
|
from app.core.email import send_kyc_status_update
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/upload", response_model=schemas.KYC)
|
|
async def upload_kyc_documents(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_active_verified_user),
|
|
full_name: str = Form(...),
|
|
id_document_type: schemas.IDDocumentType = Form(...),
|
|
id_document: UploadFile = File(...),
|
|
selfie: UploadFile = File(...),
|
|
additional_document: UploadFile = File(None),
|
|
) -> Any:
|
|
"""
|
|
Upload KYC documents.
|
|
"""
|
|
# Check if user already has KYC submission
|
|
existing_kyc = crud.kyc.get_by_user(db, user_id=current_user.id)
|
|
if existing_kyc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"You already have a KYC submission with status: {existing_kyc.status}",
|
|
)
|
|
|
|
# Save documents
|
|
id_document_path = save_kyc_document(current_user.id, "id_document", id_document)
|
|
selfie_path = save_kyc_document(current_user.id, "selfie", selfie)
|
|
additional_document_path = None
|
|
if additional_document:
|
|
additional_document_path = save_kyc_document(current_user.id, "additional", additional_document)
|
|
|
|
# Create KYC record
|
|
kyc_in = schemas.KYCCreate(
|
|
user_id=current_user.id,
|
|
full_name=full_name,
|
|
id_document_type=id_document_type,
|
|
id_document_path=id_document_path,
|
|
selfie_path=selfie_path,
|
|
additional_document_path=additional_document_path,
|
|
)
|
|
kyc = crud.kyc.create(db, obj_in=kyc_in)
|
|
|
|
return kyc
|
|
|
|
|
|
@router.get("/status", response_model=schemas.KYC)
|
|
def get_kyc_status(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_active_verified_user),
|
|
) -> Any:
|
|
"""
|
|
Get user's KYC status.
|
|
"""
|
|
kyc = crud.kyc.get_by_user(db, user_id=current_user.id)
|
|
if not kyc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="No KYC submission found",
|
|
)
|
|
|
|
return kyc
|
|
|
|
|
|
# Admin endpoints
|
|
@router.get("/admin/pending", response_model=List[schemas.KYC])
|
|
def get_pending_kyc(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
) -> Any:
|
|
"""
|
|
Get all pending KYC submissions (admin only).
|
|
"""
|
|
kyc_submissions = crud.kyc.get_all_pending(db, skip=skip, limit=limit)
|
|
return kyc_submissions
|
|
|
|
|
|
@router.get("/admin/{kyc_id}", response_model=schemas.KYC)
|
|
def get_kyc(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
kyc_id: int,
|
|
) -> Any:
|
|
"""
|
|
Get a specific KYC submission by ID (admin only).
|
|
"""
|
|
kyc = crud.kyc.get(db, id=kyc_id)
|
|
if not kyc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="KYC submission not found",
|
|
)
|
|
|
|
return kyc
|
|
|
|
|
|
@router.put("/admin/{kyc_id}/approve", response_model=schemas.KYC)
|
|
def approve_kyc_submission(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
kyc_id: int,
|
|
) -> Any:
|
|
"""
|
|
Approve a KYC submission (admin only).
|
|
"""
|
|
kyc = crud.kyc.get(db, id=kyc_id)
|
|
if not kyc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="KYC submission not found",
|
|
)
|
|
|
|
if kyc.status != "pending":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"KYC submission is already {kyc.status}",
|
|
)
|
|
|
|
# Get user
|
|
user = crud.user.get(db, id=kyc.user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
# Update KYC status
|
|
updated_kyc = crud.kyc.approve(db, db_obj=kyc)
|
|
|
|
# Update user's KYC status
|
|
crud.user.set_kyc_verified(db, user=user)
|
|
|
|
# Send email notification
|
|
send_kyc_status_update(
|
|
email_to=user.email,
|
|
status="approved",
|
|
)
|
|
|
|
return updated_kyc
|
|
|
|
|
|
@router.put("/admin/{kyc_id}/reject", response_model=schemas.KYC)
|
|
def reject_kyc_submission(
|
|
*,
|
|
db: Session = Depends(deps.get_db),
|
|
current_user: models.User = Depends(deps.get_current_admin),
|
|
kyc_id: int,
|
|
kyc_data: schemas.KYCReject,
|
|
) -> Any:
|
|
"""
|
|
Reject a KYC submission (admin only).
|
|
"""
|
|
kyc = crud.kyc.get(db, id=kyc_id)
|
|
if not kyc:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="KYC submission not found",
|
|
)
|
|
|
|
if kyc.status != "pending":
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"KYC submission is already {kyc.status}",
|
|
)
|
|
|
|
# Get user
|
|
user = crud.user.get(db, id=kyc.user_id)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="User not found",
|
|
)
|
|
|
|
# Update KYC status
|
|
updated_kyc = crud.kyc.reject(db, db_obj=kyc, rejection_reason=kyc_data.rejection_reason)
|
|
|
|
# Send email notification
|
|
send_kyc_status_update(
|
|
email_to=user.email,
|
|
status="rejected",
|
|
reason=kyc_data.rejection_reason,
|
|
)
|
|
|
|
return updated_kyc |