from fastapi import APIRouter, Depends, UploadFile, File from fastapi.responses import Response from typing import Optional from models.scan import ScanReport from models.conversion import ConversionRequest, ConversionResult from services.scan_service import ScanService from services.conversion_service import ConversionService, get_conversion_result from dependencies import ( get_scan_service, get_conversion_service, get_optional_user, get_admin_token, ) router = APIRouter(prefix='/api', tags=['upload']) @router.post('/scan', response_model=ScanReport) async def scan_file( file: UploadFile = File(...), service: ScanService = Depends(get_scan_service), ): """Validate and scan an idconvert_export.json. Costs no credits.""" return await service.scan(file) @router.post('/convert', response_model=ConversionResult) async def convert_file( body: ConversionRequest, service: ConversionService = Depends(get_conversion_service), user: Optional[dict] = Depends(get_optional_user), admin_token: str = Depends(get_admin_token), ): """Convert the cached scan to DOCX. Deducts 1 credit if the user is authenticated via Bearer token. Works without auth for local development (no credit deduction). """ return await service.convert(body.session_id, body.filename, user, admin_token) @router.get('/download/{session_id}') async def download_file(session_id: str): """Fallback download endpoint when MinIO is not configured.""" result = get_conversion_result(session_id) if not result: from fastapi import HTTPException raise HTTPException(404, 'File not found or session expired') docx_bytes, filename = result return Response( content=docx_bytes, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document', headers={'Content-Disposition': f'attachment; filename="{filename}"'}, )