from sqlalchemy import Column, String, Integer, BigInteger, Boolean, DateTime, ForeignKey, Text, CheckConstraint, Index from sqlalchemy.sql import func from datetime import datetime from app.core.database.db_session import Base class FileUpload(Base): __tablename__ = "file_uploads" file_id = Column(String(26), primary_key=True) original_name = Column(String(255), nullable=False) stored_name = Column(String(100), nullable=True) mime_type = Column(String(100), nullable=False) extension = Column(String(10), nullable=True) file_size = Column(BigInteger, nullable=False) storage_provider = Column(String(30), nullable=False, default="LOCAL") # Path variants raw_path = Column(String(500), nullable=True) webp_path = Column(String(500), nullable=True) thumbnail_path = Column(String(500), nullable=True) medium_path = Column(String(500), nullable=True) large_path = Column(String(500), nullable=True) storage_path = Column(String(500), nullable=True) # Legacy fallback compatibility entity_type = Column(String(50), nullable=True) entity_id = Column(String(50), nullable=True) blur_hash = Column(String(255), nullable=True) # State machine status status = Column( String(30), CheckConstraint("status IN ('ACTIVE', 'ORPHANED', 'PENDING_DELETE', 'DELETED', 'INCONSISTENT')"), nullable=False, default="ACTIVE", server_default="ACTIVE" ) # Lifecycle audit timestamps & tracking orphaned_at = Column(DateTime, nullable=True) cleanup_claimed_at = Column(DateTime, nullable=True) cleanup_started_at = Column(DateTime, nullable=True) deleted_at = Column(DateTime, nullable=True) last_reconciled_at = Column(DateTime, nullable=True) cleanup_attempts = Column(Integer, nullable=False, default=0) last_cleanup_error = Column(Text, nullable=True) uploaded_by = Column(String(26), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True) created_at = Column(DateTime, server_default=func.now()) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) __table_args__ = ( Index("idx_file_uploads_status_orphaned", "status", "orphaned_at"), )