""" Repository interfaces for artifact persistence. Defines abstract interfaces for artifact storage, enabling pluggable storage backends. """ from abc import ABC, abstractmethod from typing import List, Optional from markitect.prompts.models import Artifact, ArtifactType class RepositoryError(Exception): """Base exception for repository errors.""" pass class ArtifactNotFoundError(RepositoryError): """Raised when an artifact cannot be found.""" pass class DuplicateArtifactError(RepositoryError): """Raised when attempting to create an artifact with duplicate name.""" pass class IArtifactRepository(ABC): """ Abstract interface for artifact persistence. Implements FR-1: InformationSpace Addressability Provides CRUD operations for artifacts with content digest tracking. """ @abstractmethod def create(self, artifact: Artifact) -> Artifact: """ Persist a new artifact. Args: artifact: Artifact to create Returns: Created artifact Raises: DuplicateArtifactError: If artifact with same space_id+name exists RepositoryError: On other persistence errors """ pass @abstractmethod def get_by_id(self, artifact_id: str) -> Optional[Artifact]: """ Retrieve artifact by ID. Args: artifact_id: Artifact identifier Returns: Artifact if found, None otherwise """ pass @abstractmethod def get_by_name(self, space_id: str, name: str) -> Optional[Artifact]: """ Retrieve artifact by space and name. Implements FR-1.3: Cross-space artifact lookup Args: space_id: Space identifier name: Artifact name Returns: Artifact if found, None otherwise """ pass @abstractmethod def get_by_digest(self, content_digest: str) -> List[Artifact]: """ Find artifacts with matching content digest. Implements FR-1.2: Content digest queries Args: content_digest: SHA-256 digest to match Returns: List of artifacts with matching digest """ pass @abstractmethod def list_by_space( self, space_id: str, artifact_type: Optional[ArtifactType] = None, ) -> List[Artifact]: """ List all artifacts in a space. Args: space_id: Space identifier artifact_type: Optional type filter Returns: List of artifacts in space """ pass @abstractmethod def update(self, artifact: Artifact) -> Artifact: """ Update an existing artifact. Updates content digest and modified timestamp. Args: artifact: Artifact with updated data Returns: Updated artifact Raises: ArtifactNotFoundError: If artifact doesn't exist RepositoryError: On other persistence errors """ pass @abstractmethod def delete(self, artifact_id: str) -> bool: """ Delete an artifact. Args: artifact_id: Artifact identifier Returns: True if deleted, False if not found """ pass @abstractmethod def exists(self, space_id: str, name: str) -> bool: """ Check if artifact exists. Args: space_id: Space identifier name: Artifact name Returns: True if artifact exists """ pass