Files
orion/app/modules/billing/services/billing_metrics.py
Samir Boulahtit 9c27fa02b0
Some checks failed
CI / ruff (push) Failing after 8s
CI / pytest (push) Successful in 36m5s
CI / architecture (push) Successful in 11s
CI / dependency-scanning (push) Successful in 27s
CI / docs (push) Has been skipped
CI / audit (push) Successful in 8s
refactor: move capacity_forecast_service from billing to monitoring
Resolves the billing (core) → monitoring (optional) architecture violation
by moving CapacityForecastService to the monitoring module where it belongs.

- Create BillingMetricsProvider to expose subscription counts via stats_aggregator
- Move CapacitySnapshot model from billing to monitoring
- Replace direct MerchantSubscription queries with stats_aggregator calls
- Fix middleware test mocks to cover StoreDomain/MerchantDomain fallback chains

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:58:22 +01:00

116 lines
3.2 KiB
Python

# 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 []
# Singleton instance
billing_metrics_provider = BillingMetricsProvider()
__all__ = ["BillingMetricsProvider", "billing_metrics_provider"]