from fastapi import APIRouter, Depends, UploadFile, File, HTTPException from fastapi.responses import FileResponse from sqlalchemy.orm import Session import uuid import shutil from pathlib import Path from app.db import get_db from app.auth.dependencies import get_current_user from app.config import settings router = APIRouter(prefix="/documents", tags=["Assets"]) def get_asset_path(document_id: str, ref: str) -> Path: # Ensure directory exists dir_path = settings.PDF_STORAGE_PATH / "assets" / document_id dir_path.mkdir(parents=True, exist_ok=True) return dir_path / ref @router.post("/{id}/assets") async def upload_asset( id: str, file: UploadFile = File(...), user_id: int = Depends(get_current_user), db: Session = Depends(get_db) ): """Upload a binary asset (like an image or signature) for a document.""" # In a real app we'd verify the user owns the document here # For this single-user app, we trust the ID if not file.content_type or not file.content_type.startswith("image/"): raise HTTPException(status_code=400, detail="Only image assets are supported") ref = str(uuid.uuid4()) filepath = get_asset_path(id, ref) try: with open(filepath, "wb") as f: shutil.copyfileobj(file.file, f) except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to save asset: {e}") return { "ref": ref, "url": f"/api/v1/documents/{id}/assets/{ref}" } @router.get("/{id}/assets/{ref}") async def get_asset( id: str, ref: str, ): """Serve a binary asset.""" filepath = get_asset_path(id, ref) if not filepath.exists() or not filepath.is_file(): raise HTTPException(status_code=404, detail="Asset not found") return FileResponse(filepath)