# app/modules/billing/services/billing_metrics.py """ Metrics provider for the billing module. Provides metrics for: - Subscription counts (total, active, trial) """ import logging from sqlalchemy import func from sqlalchemy.orm import Session from app.modules.contracts.metrics import ( MetricsContext, MetricValue, ) logger = logging.getLogger(__name__) class BillingMetricsProvider: """ Metrics provider for billing module. Provides subscription metrics at the platform level. """ @property def metrics_category(self) -> str: return "billing" def get_store_metrics( self, db: Session, store_id: int, context: MetricsContext | None = None, ) -> list[MetricValue]: """ Get metrics for a specific store. Subscriptions are merchant-level, not store-level, so no store metrics. """ return [] def get_platform_metrics( self, db: Session, platform_id: int, context: MetricsContext | None = None, ) -> list[MetricValue]: """ Get subscription metrics aggregated for a platform. Provides: - Total subscriptions - Active subscriptions (active + trial) - Trial subscriptions """ from app.modules.billing.models import MerchantSubscription, SubscriptionStatus try: total_subs = ( db.query(func.count(MerchantSubscription.id)).scalar() or 0 ) active_subs = ( db.query(func.count(MerchantSubscription.id)) .filter(MerchantSubscription.status.in_(["active", "trial"])) .scalar() or 0 ) trial_subs = ( db.query(func.count(MerchantSubscription.id)) .filter(MerchantSubscription.status == SubscriptionStatus.TRIAL.value) .scalar() or 0 ) return [ MetricValue( key="billing.total_subscriptions", value=total_subs, label="Total Subscriptions", category="billing", icon="credit-card", description="Total number of merchant subscriptions", ), MetricValue( key="billing.active_subscriptions", value=active_subs, label="Active Subscriptions", category="billing", icon="check-circle", description="Subscriptions with active or trial status", ), MetricValue( key="billing.trial_subscriptions", value=trial_subs, label="Trial Subscriptions", category="billing", icon="clock", description="Subscriptions currently in trial period", ), ] except Exception as e: logger.warning(f"Failed to get billing platform metrics: {e}") return [] def get_merchant_metrics( self, db: Session, merchant_id: int, context: MetricsContext | None = None, ) -> list[MetricValue]: """ Get subscription metrics for a specific merchant. Provides: - Active subscriptions (active + trial) """ from app.modules.billing.models import MerchantSubscription try: active_subs = ( db.query(func.count(MerchantSubscription.id)) .filter( MerchantSubscription.merchant_id == merchant_id, MerchantSubscription.status.in_(["active", "trial"]), ) .scalar() or 0 ) return [ MetricValue( key="billing.active_subscriptions", value=active_subs, label="Active Subscriptions", category="billing", icon="clipboard-list", description="Active or trial subscriptions for this merchant", ), ] except Exception as e: logger.warning(f"Failed to get billing merchant metrics: {e}") return [] # Singleton instance billing_metrics_provider = BillingMetricsProvider() __all__ = ["BillingMetricsProvider", "billing_metrics_provider"]