2025-12-24 06:28:01 +03:00

138 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Use cases для работы с документами
"""
from uuid import UUID
from typing import BinaryIO, Optional
from src.domain.entities.document import Document
from src.domain.repositories.document_repository import IDocumentRepository
from src.domain.repositories.collection_repository import ICollectionRepository
from src.domain.repositories.collection_access_repository import ICollectionAccessRepository
from src.application.services.document_parser_service import DocumentParserService
from src.shared.exceptions import NotFoundError, ForbiddenError
class DocumentUseCases:
"""Use cases для документов"""
def __init__(
self,
document_repository: IDocumentRepository,
collection_repository: ICollectionRepository,
access_repository: ICollectionAccessRepository,
parser_service: DocumentParserService
):
self.document_repository = document_repository
self.collection_repository = collection_repository
self.access_repository = access_repository
self.parser_service = parser_service
async def _check_collection_access(self, user_id: UUID, collection) -> bool:
"""Проверить доступ пользователя к коллекции"""
if collection.owner_id == user_id:
return True
if collection.is_public:
return True
access = await self.access_repository.get_by_user_and_collection(user_id, collection.collection_id)
return access is not None
async def create_document(
self,
collection_id: UUID,
title: str,
content: str,
metadata: dict | None = None
) -> Document:
"""Создать документ"""
collection = await self.collection_repository.get_by_id(collection_id)
if not collection:
raise NotFoundError(f"Коллекция {collection_id} не найдена")
document = Document(
collection_id=collection_id,
title=title,
content=content,
metadata=metadata or {}
)
return await self.document_repository.create(document)
async def upload_and_parse_document(
self,
collection_id: UUID,
file: BinaryIO,
filename: str,
user_id: UUID
) -> Document:
"""Загрузить и распарсить документ"""
collection = await self.collection_repository.get_by_id(collection_id)
if not collection:
raise NotFoundError(f"Коллекция {collection_id} не найдена")
has_access = await self._check_collection_access(user_id, collection)
if not has_access:
raise ForbiddenError("У вас нет доступа к этой коллекции")
title, content = await self.parser_service.parse_pdf(file, filename)
document = Document(
collection_id=collection_id,
title=title,
content=content,
metadata={"filename": filename}
)
return await self.document_repository.create(document)
async def get_document(self, document_id: UUID) -> Document:
"""Получить документ по ID"""
document = await self.document_repository.get_by_id(document_id)
if not document:
raise NotFoundError(f"Документ {document_id} не найден")
return document
async def update_document(
self,
document_id: UUID,
user_id: UUID,
title: str | None = None,
content: str | None = None,
metadata: dict | None = None
) -> Document:
"""Обновить документ"""
document = await self.get_document(document_id)
collection = await self.collection_repository.get_by_id(document.collection_id)
if not collection:
raise NotFoundError(f"Коллекция {document.collection_id} не найдена")
has_access = await self._check_collection_access(user_id, collection)
if not has_access:
raise ForbiddenError("У вас нет доступа к этой коллекции")
if title is not None:
document.title = title
if content is not None:
document.content = content
if metadata is not None:
document.metadata = metadata
return await self.document_repository.update(document)
async def delete_document(self, document_id: UUID, user_id: UUID) -> bool:
"""Удалить документ"""
document = await self.get_document(document_id)
collection = await self.collection_repository.get_by_id(document.collection_id)
if not collection or collection.owner_id != user_id:
raise ForbiddenError("Только владелец коллекции может удалять документы")
return await self.document_repository.delete(document_id)
async def list_collection_documents(self, collection_id: UUID, skip: int = 0, limit: int = 100) -> list[Document]:
"""Получить документы коллекции"""
collection = await self.collection_repository.get_by_id(collection_id)
if not collection:
raise NotFoundError(f"Коллекция {collection_id} не найдена")
return await self.document_repository.list_by_collection(collection_id, skip=skip, limit=limit)