import uuid from datetime import datetime from typing import Optional, Any from sqlalchemy import String, Text, DateTime, ForeignKey, Boolean, Integer, Index from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import UUID, JSONB from app.core.database import Base class Tree(Base): __tablename__ = "trees" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) name: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) category: Mapped[Optional[str]] = mapped_column(String(100), nullable=True, index=True) tree_structure: Mapped[dict[str, Any]] = mapped_column(JSONB, nullable=False) author_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True ) team_id: Mapped[Optional[uuid.UUID]] = mapped_column( UUID(as_uuid=True), ForeignKey("teams.id"), nullable=True, index=True ) is_active: Mapped[bool] = mapped_column(Boolean, default=True) version: Mapped[int] = mapped_column(Integer, default=1) created_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow ) updated_at: Mapped[datetime] = mapped_column( DateTime, default=datetime.utcnow, onupdate=datetime.utcnow ) usage_count: Mapped[int] = mapped_column(Integer, default=0) # Relationships author: Mapped[Optional["User"]] = relationship("User", back_populates="trees") team: Mapped[Optional["Team"]] = relationship("Team", back_populates="trees") sessions: Mapped[list["Session"]] = relationship("Session", back_populates="tree") # Full-text search index will be created in migration