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:
@@ -305,109 +305,11 @@ class CustomerService:
|
||||
|
||||
return customers, total
|
||||
|
||||
def get_customer_orders(
|
||||
self,
|
||||
db: Session,
|
||||
vendor_id: int,
|
||||
customer_id: int,
|
||||
skip: int = 0,
|
||||
limit: int = 50,
|
||||
) -> tuple[list, int]:
|
||||
"""
|
||||
Get orders for a specific customer.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor_id: Vendor ID
|
||||
customer_id: Customer ID
|
||||
skip: Pagination offset
|
||||
limit: Pagination limit
|
||||
|
||||
Returns:
|
||||
Tuple of (orders, total_count)
|
||||
|
||||
Raises:
|
||||
CustomerNotFoundException: If customer not found
|
||||
"""
|
||||
# Verify customer belongs to vendor
|
||||
self.get_customer(db, vendor_id, customer_id)
|
||||
|
||||
try:
|
||||
from app.modules.orders.models import Order
|
||||
|
||||
# Get customer orders
|
||||
query = (
|
||||
db.query(Order)
|
||||
.filter(
|
||||
Order.customer_id == customer_id,
|
||||
Order.vendor_id == vendor_id,
|
||||
)
|
||||
.order_by(Order.created_at.desc())
|
||||
)
|
||||
|
||||
total = query.count()
|
||||
orders = query.offset(skip).limit(limit).all()
|
||||
|
||||
return orders, total
|
||||
except ImportError:
|
||||
# Orders module not available
|
||||
logger.warning("Orders module not available for customer orders")
|
||||
return [], 0
|
||||
|
||||
def get_customer_statistics(
|
||||
self, db: Session, vendor_id: int, customer_id: int
|
||||
) -> dict:
|
||||
"""
|
||||
Get detailed statistics for a customer.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor_id: Vendor ID
|
||||
customer_id: Customer ID
|
||||
|
||||
Returns:
|
||||
Dict with customer statistics
|
||||
"""
|
||||
customer = self.get_customer(db, vendor_id, customer_id)
|
||||
|
||||
# Get order statistics if orders module is available
|
||||
try:
|
||||
from sqlalchemy import func
|
||||
|
||||
from app.modules.orders.models import Order
|
||||
|
||||
order_stats = (
|
||||
db.query(
|
||||
func.count(Order.id).label("total_orders"),
|
||||
func.sum(Order.total_cents).label("total_spent_cents"),
|
||||
func.avg(Order.total_cents).label("avg_order_cents"),
|
||||
func.max(Order.created_at).label("last_order_date"),
|
||||
)
|
||||
.filter(Order.customer_id == customer_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
total_orders = order_stats.total_orders or 0
|
||||
total_spent_cents = order_stats.total_spent_cents or 0
|
||||
avg_order_cents = order_stats.avg_order_cents or 0
|
||||
last_order_date = order_stats.last_order_date
|
||||
except ImportError:
|
||||
# Orders module not available
|
||||
logger.warning("Orders module not available for customer statistics")
|
||||
total_orders = 0
|
||||
total_spent_cents = 0
|
||||
avg_order_cents = 0
|
||||
last_order_date = None
|
||||
|
||||
return {
|
||||
"customer_id": customer_id,
|
||||
"total_orders": total_orders,
|
||||
"total_spent": total_spent_cents / 100, # Convert to euros
|
||||
"average_order_value": avg_order_cents / 100 if avg_order_cents else 0.0,
|
||||
"last_order_date": last_order_date,
|
||||
"member_since": customer.created_at,
|
||||
"is_active": customer.is_active,
|
||||
}
|
||||
# Note: Customer order methods have been moved to the orders module.
|
||||
# Use orders.services.customer_order_service for:
|
||||
# - get_customer_orders()
|
||||
# Use orders.services.order_metrics.get_customer_order_metrics() for:
|
||||
# - customer order statistics
|
||||
|
||||
def toggle_customer_status(
|
||||
self, db: Session, vendor_id: int, customer_id: int
|
||||
|
||||
Reference in New Issue
Block a user