# app/modules/customers/models/customer.py """ Customer database models. Provides Customer and CustomerAddress models for store-scoped customer management. """ from sqlalchemy import ( JSON, Boolean, Column, Date, ForeignKey, Integer, String, ) from sqlalchemy.orm import relationship from app.core.database import Base from models.database.base import SoftDeleteMixin, TimestampMixin class Customer(Base, TimestampMixin, SoftDeleteMixin): """Customer model with store isolation.""" __tablename__ = "customers" id = Column(Integer, primary_key=True, index=True) store_id = Column(Integer, ForeignKey("stores.id"), nullable=False) email = Column( String(255), nullable=False, index=True ) # Unique within store scope hashed_password = Column(String(255), nullable=False) first_name = Column(String(100)) last_name = Column(String(100)) phone = Column(String(50)) birth_date = Column(Date, nullable=True) customer_number = Column( String(100), nullable=False, index=True ) # Store-specific ID preferences = Column(JSON, default=dict) marketing_consent = Column(Boolean, default=False) is_active = Column(Boolean, default=True, nullable=False) # Language preference (NULL = use store storefront_language default) # Supported: en, fr, de, lb preferred_language = Column(String(5), nullable=True) # Relationships store = relationship("Store", back_populates="customers") addresses = relationship("CustomerAddress", back_populates="customer") orders = relationship("Order", back_populates="customer") def __repr__(self): return f"" @property def full_name(self): if self.first_name and self.last_name: return f"{self.first_name} {self.last_name}" return self.email class CustomerAddress(Base, TimestampMixin): """Customer address model for shipping and billing addresses.""" __tablename__ = "customer_addresses" id = Column(Integer, primary_key=True, index=True) store_id = Column(Integer, ForeignKey("stores.id"), nullable=False) customer_id = Column(Integer, ForeignKey("customers.id"), nullable=False) address_type = Column(String(50), nullable=False) # 'billing', 'shipping' first_name = Column(String(100), nullable=False) last_name = Column(String(100), nullable=False) company = Column(String(200)) address_line_1 = Column(String(255), nullable=False) address_line_2 = Column(String(255)) city = Column(String(100), nullable=False) postal_code = Column(String(20), nullable=False) country_name = Column(String(100), nullable=False) country_iso = Column(String(5), nullable=False) is_default = Column(Boolean, default=False) # Relationships store = relationship("Store") customer = relationship("Customer", back_populates="addresses") def __repr__(self): return f""