# app/modules/contracts/cms.py """ CMS module contracts. Defines the interface for content management functionality that other modules can depend on without importing the concrete implementation. """ from typing import TYPE_CHECKING, Protocol, runtime_checkable if TYPE_CHECKING: from sqlalchemy.orm import Session @runtime_checkable class ContentServiceProtocol(Protocol): """ Protocol for content page service. Defines the interface for retrieving and managing content pages with three-tier resolution (platform > store default > store override). """ def get_page_for_store( self, db: "Session", platform_id: int, slug: str, store_id: int | None = None, include_unpublished: bool = False, ) -> object | None: """ Get content page with three-tier resolution. Resolution order: 1. Store override (platform_id + store_id + slug) 2. Store default (platform_id + store_id=NULL + is_platform_page=False + slug) Args: db: Database session platform_id: Platform ID slug: Page slug store_id: Store ID (None for defaults only) include_unpublished: Include draft pages Returns: ContentPage or None """ ... def get_platform_page( self, db: "Session", platform_id: int, slug: str, include_unpublished: bool = False, ) -> object | None: """ Get a platform marketing page. Args: db: Database session platform_id: Platform ID slug: Page slug include_unpublished: Include draft pages Returns: ContentPage or None """ ... def list_pages_for_store( self, db: "Session", platform_id: int, store_id: int | None = None, include_unpublished: bool = False, footer_only: bool = False, header_only: bool = False, legal_only: bool = False, ) -> list: """ List all available pages for a store storefront. Merges store overrides with store defaults, prioritizing overrides. Args: db: Database session platform_id: Platform ID store_id: Store ID (None for store defaults only) include_unpublished: Include draft pages footer_only: Only pages marked for footer display header_only: Only pages marked for header display legal_only: Only pages marked for legal/bottom bar display Returns: List of ContentPage objects """ ... def list_platform_pages( self, db: "Session", platform_id: int, include_unpublished: bool = False, footer_only: bool = False, header_only: bool = False, ) -> list: """ List platform marketing pages. Args: db: Database session platform_id: Platform ID include_unpublished: Include draft pages footer_only: Only pages marked for footer display header_only: Only pages marked for header display Returns: List of platform marketing ContentPage objects """ ... @runtime_checkable class MediaUsageProviderProtocol(Protocol): """Protocol for modules that track media file usage.""" def get_media_usage(self, db: "Session", media_id: int) -> list[dict]: """Return list of usage records. Each dict should contain: entity_type: str (e.g. "product") entity_id: int entity_name: str usage_type: str (e.g. "main_image", "gallery") """ ... @runtime_checkable class MediaServiceProtocol(Protocol): """ Protocol for media library service. Defines the interface for managing media files (images, documents, etc.). """ def get_media_by_id( self, db: "Session", media_id: int, ) -> object | None: """Get media item by ID.""" ... def list_media_for_store( self, db: "Session", store_id: int, media_type: str | None = None, ) -> list: """List media items for a store.""" ...