"""Title library use cases.""" from __future__ import annotations import uuid from typing import List, Optional from packages.adapters.sqlalchemy_impl.title_library_repository import SQLAlchemyTitleLibraryRepository from packages.application.title_library.commands import ( CreateTitleLibraryCommand, UpdateTitleLibraryCommand, ) from packages.domain.quota import QuotaDimension, quota_checker from packages.domain.title_library import TitleLibraryItem class ListTitleLibraryUseCase: def __init__(self, repository: SQLAlchemyTitleLibraryRepository) -> None: self.repository = repository def execute( self, user_id: str, *, category: Optional[str] = None, skip: int = 0, limit: int = 50, ) -> List[TitleLibraryItem]: return self.repository.list_by_user(user_id, category=category, skip=skip, limit=limit) class GetTitleLibraryUseCase: def __init__(self, repository: SQLAlchemyTitleLibraryRepository) -> None: self.repository = repository def execute(self, title_id: str, user_id: str) -> Optional[TitleLibraryItem]: return self.repository.get(title_id, user_id) class CreateTitleLibraryUseCase: def __init__(self, repository: SQLAlchemyTitleLibraryRepository) -> None: self.repository = repository def execute(self, command: CreateTitleLibraryCommand, plan_name: str = "free") -> TitleLibraryItem: # Quota check current_count = self.repository.count_by_user(command.user_id) result = quota_checker.check(plan_name, QuotaDimension.MAX_TITLES.value, current_count) if not result.allowed: raise QuotaExceededError( dimension=QuotaDimension.MAX_TITLES.value, limit=result.limit, used=result.used, ) item = TitleLibraryItem( id=uuid.uuid4().hex, user_id=command.user_id, name=command.name, text=command.text, category=command.category, description=command.description, tags=command.tags, metadata_=command.metadata_, ) return self.repository.create(item) class UpdateTitleLibraryUseCase: def __init__(self, repository: SQLAlchemyTitleLibraryRepository) -> None: self.repository = repository def execute(self, command: UpdateTitleLibraryCommand) -> TitleLibraryItem: existing = self.repository.get(command.title_id, command.user_id) if existing is None: raise NotFoundError(f"Title {command.title_id} not found") if command.name is not None: existing.name = command.name if command.text is not None: existing.text = command.text if command.category is not None: existing.category = command.category if command.description is not None: existing.description = command.description if command.tags is not None: existing.tags = command.tags if command.is_active is not None: existing.is_active = command.is_active if command.metadata_ is not None: existing.metadata_ = command.metadata_ return self.repository.update(existing) class DeleteTitleLibraryUseCase: def __init__(self, repository: SQLAlchemyTitleLibraryRepository) -> None: self.repository = repository def execute(self, title_id: str, user_id: str) -> bool: return self.repository.delete(title_id, user_id) class QuotaExceededError(Exception): def __init__(self, dimension: str, limit: float, used: float) -> None: self.dimension = dimension self.limit = limit self.used = used super().__init__(f"Quota exceeded for {dimension}: {used}/{limit}") class NotFoundError(Exception): pass