# app/modules/registry.py """ Module registry defining all available platform modules. Each module bundles related features and menu items that can be enabled/disabled per platform. Core modules cannot be disabled. Module Granularity (Medium - ~12 modules): Matches menu sections for intuitive mapping between modules and UI. """ from app.modules.base import ModuleDefinition from models.database.admin_menu_config import FrontendType # ============================================================================= # Module Definitions # ============================================================================= MODULES: dict[str, ModuleDefinition] = { # ========================================================================= # Core Modules (Always Enabled) # ========================================================================= "core": ModuleDefinition( code="core", name="Core Platform", description="Dashboard, settings, and profile management. Required for basic operation.", is_core=True, features=[ "dashboard", "settings", "profile", ], menu_items={ FrontendType.ADMIN: [ "dashboard", "settings", "email-templates", "my-menu", ], FrontendType.VENDOR: [ "dashboard", "profile", "settings", "email-templates", ], }, ), "platform-admin": ModuleDefinition( code="platform-admin", name="Platform Administration", description="Company, vendor, and admin user management. Required for multi-tenant operation.", is_core=True, features=[ "company_management", "vendor_management", "admin_user_management", "platform_management", ], menu_items={ FrontendType.ADMIN: [ "admin-users", "companies", "vendors", "platforms", ], FrontendType.VENDOR: [ "team", ], }, ), # ========================================================================= # Optional Modules # ========================================================================= "billing": ModuleDefinition( code="billing", name="Billing & Subscriptions", description="Subscription tiers, billing history, and payment processing.", features=[ "subscription_management", "billing_history", "stripe_integration", "invoice_generation", ], menu_items={ FrontendType.ADMIN: [ "subscription-tiers", "subscriptions", "billing-history", ], FrontendType.VENDOR: [ "billing", "invoices", ], }, ), "inventory": ModuleDefinition( code="inventory", name="Inventory Management", description="Stock levels, locations, and low stock alerts.", features=[ "inventory_basic", "inventory_locations", "low_stock_alerts", "inventory_purchase_orders", "product_management", ], menu_items={ FrontendType.ADMIN: [ "inventory", "vendor-products", ], FrontendType.VENDOR: [ "products", "inventory", ], }, ), "orders": ModuleDefinition( code="orders", name="Order Management", description="Order processing, fulfillment, and tracking.", features=[ "order_management", "order_bulk_actions", "order_export", "automation_rules", "fulfillment_tracking", "shipping_management", ], menu_items={ FrontendType.ADMIN: [ "orders", ], FrontendType.VENDOR: [ "orders", ], }, ), "marketplace": ModuleDefinition( code="marketplace", name="Marketplace (Letzshop)", description="Letzshop integration for product sync and order import.", requires=["inventory"], # Depends on inventory module features=[ "letzshop_sync", "marketplace_import", "product_sync", ], menu_items={ FrontendType.ADMIN: [ "marketplace-letzshop", ], FrontendType.VENDOR: [ "marketplace", "letzshop", ], }, ), "customers": ModuleDefinition( code="customers", name="Customer Management", description="Customer database, profiles, and segmentation.", features=[ "customer_view", "customer_export", "customer_profiles", "customer_segmentation", ], menu_items={ FrontendType.ADMIN: [ "customers", ], FrontendType.VENDOR: [ "customers", ], }, ), "cms": ModuleDefinition( code="cms", name="Content Management", description="Content pages, media library, and vendor themes.", features=[ "cms_basic", "cms_custom_pages", "cms_unlimited_pages", "cms_templates", "cms_seo", "media_library", ], menu_items={ FrontendType.ADMIN: [ "content-pages", "vendor-themes", ], FrontendType.VENDOR: [ "content-pages", "media", ], }, ), "analytics": ModuleDefinition( code="analytics", name="Analytics & Reporting", description="Dashboard analytics, custom reports, and data exports.", features=[ "basic_reports", "analytics_dashboard", "custom_reports", "export_reports", ], menu_items={ FrontendType.ADMIN: [ # Analytics appears in dashboard for admin ], FrontendType.VENDOR: [ "analytics", ], }, ), "messaging": ModuleDefinition( code="messaging", name="Messaging & Notifications", description="Internal messages, customer communication, and notifications.", features=[ "customer_messaging", "internal_messages", "notification_center", ], menu_items={ FrontendType.ADMIN: [ "messages", "notifications", ], FrontendType.VENDOR: [ "messages", "notifications", ], }, ), "dev-tools": ModuleDefinition( code="dev-tools", name="Developer Tools", description="Component library and icon browser for development.", features=[ "component_library", "icon_browser", ], menu_items={ FrontendType.ADMIN: [ "components", "icons", ], FrontendType.VENDOR: [], }, ), "monitoring": ModuleDefinition( code="monitoring", name="Platform Monitoring", description="Logs, background tasks, imports, and system health.", features=[ "application_logs", "background_tasks", "import_jobs", "capacity_monitoring", "testing_hub", "code_quality", ], menu_items={ FrontendType.ADMIN: [ "imports", "background-tasks", "logs", "platform-health", "testing", "code-quality", ], FrontendType.VENDOR: [], }, ), } # ============================================================================= # Helper Functions # ============================================================================= def get_module(code: str) -> ModuleDefinition | None: """Get a module definition by code.""" return MODULES.get(code) def get_core_modules() -> list[ModuleDefinition]: """Get all core modules (cannot be disabled).""" return [m for m in MODULES.values() if m.is_core] def get_core_module_codes() -> set[str]: """Get codes of all core modules.""" return {m.code for m in MODULES.values() if m.is_core} def get_optional_modules() -> list[ModuleDefinition]: """Get all optional modules (can be enabled/disabled).""" return [m for m in MODULES.values() if not m.is_core] def get_all_module_codes() -> set[str]: """Get all module codes.""" return set(MODULES.keys()) def get_menu_item_module(menu_item_id: str, frontend_type: FrontendType) -> str | None: """ Find which module provides a specific menu item. Args: menu_item_id: The menu item ID to find frontend_type: The frontend type to search in Returns: Module code if found, None otherwise """ for module in MODULES.values(): if menu_item_id in module.get_menu_items(frontend_type): return module.code return None def get_feature_module(feature_code: str) -> str | None: """ Find which module provides a specific feature. Args: feature_code: The feature code to find Returns: Module code if found, None otherwise """ for module in MODULES.values(): if module.has_feature(feature_code): return module.code return None def validate_module_dependencies() -> list[str]: """ Validate that all module dependencies are valid. Returns: List of error messages for invalid dependencies """ errors = [] all_codes = get_all_module_codes() for module in MODULES.values(): for required in module.requires: if required not in all_codes: errors.append( f"Module '{module.code}' requires unknown module '{required}'" ) # Core modules should not depend on optional modules if module.is_core and required not in get_core_module_codes(): errors.append( f"Core module '{module.code}' depends on optional module '{required}'" ) return errors # Validate dependencies on import (development check) _validation_errors = validate_module_dependencies() if _validation_errors: import warnings for error in _validation_errors: warnings.warn(f"Module registry validation: {error}", stacklevel=2) __all__ = [ "MODULES", "get_module", "get_core_modules", "get_core_module_codes", "get_optional_modules", "get_all_module_codes", "get_menu_item_module", "get_feature_module", "validate_module_dependencies", ]