from __future__ import annotations import uuid from datetime import datetime from typing import Optional from sqlalchemy import Boolean, DateTime, Enum, ForeignKey, Integer, String, Text, UniqueConstraint, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.db.base_class import Base from app.models.document import DocumentScopeType class EtmfNode(Base): __tablename__ = "etmf_nodes" __table_args__ = ( UniqueConstraint("study_id", "parent_id", "code", name="uq_etmf_nodes_study_parent_code"), ) id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) study_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), nullable=False) parent_id: Mapped[Optional[uuid.UUID]] = mapped_column(UUID(as_uuid=True), ForeignKey("etmf_nodes.id"), nullable=True) code: Mapped[str] = mapped_column(String(50), nullable=False) name: Mapped[str] = mapped_column(String(200), nullable=False) description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) scope_type: Mapped[DocumentScopeType] = mapped_column( Enum(DocumentScopeType, name="document_scope_type"), nullable=False, server_default=DocumentScopeType.GLOBAL.value, ) required: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, server_default="false") expected_doc_type: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0") is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, server_default="true") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now(), ) parent = relationship("EtmfNode", remote_side=[id], foreign_keys=[parent_id])