import enum import uuid from datetime import datetime from typing import Optional from pydantic import BaseModel, ConfigDict, Field from app.schemas.document import DocumentScopeType, DocumentSummary class EtmfNodeStatus(str, enum.Enum): NOT_REQUIRED = "NOT_REQUIRED" MISSING = "MISSING" UPLOADED = "UPLOADED" EFFECTIVE = "EFFECTIVE" INACTIVE = "INACTIVE" class EtmfNodeBase(BaseModel): parent_id: Optional[uuid.UUID] = None code: str name: str description: Optional[str] = None scope_type: DocumentScopeType = DocumentScopeType.GLOBAL required: bool = False expected_doc_type: Optional[str] = None sort_order: int = 0 is_active: bool = True class EtmfNodeCreate(EtmfNodeBase): study_id: uuid.UUID class EtmfNodeUpdate(BaseModel): parent_id: Optional[uuid.UUID] = None code: Optional[str] = None name: Optional[str] = None description: Optional[str] = None scope_type: Optional[DocumentScopeType] = None required: Optional[bool] = None expected_doc_type: Optional[str] = None sort_order: Optional[int] = None is_active: Optional[bool] = None class EtmfNodeRead(EtmfNodeBase): id: uuid.UUID study_id: uuid.UUID created_at: datetime updated_at: datetime model_config = ConfigDict(from_attributes=True) class EtmfNodeStatusSummary(BaseModel): status: EtmfNodeStatus document_count: int = 0 effective_document_count: int = 0 missing_count: int = 0 class EtmfTreeNode(EtmfNodeRead): status: EtmfNodeStatus = EtmfNodeStatus.NOT_REQUIRED document_count: int = 0 effective_document_count: int = 0 children: list["EtmfTreeNode"] = Field(default_factory=list) class EtmfNodeDocuments(BaseModel): node: EtmfNodeRead documents: list[DocumentSummary] = Field(default_factory=list)