# app/modules/billing/definition.py """ Billing module definition. Defines the billing module including its features, menu items, route configurations, and scheduled tasks. """ from app.modules.base import ModuleDefinition, ScheduledTask from models.database.admin_menu_config import FrontendType def _get_admin_router(): """Lazy import of admin router to avoid circular imports.""" from app.modules.billing.routes.api.admin import admin_router return admin_router def _get_vendor_router(): """Lazy import of vendor router to avoid circular imports.""" from app.modules.billing.routes.api.vendor import vendor_router return vendor_router # Billing module definition billing_module = ModuleDefinition( code="billing", name="Billing & Subscriptions", description=( "Platform subscription management, vendor billing, and invoice history. " "Uses the payments module for actual payment processing." ), version="1.0.0", requires=["payments"], # Depends on payments module for payment processing features=[ "subscription_management", # Manage subscription tiers "billing_history", # View invoices and payment history "invoice_generation", # Generate and download invoices "subscription_analytics", # Subscription stats and metrics "trial_management", # Manage vendor trial periods "limit_overrides", # Override tier limits per vendor ], menu_items={ FrontendType.ADMIN: [ "subscription-tiers", # Manage tier definitions "subscriptions", # View/manage vendor subscriptions "billing-history", # View all invoices ], FrontendType.VENDOR: [ "billing", # Vendor billing dashboard "invoices", # Vendor invoice history ], }, is_core=False, # Billing can be disabled (e.g., internal platforms) # ========================================================================= # Self-Contained Module Configuration # ========================================================================= is_self_contained=True, services_path="app.modules.billing.services", models_path="app.modules.billing.models", schemas_path="app.modules.billing.schemas", exceptions_path="app.modules.billing.exceptions", tasks_path="app.modules.billing.tasks", # ========================================================================= # Scheduled Tasks # ========================================================================= scheduled_tasks=[ ScheduledTask( name="billing.reset_period_counters", task="app.modules.billing.tasks.subscription.reset_period_counters", schedule="5 0 * * *", # Daily at 00:05 options={"queue": "scheduled"}, ), ScheduledTask( name="billing.check_trial_expirations", task="app.modules.billing.tasks.subscription.check_trial_expirations", schedule="0 1 * * *", # Daily at 01:00 options={"queue": "scheduled"}, ), ScheduledTask( name="billing.sync_stripe_status", task="app.modules.billing.tasks.subscription.sync_stripe_status", schedule="30 * * * *", # Hourly at :30 options={"queue": "scheduled"}, ), ScheduledTask( name="billing.cleanup_stale_subscriptions", task="app.modules.billing.tasks.subscription.cleanup_stale_subscriptions", schedule="0 3 * * 0", # Weekly on Sunday at 03:00 options={"queue": "scheduled"}, ), ], ) def get_billing_module_with_routers() -> ModuleDefinition: """ Get billing module with routers attached. This function attaches the routers lazily to avoid circular imports during module initialization. """ billing_module.admin_router = _get_admin_router() billing_module.vendor_router = _get_vendor_router() return billing_module __all__ = ["billing_module", "get_billing_module_with_routers"]