# app/modules/cms/services/cms_metrics.py """ Metrics provider for the CMS module. Provides metrics for: - Content pages - Media files - Themes """ import logging from typing import TYPE_CHECKING from sqlalchemy import func from sqlalchemy.orm import Session from app.modules.contracts.metrics import ( MetricValue, MetricsContext, MetricsProviderProtocol, ) if TYPE_CHECKING: pass logger = logging.getLogger(__name__) class CMSMetricsProvider: """ Metrics provider for CMS module. Provides content management metrics for vendor and platform dashboards. """ @property def metrics_category(self) -> str: return "cms" def get_vendor_metrics( self, db: Session, vendor_id: int, context: MetricsContext | None = None, ) -> list[MetricValue]: """ Get CMS metrics for a specific vendor. Provides: - Total content pages - Published pages - Media files count - Theme status """ from app.modules.cms.models import ContentPage, MediaFile, VendorTheme try: # Content pages total_pages = ( db.query(ContentPage).filter(ContentPage.vendor_id == vendor_id).count() ) published_pages = ( db.query(ContentPage) .filter( ContentPage.vendor_id == vendor_id, ContentPage.is_published == True, ) .count() ) # Media files media_count = ( db.query(MediaFile).filter(MediaFile.vendor_id == vendor_id).count() ) # Total media size (in MB) total_media_size = ( db.query(func.sum(MediaFile.file_size)) .filter(MediaFile.vendor_id == vendor_id) .scalar() or 0 ) total_media_size_mb = round(total_media_size / (1024 * 1024), 2) # Theme configured has_theme = ( db.query(VendorTheme).filter(VendorTheme.vendor_id == vendor_id).first() is not None ) return [ MetricValue( key="cms.total_pages", value=total_pages, label="Total Pages", category="cms", icon="file-text", description="Total content pages created", ), MetricValue( key="cms.published_pages", value=published_pages, label="Published Pages", category="cms", icon="globe", description="Content pages that are published", ), MetricValue( key="cms.media_count", value=media_count, label="Media Files", category="cms", icon="image", description="Files in media library", ), MetricValue( key="cms.media_size", value=total_media_size_mb, label="Media Size", category="cms", icon="hard-drive", unit="MB", description="Total storage used by media", ), MetricValue( key="cms.has_theme", value=1 if has_theme else 0, label="Theme Configured", category="cms", icon="palette", description="Whether a custom theme is configured", ), ] except Exception as e: logger.warning(f"Failed to get CMS vendor metrics: {e}") return [] def get_platform_metrics( self, db: Session, platform_id: int, context: MetricsContext | None = None, ) -> list[MetricValue]: """ Get CMS metrics aggregated for a platform. Aggregates content management data across all vendors. """ from app.modules.cms.models import ContentPage, MediaFile, VendorTheme from app.modules.tenancy.models import VendorPlatform try: # Get all vendor IDs for this platform using VendorPlatform junction table vendor_ids = ( db.query(VendorPlatform.vendor_id) .filter( VendorPlatform.platform_id == platform_id, VendorPlatform.is_active == True, ) .subquery() ) # Content pages total_pages = ( db.query(ContentPage) .filter(ContentPage.vendor_id.in_(vendor_ids)) .count() ) published_pages = ( db.query(ContentPage) .filter( ContentPage.vendor_id.in_(vendor_ids), ContentPage.is_published == True, ) .count() ) # Media files media_count = ( db.query(MediaFile).filter(MediaFile.vendor_id.in_(vendor_ids)).count() ) # Total media size (in GB for platform-level) total_media_size = ( db.query(func.sum(MediaFile.file_size)) .filter(MediaFile.vendor_id.in_(vendor_ids)) .scalar() or 0 ) total_media_size_gb = round(total_media_size / (1024 * 1024 * 1024), 2) # Vendors with themes vendors_with_themes = ( db.query(func.count(func.distinct(VendorTheme.vendor_id))) .filter(VendorTheme.vendor_id.in_(vendor_ids)) .scalar() or 0 ) return [ MetricValue( key="cms.total_pages", value=total_pages, label="Total Pages", category="cms", icon="file-text", description="Total content pages across all vendors", ), MetricValue( key="cms.published_pages", value=published_pages, label="Published Pages", category="cms", icon="globe", description="Published content pages across all vendors", ), MetricValue( key="cms.media_count", value=media_count, label="Media Files", category="cms", icon="image", description="Total media files across all vendors", ), MetricValue( key="cms.media_size", value=total_media_size_gb, label="Total Media Size", category="cms", icon="hard-drive", unit="GB", description="Total storage used by media", ), MetricValue( key="cms.vendors_with_themes", value=vendors_with_themes, label="Themed Vendors", category="cms", icon="palette", description="Vendors with custom themes", ), ] except Exception as e: logger.warning(f"Failed to get CMS platform metrics: {e}") return [] # Singleton instance cms_metrics_provider = CMSMetricsProvider() __all__ = ["CMSMetricsProvider", "cms_metrics_provider"]