fix: resolve cross-module import violations with lazy import pattern

- Convert core→optional imports to lazy imports with try/except fallbacks
- cms/media_service: use TYPE_CHECKING for ProductMedia type hints
- customers/customer_service: wrap Order imports in try/except
- tenancy/admin_platform_users: wrap stats_service import in try/except
- Enhance validate_architecture.py to recognize lazy import patterns
- Add module_dependency_graph.py script for dependency visualization

The lazy import pattern allows optional modules to be truly optional while
maintaining type safety through TYPE_CHECKING blocks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 19:22:11 +01:00
parent 5afc0fdfae
commit 37942ae02b
5 changed files with 574 additions and 40 deletions

View File

@@ -329,25 +329,30 @@ class CustomerService:
Raises:
CustomerNotFoundException: If customer not found
"""
from app.modules.orders.models import Order
# Verify customer belongs to vendor
self.get_customer(db, vendor_id, customer_id)
# Get customer orders
query = (
db.query(Order)
.filter(
Order.customer_id == customer_id,
Order.vendor_id == vendor_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())
)
.order_by(Order.created_at.desc())
)
total = query.count()
orders = query.offset(skip).limit(limit).all()
total = query.count()
orders = query.offset(skip).limit(limit).all()
return orders, total
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
@@ -363,34 +368,43 @@ class CustomerService:
Returns:
Dict with customer statistics
"""
from sqlalchemy import func
from app.modules.orders.models import Order
customer = self.get_customer(db, vendor_id, customer_id)
# Get order statistics
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()
)
# Get order statistics if orders module is available
try:
from sqlalchemy import func
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
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": order_stats.last_order_date,
"last_order_date": last_order_date,
"member_since": customer.created_at,
"is_active": customer.is_active,
}