refactor: fix architecture violations with provider patterns and dependency inversion
Major changes: - Add AuditProvider protocol for cross-module audit logging - Move customer order operations to orders module (dependency inversion) - Add customer order metrics via MetricsProvider pattern - Fix missing db parameter in get_admin_context() calls - Move ProductMedia relationship to catalog module (proper ownership) - Add marketplace breakdown stats to marketplace_widgets New files: - contracts/audit.py - AuditProviderProtocol - core/services/audit_aggregator.py - Aggregates audit providers - monitoring/services/audit_provider.py - Monitoring audit implementation - orders/services/customer_order_service.py - Customer order operations - orders/routes/api/vendor_customer_orders.py - Customer order endpoints - catalog/services/product_media_service.py - Product media service - Architecture documentation for patterns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@ if TYPE_CHECKING:
|
||||
from fastapi import APIRouter
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.modules.contracts.audit import AuditProviderProtocol
|
||||
from app.modules.contracts.metrics import MetricsProviderProtocol
|
||||
from app.modules.contracts.widgets import DashboardWidgetProviderProtocol
|
||||
|
||||
@@ -434,6 +435,26 @@ class ModuleDefinition:
|
||||
# The provider will be discovered by core's WidgetAggregator service.
|
||||
widget_provider: "Callable[[], DashboardWidgetProviderProtocol] | None" = None
|
||||
|
||||
# =========================================================================
|
||||
# Audit Provider (Module-Driven Audit Logging)
|
||||
# =========================================================================
|
||||
# Callable that returns an AuditProviderProtocol implementation.
|
||||
# Use a callable (factory function) to enable lazy loading and avoid
|
||||
# circular imports. Modules can provide audit logging backends.
|
||||
#
|
||||
# Example:
|
||||
# def _get_audit_provider():
|
||||
# from app.modules.monitoring.services.audit_provider import audit_provider
|
||||
# return audit_provider
|
||||
#
|
||||
# monitoring_module = ModuleDefinition(
|
||||
# code="monitoring",
|
||||
# audit_provider=_get_audit_provider,
|
||||
# )
|
||||
#
|
||||
# The provider will be discovered by core's AuditAggregator service.
|
||||
audit_provider: "Callable[[], AuditProviderProtocol] | None" = None
|
||||
|
||||
# =========================================================================
|
||||
# Menu Item Methods (Legacy - uses menu_items dict of IDs)
|
||||
# =========================================================================
|
||||
@@ -842,6 +863,28 @@ class ModuleDefinition:
|
||||
return None
|
||||
return self.widget_provider()
|
||||
|
||||
# =========================================================================
|
||||
# Audit Provider Methods
|
||||
# =========================================================================
|
||||
|
||||
def has_audit_provider(self) -> bool:
|
||||
"""Check if this module has an audit provider."""
|
||||
return self.audit_provider is not None
|
||||
|
||||
def get_audit_provider_instance(self) -> "AuditProviderProtocol | None":
|
||||
"""
|
||||
Get the audit provider instance for this module.
|
||||
|
||||
Calls the audit_provider factory function to get the provider.
|
||||
Returns None if no provider is configured.
|
||||
|
||||
Returns:
|
||||
AuditProviderProtocol instance, or None
|
||||
"""
|
||||
if self.audit_provider is None:
|
||||
return None
|
||||
return self.audit_provider()
|
||||
|
||||
# =========================================================================
|
||||
# Magic Methods
|
||||
# =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user