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:
@@ -9,11 +9,11 @@ Usage:
|
||||
"""
|
||||
|
||||
from app.modules.catalog.models.product import Product
|
||||
from app.modules.catalog.models.product_translation import ProductTranslation
|
||||
from app.modules.catalog.models.product_media import ProductMedia
|
||||
from app.modules.catalog.models.product_translation import ProductTranslation
|
||||
|
||||
__all__ = [
|
||||
"Product",
|
||||
"ProductTranslation",
|
||||
"ProductMedia",
|
||||
"ProductTranslation",
|
||||
]
|
||||
|
||||
@@ -114,6 +114,9 @@ class Product(Base, TimestampMixin):
|
||||
inventory_entries = relationship(
|
||||
"Inventory", back_populates="product", cascade="all, delete-orphan"
|
||||
)
|
||||
media_associations = relationship(
|
||||
"ProductMedia", back_populates="product", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
# === CONSTRAINTS & INDEXES ===
|
||||
__table_args__ = (
|
||||
|
||||
@@ -4,6 +4,11 @@ Product-Media association model.
|
||||
|
||||
Links media files to products with usage type tracking
|
||||
(main image, gallery, variant images, etc.)
|
||||
|
||||
This model lives in the catalog module because:
|
||||
- It's an association specific to products
|
||||
- Catalog owns the relationship between its products and media
|
||||
- CMS provides generic media storage, catalog defines how it uses media
|
||||
"""
|
||||
|
||||
from sqlalchemy import (
|
||||
@@ -25,6 +30,8 @@ class ProductMedia(Base, TimestampMixin):
|
||||
|
||||
Tracks which media files are used by which products,
|
||||
including the usage type (main image, gallery, variant, etc.)
|
||||
|
||||
This is catalog's association table - CMS doesn't need to know about it.
|
||||
"""
|
||||
|
||||
__tablename__ = "product_media"
|
||||
@@ -52,8 +59,9 @@ class ProductMedia(Base, TimestampMixin):
|
||||
variant_id = Column(Integer) # Reference to variant if applicable
|
||||
|
||||
# Relationships
|
||||
product = relationship("Product")
|
||||
media = relationship("MediaFile", back_populates="product_associations")
|
||||
product = relationship("Product", back_populates="media_associations")
|
||||
# MediaFile is generic and doesn't know about ProductMedia
|
||||
media = relationship("MediaFile", lazy="joined")
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
|
||||
Reference in New Issue
Block a user