refactor: migrate Feature to billing module and split ProductMedia to catalog
- Move Feature model from models/database/ to app/modules/billing/models/ (tightly coupled to SubscriptionTier for tier-based access control) - Move ProductMedia from models/database/media.py to app/modules/catalog/models/ (product-specific media associations belong with catalog) - Keep MediaFile as CORE in models/database/media.py (cross-cutting file storage) - Convert legacy feature.py to re-export for backwards compatibility - Update all imports to use canonical module locations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,13 +5,15 @@ Catalog module models.
|
||||
This is the canonical location for product models.
|
||||
|
||||
Usage:
|
||||
from app.modules.catalog.models import Product, ProductTranslation
|
||||
from app.modules.catalog.models import Product, ProductTranslation, ProductMedia
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
__all__ = [
|
||||
"Product",
|
||||
"ProductTranslation",
|
||||
"ProductMedia",
|
||||
]
|
||||
|
||||
71
app/modules/catalog/models/product_media.py
Normal file
71
app/modules/catalog/models/product_media.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# app/modules/catalog/models/product_media.py
|
||||
"""
|
||||
Product-Media association model.
|
||||
|
||||
Links media files to products with usage type tracking
|
||||
(main image, gallery, variant images, etc.)
|
||||
"""
|
||||
|
||||
from sqlalchemy import (
|
||||
Column,
|
||||
ForeignKey,
|
||||
Index,
|
||||
Integer,
|
||||
String,
|
||||
UniqueConstraint,
|
||||
)
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from app.core.database import Base
|
||||
from models.database.base import TimestampMixin
|
||||
|
||||
|
||||
class ProductMedia(Base, TimestampMixin):
|
||||
"""Association between products and media files.
|
||||
|
||||
Tracks which media files are used by which products,
|
||||
including the usage type (main image, gallery, variant, etc.)
|
||||
"""
|
||||
|
||||
__tablename__ = "product_media"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
product_id = Column(
|
||||
Integer,
|
||||
ForeignKey("products.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
)
|
||||
media_id = Column(
|
||||
Integer,
|
||||
ForeignKey("media_files.id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
# Usage type
|
||||
usage_type = Column(String(50), nullable=False, default="gallery")
|
||||
# Types: main_image, gallery, variant, thumbnail, swatch
|
||||
|
||||
# Display order for galleries
|
||||
display_order = Column(Integer, default=0)
|
||||
|
||||
# Variant-specific (if usage_type is variant)
|
||||
variant_id = Column(Integer) # Reference to variant if applicable
|
||||
|
||||
# Relationships
|
||||
product = relationship("Product")
|
||||
media = relationship("MediaFile", back_populates="product_associations")
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
"product_id", "media_id", "usage_type",
|
||||
name="uq_product_media_usage"
|
||||
),
|
||||
Index("idx_product_media_product", "product_id"),
|
||||
Index("idx_product_media_media", "media_id"),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"<ProductMedia(product_id={self.product_id}, "
|
||||
f"media_id={self.media_id}, usage='{self.usage_type}')>"
|
||||
)
|
||||
Reference in New Issue
Block a user