first commit
This commit is contained in:
commit
efa5080897
127 changed files with 18610 additions and 0 deletions
130
backend/app/routes_dlt.py
Normal file
130
backend/app/routes_dlt.py
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
|
||||
from fastapi.responses import FileResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from .auth import current_user
|
||||
from .config import settings
|
||||
from .database import get_db
|
||||
from .dlt_constants import DLT_DOCUMENT_TYPES, DLT_UPLOAD_DOCUMENT_TYPES, PE_TM_CHAIN_BINDING_ID
|
||||
from .dlt_service import ensure_dlt_application, serialize_dlt
|
||||
from .kyc_constants import ALLOWED_UPLOAD_EXTENSIONS
|
||||
from .kyc_service import upload_root
|
||||
from .models import UserAccount
|
||||
|
||||
router = APIRouter(prefix="/api/v1/dlt", tags=["dlt"])
|
||||
|
||||
|
||||
@router.get("/me")
|
||||
def get_my_dlt(db: Session = Depends(get_db), user: UserAccount = Depends(current_user)) -> dict:
|
||||
application = ensure_dlt_application(db, user)
|
||||
return serialize_dlt(application)
|
||||
|
||||
|
||||
@router.get("/loa")
|
||||
def download_loa(_: UserAccount = Depends(current_user)) -> FileResponse:
|
||||
template = Path(settings.dlt_loa_template_path)
|
||||
if not template.is_file():
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="LOA template not found")
|
||||
return FileResponse(
|
||||
template,
|
||||
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
filename="Updated LOA.docx",
|
||||
)
|
||||
|
||||
|
||||
@router.post("/chain-binding/confirm")
|
||||
def confirm_chain_binding(
|
||||
db: Session = Depends(get_db),
|
||||
user: UserAccount = Depends(current_user),
|
||||
) -> dict:
|
||||
application = ensure_dlt_application(db, user)
|
||||
if application.status == "approved":
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Approved DLT cannot be edited")
|
||||
|
||||
document = next(doc for doc in application.documents if doc.document_type == "pe_tm_chain_binding")
|
||||
if document.status == "approved":
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Chain binding already approved")
|
||||
|
||||
document.original_filename = f"Chain binding {PE_TM_CHAIN_BINDING_ID}"
|
||||
document.stored_path = None
|
||||
document.status = "pending"
|
||||
document.review_note = None
|
||||
document.uploaded_at = datetime.now(timezone.utc)
|
||||
document.reviewed_at = None
|
||||
if application.status in {"not_started", "in_progress", "rejected"}:
|
||||
application.status = "in_progress"
|
||||
db.commit()
|
||||
db.refresh(application)
|
||||
return serialize_dlt(application)
|
||||
|
||||
|
||||
@router.post("/documents/{document_type}")
|
||||
async def upload_document(
|
||||
document_type: str,
|
||||
file: UploadFile = File(...),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserAccount = Depends(current_user),
|
||||
) -> dict:
|
||||
if document_type not in DLT_DOCUMENT_TYPES:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid document type")
|
||||
if document_type not in DLT_UPLOAD_DOCUMENT_TYPES:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="This item uses chain binding confirmation instead of file upload",
|
||||
)
|
||||
application = ensure_dlt_application(db, user)
|
||||
if application.status == "approved":
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Approved DLT cannot be edited")
|
||||
|
||||
filename = file.filename or ""
|
||||
extension = Path(filename).suffix.lower()
|
||||
if extension not in ALLOWED_UPLOAD_EXTENSIONS:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Allowed file types: PDF, PNG, JPG, DOC, DOCX",
|
||||
)
|
||||
|
||||
content = await file.read()
|
||||
if not content:
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="File is empty")
|
||||
if len(content) > settings.max_upload_bytes:
|
||||
raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, detail="File exceeds 10 MB limit")
|
||||
|
||||
document = next(doc for doc in application.documents if doc.document_type == document_type)
|
||||
root = upload_root(settings.upload_dir)
|
||||
stored_name = f"{application.id}_{document_type}{extension}"
|
||||
stored_path = root / stored_name
|
||||
stored_path.write_bytes(content)
|
||||
|
||||
document.original_filename = filename
|
||||
document.stored_path = str(stored_path)
|
||||
document.status = "pending"
|
||||
document.review_note = None
|
||||
document.uploaded_at = datetime.now(timezone.utc)
|
||||
document.reviewed_at = None
|
||||
if application.status in {"not_started", "in_progress", "rejected"}:
|
||||
application.status = "in_progress"
|
||||
db.commit()
|
||||
db.refresh(application)
|
||||
return serialize_dlt(application)
|
||||
|
||||
|
||||
@router.post("/submit")
|
||||
def submit_dlt(db: Session = Depends(get_db), user: UserAccount = Depends(current_user)) -> dict:
|
||||
application = ensure_dlt_application(db, user)
|
||||
if application.status == "approved":
|
||||
return serialize_dlt(application)
|
||||
missing = [doc.document_type for doc in application.documents if doc.status == "missing"]
|
||||
if missing:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail="Complete all required DLT items before submitting",
|
||||
)
|
||||
application.status = "submitted"
|
||||
application.submitted_at = datetime.now(timezone.utc)
|
||||
db.commit()
|
||||
db.refresh(application)
|
||||
return serialize_dlt(application)
|
||||
Loading…
Add table
Add a link
Reference in a new issue