""" SAMMS ENTERPRISE SOVEREIGN OPERATING SYSTEM - Base Service Foundation service class with common business logic patterns. """ from abc import ABC, abstractmethod from dataclasses import dataclass, field from datetime import datetime from decimal import Decimal from typing import ( Optional, List, Dict, Any, Generic, TypeVar, Union, Callable, Awaitable, Protocol ) from uuid import UUID import asyncio import logging from functools import wraps from sqlalchemy.ext.asyncio import AsyncSession from ..repositories.base import BaseRepository from ..core.exceptions import ( NotFoundError, ValidationError, BusinessLogicError, PermissionDeniedError, ConflictError ) from ..core.events import EventPublisher from ..core.cache import CacheManager logger = logging.getLogger(__name__) @dataclass class Result(Generic[TypeVar('T')]): """ Generic result wrapper for service operations. Provides success/failure status, data, errors, and metadata. """ success: bool data: Optional[Any] = None errors: List[str] = field(default_factory=list) warnings: List[str] = field(default_factory=list) metadata: Dict[str, Any] = field(default_factory=dict) @classmethod def ok(cls, data: Any = None, metadata: Optional[Dict[str, Any]] = None, warnings: Optional[List[str]] = None) -> 'Result': """Create a successful result.""" return cls( success=True, data=data, warnings=warnings or [], metadata=metadata or {} ) @classmethod def fail(cls, errors: Union[str, List[str]], metadata: Optional[Dict[str, Any]] = None) -> 'Result': """Create a failed result.""" error_list = [errors] if isinstance(errors, str) else errors return cls( success=False, errors=error_list, metadata=metadata or {} ) @classmethod def partial(cls, data: Any, warnings: List[str], metadata: Optional[Dict[str, Any]] = None) -> 'Result': """Create a partial success result with warnings.""" return cls( success=True, data=data, warnings=warnings, metadata=metadata or {} ) def add_error(self, error: str) -> 'Result': """Add an error to the result.""" self.errors.append(error) self.success = False return self def add_warning(self, warning: str) -> 'Result': """Add a warning to the result.""" self.warnings.append(warning) return self def merge(self, other: 'Result') -> 'Result': """Merge another result into this one.""" self.errors.extend(other.errors) self.warnings.extend(other.warnings) self.metadata.update(other.metadata) if not other.success: self.success = False return self # Type alias for service results ServiceResult = Result @dataclass class PaginationResult(Generic[TypeVar('T')]): """ Result wrapper for paginated data. """ items: List[Any] total: int page: int page_size: int total_pages: int has_next: bool has_prev: bool @classmethod def create( cls, items: List[Any], total: int, page: int, page_size: int ) -> 'PaginationResult': """Create a pagination result.""" total_pages = (total + page_size - 1) // page_size if page_size > 0 else 0 return cls( items=items, total=total, page=page, page_size=page_size, total_pages=total_pages, has_next=page < total_pages, has_prev=page > 1 ) class ServiceContext: """ Context object passed through service operations. Contains user info, company info, and request metadata. """ def __init__( self, user_id: Optional[UUID] = None, company_id: Optional[UUID] = None, roles: Optional[List[str]] = None, permissions: Optional[List[str]] = None, request_id: Optional[str] = None, ip_address: Optional[str] = None, user_agent: Optional[str] = None, metadata: Optional[Dict[str, Any]] = None ): self.user_id = user_id self.company_id = company_id self.roles = roles or [] self.permissions = permissions or [] self.request_id = request_id self.ip_address = ip_address self.user_agent = user_agent self.metadata = metadata or {} self.created_at = datetime.utcnow() def has_permission(self, permission: str) -> bool: """Check if context has a specific permission.""" return permission in self.permissions def has_any_permission(self, permissions: List[str]) -> bool: """Check if context has any of the specified permissions.""" return any(p in self.permissions for p in permissions) def has_all_permissions(self, permissions: List[str]) -> bool: """Check if context has all specified permissions.""" return all(p in self.permissions for p in permissions) def has_role(self, role: str) -> bool: """Check if context has a specific role.""" return role in self.roles def is_authenticated(self) -> bool: """Check if context represents an authenticated user.""" return self.user_id is not None class BaseService(ABC): """ Base service class providing common business logic patterns. Features: - Repository management - Event publishing - Caching - Logging - Transaction management - Validation helpers """ def __init__( self, session: AsyncSession, cache: Optional[CacheManager] = None,