""" Folder and SourceRoot model definitions """ from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Index from sqlalchemy.sql import func from sqlalchemy.orm import relationship import uuid from app.database import Base class SourceRoot(Base): __tablename__ = 'source_roots' id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String, nullable=False) path = Column(String, unique=True, nullable=False) is_active = Column(Boolean, default=True) added_at = Column(DateTime, server_default=func.now()) # Owner user_id = Column(String, ForeignKey('users.id'), nullable=True, index=True) # Relationships folders = relationship("Folder", back_populates="source_root") class Folder(Base): __tablename__ = 'folders' id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) name = Column(String, nullable=False) path = Column(String, unique=True, nullable=False) parent_id = Column(String, ForeignKey('folders.id')) source_root_id = Column(String, ForeignKey('source_roots.id')) # Owner user_id = Column(String, ForeignKey('users.id'), nullable=True, index=True) photo_count = Column(Integer, default=0) last_scanned = Column(DateTime) # "Hide from views" — when true, photos in this folder (and every # descendant folder) are excluded from cross-cutting views like # All Photos, Map, Tags, People, Search and the sidebar counts. # Photos are still scanned, thumbnailed and indexed — they just # stop showing up unless the user navigates directly to a folder # inside the hidden subtree. The effective flag is materialized # onto Photo.is_hidden so queries don't have to walk parent_id. is_hidden = Column(Boolean, nullable=False, default=False, server_default='false') # Relationships source_root = relationship("SourceRoot", back_populates="folders") photos = relationship("Photo", backref="folder") # Indexes __table_args__ = ( Index('ix_folders_path', 'path'), Index('ix_folders_parent_id', 'parent_id'), Index('ix_folders_source_root_id', 'source_root_id'), )