first commit

This commit is contained in:
debu-2 2026-10-02 11:22:40 +05:30
commit efa5080897
127 changed files with 18610 additions and 0 deletions

130
backend/app/routes_dlt.py Normal file
View 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)