Initial phase 4 extra tools, bug fixes, multi select changes.
Some checks failed
Automated Container Build / build-and-push (push) Failing after 3s
CI / Backend (Python) (push) Failing after 18s
CI / Frontend (TypeScript) (push) Failing after 4m52s

This commit is contained in:
Elijah 2026-06-13 12:15:22 -07:00
parent bce3c1b420
commit f273685cc1
18 changed files with 1379 additions and 88 deletions

View file

@ -14,6 +14,10 @@ router.include_router(auth_router)
# Documents
router.include_router(documents_router)
# Assets
from app.api.v1.assets import router as assets_router
router.include_router(assets_router)
# Annotations
from app.api.v1.annotations import router as annotations_router
router.include_router(annotations_router)

View file

@ -0,0 +1,58 @@
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)