# models/database_models.py from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Index, UniqueConstraint, Boolean from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime Base = declarative_base() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) email = Column(String, unique=True, index=True, nullable=False) username = Column(String, unique=True, index=True, nullable=False) hashed_password = Column(String, nullable=False) role = Column(String, nullable=False, default="user") # 'admin' or 'user' is_active = Column(Boolean, default=True, nullable=False) last_login = Column(DateTime, nullable=True) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) def __repr__(self): return f"" class Product(Base): __tablename__ = "products" id = Column(Integer, primary_key=True, index=True) product_id = Column(String, unique=True, index=True, nullable=False) title = Column(String, nullable=False) description = Column(String) link = Column(String) image_link = Column(String) availability = Column(String, index=True) # Index for filtering price = Column(String) brand = Column(String, index=True) # Index for filtering gtin = Column(String, index=True) # Index for stock lookups mpn = Column(String) condition = Column(String) adult = Column(String) multipack = Column(Integer) is_bundle = Column(String) age_group = Column(String) color = Column(String) gender = Column(String) material = Column(String) pattern = Column(String) size = Column(String) size_type = Column(String) size_system = Column(String) item_group_id = Column(String) google_product_category = Column(String, index=True) # Index for filtering product_type = Column(String) custom_label_0 = Column(String) custom_label_1 = Column(String) custom_label_2 = Column(String) custom_label_3 = Column(String) custom_label_4 = Column(String) additional_image_link = Column(String) sale_price = Column(String) unit_pricing_measure = Column(String) unit_pricing_base_measure = Column(String) identifier_exists = Column(String) shipping = Column(String) currency = Column(String) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) # Relationship to stock (one-to-many via GTIN) stock_entries = relationship("Stock", foreign_keys="Stock.gtin", primaryjoin="Product.gtin == Stock.gtin", viewonly=True) def __repr__(self): return f"" class Stock(Base): __tablename__ = "stock" id = Column(Integer, primary_key=True, index=True) gtin = Column(String, index=True, nullable=False) # Foreign key relationship would be ideal location = Column(String, nullable=False, index=True) quantity = Column(Integer, nullable=False, default=0) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False) # Composite unique constraint to prevent duplicate GTIN-location combinations __table_args__ = ( UniqueConstraint('gtin', 'location', name='uq_stock_gtin_location'), Index('idx_stock_gtin_location', 'gtin', 'location'), # Composite index for efficient queries ) def __repr__(self): return f"" class ImportJob(Base): __tablename__ = "import_jobs" id = Column(Integer, primary_key=True, index=True) status = Column(String, nullable=False, default="pending") # pending, processing, completed, failed, completed_with_errors source_url = Column(String, nullable=False) user_id = Column(Integer, ForeignKey('users.id')) # Foreign key to users table imported_count = Column(Integer, default=0) updated_count = Column(Integer, default=0) error_count = Column(Integer, default=0) total_processed = Column(Integer, default=0) error_message = Column(String) created_at = Column(DateTime, default=datetime.utcnow, nullable=False) started_at = Column(DateTime) completed_at = Column(DateTime) # Relationship to user user = relationship("User", foreign_keys=[user_id]) def __repr__(self): return f""