""" API роутеры для работы с документами """ from uuid import UUID from fastapi import APIRouter, status, UploadFile, File from fastapi.responses import JSONResponse from typing import List from dishka.integrations.fastapi import FromDishka from src.presentation.schemas.document_schemas import ( DocumentCreate, DocumentUpdate, DocumentResponse ) from src.application.use_cases.document_use_cases import DocumentUseCases from src.domain.entities.user import User router = APIRouter(prefix="/documents", tags=["documents"]) @router.post("", response_model=DocumentResponse, status_code=status.HTTP_201_CREATED) async def create_document( document_data: DocumentCreate, current_user: FromDishka[User] = FromDishka(), use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Создать документ""" document = await use_cases.create_document( collection_id=document_data.collection_id, title=document_data.title, content=document_data.content, metadata=document_data.metadata ) return DocumentResponse.from_entity(document) @router.post("/upload", response_model=DocumentResponse, status_code=status.HTTP_201_CREATED) async def upload_document( collection_id: UUID, file: UploadFile = File(...), current_user: FromDishka[User] = FromDishka(), use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Загрузить и распарсить PDF документ или изображение""" if not file.filename: raise JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, content={"detail": "Имя файла не указано"} ) supported_formats = ['.pdf', '.png', '.jpg', '.jpeg', '.tiff', '.bmp'] file_ext = file.filename.lower().rsplit('.', 1)[-1] if '.' in file.filename else '' if f'.{file_ext}' not in supported_formats: raise JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, content={"detail": f"Неподдерживаемый формат файла. Поддерживаются: {', '.join(supported_formats)}"} ) document = await use_cases.upload_and_parse_document( collection_id=collection_id, file=file.file, filename=file.filename, user_id=current_user.user_id ) return DocumentResponse.from_entity(document) @router.get("/{document_id}", response_model=DocumentResponse) async def get_document( document_id: UUID, use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Получить документ по ID""" document = await use_cases.get_document(document_id) return DocumentResponse.from_entity(document) @router.put("/{document_id}", response_model=DocumentResponse) async def update_document( document_id: UUID, document_data: DocumentUpdate, current_user: FromDishka[User] = FromDishka(), use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Обновить документ""" document = await use_cases.update_document( document_id=document_id, user_id=current_user.user_id, title=document_data.title, content=document_data.content, metadata=document_data.metadata ) return DocumentResponse.from_entity(document) @router.delete("/{document_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_document( document_id: UUID, current_user: FromDishka[User] = FromDishka(), use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Удалить документ""" await use_cases.delete_document(document_id, current_user.user_id) return JSONResponse(status_code=status.HTTP_204_NO_CONTENT, content=None) @router.get("/collection/{collection_id}", response_model=List[DocumentResponse]) async def list_collection_documents( collection_id: UUID, skip: int = 0, limit: int = 100, use_cases: FromDishka[DocumentUseCases] = FromDishka() ): """Получить документы коллекции""" documents = await use_cases.list_collection_documents( collection_id=collection_id, skip=skip, limit=limit ) return [DocumentResponse.from_entity(d) for d in documents]