新增电子试验主文件目录与文件归档

This commit is contained in:
Cheng Zhou
2026-05-28 10:54:13 +08:00
parent 31fcb7e6f2
commit fa961f1391
20 changed files with 2226 additions and 10 deletions
+1
View File
@@ -31,6 +31,7 @@ class Document(Base):
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
trial_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), nullable=False)
site_id: Mapped[Optional[uuid.UUID]] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), nullable=True)
etmf_node_id: Mapped[Optional[uuid.UUID]] = mapped_column(UUID(as_uuid=True), ForeignKey("etmf_nodes.id"), nullable=True)
doc_no: Mapped[str] = mapped_column(String(50), nullable=False)
doc_type: Mapped[str] = mapped_column(String(50), nullable=False)
title: Mapped[str] = mapped_column(String(200), nullable=False)
+44
View File
@@ -0,0 +1,44 @@
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])