""" Routes pour la gestion des documents """ from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Depends, Query from sqlalchemy.orm import Session from typing import List, Optional import uuid import time import logging from domain.database import get_db, Document, ProcessingLog from domain.models import DocumentResponse, DocumentInfo, DocumentStatus, DocumentType from tasks.enqueue import enqueue_import from utils.storage import store_document logger = logging.getLogger(__name__) router = APIRouter() @router.post("/import", response_model=DocumentResponse) async def import_document( file: UploadFile = File(...), id_dossier: str = Form(...), source: str = Form("upload"), etude_id: str = Form(...), utilisateur_id: str = Form(...), db: Session = Depends(get_db) ): """ Import d'un nouveau document dans le pipeline """ try: # Vérification du type de fichier if file.content_type not in [dt.value for dt in DocumentType]: raise HTTPException( status_code=415, detail=f"Type de fichier non supporté: {file.content_type}" ) # Génération d'un ID unique doc_id = str(uuid.uuid4()) # Lecture du contenu du fichier content = await file.read() file_size = len(content) # Stockage du document storage_path = await store_document(doc_id, content, file.filename) # Création de l'enregistrement en base document = Document( id=doc_id, filename=file.filename or "unknown", mime_type=file.content_type, size=file_size, status=DocumentStatus.PENDING.value, id_dossier=id_dossier, etude_id=etude_id, utilisateur_id=utilisateur_id, source=source ) db.add(document) db.commit() db.refresh(document) # Enqueue du traitement meta = { "id_dossier": id_dossier, "source": source, "etude_id": etude_id, "utilisateur_id": utilisateur_id, "filename": file.filename, "mime": file.content_type, "received_at": int(time.time()) } enqueue_import(doc_id, meta) logger.info(f"Document {doc_id} importé avec succès") return DocumentResponse( status="queued", id_document=doc_id, message="Document en cours de traitement" ) except Exception as e: logger.error(f"Erreur lors de l'import du document: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/documents/{document_id}", response_model=DocumentInfo) async def get_document( document_id: str, db: Session = Depends(get_db) ): """ Récupération des informations d'un document """ document = db.query(Document).filter(Document.id == document_id).first() if not document: raise HTTPException(status_code=404, detail="Document non trouvé") return DocumentInfo( id=document.id, filename=document.filename, mime_type=document.mime_type, size=document.size, status=DocumentStatus(document.status), id_dossier=document.id_dossier, etude_id=document.etude_id, utilisateur_id=document.utilisateur_id, created_at=document.created_at, updated_at=document.updated_at, processing_steps=document.processing_steps, extracted_data=document.extracted_data, errors=document.errors ) @router.get("/documents", response_model=List[DocumentInfo]) async def list_documents( etude_id: Optional[str] = Query(None), id_dossier: Optional[str] = Query(None), status: Optional[DocumentStatus] = Query(None), limit: int = Query(50, le=100), offset: int = Query(0, ge=0), db: Session = Depends(get_db) ): """ Liste des documents avec filtres """ query = db.query(Document) if etude_id: query = query.filter(Document.etude_id == etude_id) if id_dossier: query = query.filter(Document.id_dossier == id_dossier) if status: query = query.filter(Document.status == status.value) documents = query.offset(offset).limit(limit).all() return [ DocumentInfo( id=doc.id, filename=doc.filename, mime_type=doc.mime_type, size=doc.size, status=DocumentStatus(doc.status), id_dossier=doc.id_dossier, etude_id=doc.etude_id, utilisateur_id=doc.utilisateur_id, created_at=doc.created_at, updated_at=doc.updated_at, processing_steps=doc.processing_steps, extracted_data=doc.extracted_data, errors=doc.errors ) for doc in documents ] @router.delete("/documents/{document_id}") async def delete_document( document_id: str, db: Session = Depends(get_db) ): """ Suppression d'un document """ document = db.query(Document).filter(Document.id == document_id).first() if not document: raise HTTPException(status_code=404, detail="Document non trouvé") # Suppression des logs de traitement db.query(ProcessingLog).filter(ProcessingLog.document_id == document_id).delete() # Suppression du document db.delete(document) db.commit() logger.info(f"Document {document_id} supprimé") return {"message": "Document supprimé avec succès"}