立项配置页初步优化

This commit is contained in:
Cheng Zhou
2026-02-24 16:53:22 +08:00
parent 0693f09b1d
commit 8f3f717e48
124 changed files with 12519 additions and 2954 deletions
+2
View File
@@ -25,6 +25,8 @@ class AdverseEvent(Base):
action_taken: Mapped[str | None] = mapped_column(Text, nullable=True)
outcome: Mapped[str | None] = mapped_column(String(50), nullable=True)
reported_to_sponsor: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
is_sae: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
is_susar: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
report_due_date: Mapped[date | None] = mapped_column(Date, nullable=True)
status: Mapped[str] = mapped_column(String(20), nullable=False, default="NEW")
description: Mapped[str | None] = mapped_column(Text, nullable=True)
+1
View File
@@ -20,6 +20,7 @@ class Milestone(Base):
status: Mapped[str] = mapped_column(String(20), nullable=False, default="NOT_STARTED")
site_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), nullable=True)
owner_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
owner_name: Mapped[str | None] = mapped_column(String(255), nullable=True)
notes: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
updated_at: Mapped[datetime] = mapped_column(
+5 -3
View File
@@ -1,7 +1,7 @@
import uuid
from datetime import datetime
from datetime import date, datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, func
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
@@ -19,5 +19,7 @@ class Site(Base):
contact: Mapped[str | None] = mapped_column(String(100), nullable=True)
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default="true")
enrollment_target: Mapped[int | None] = mapped_column(Integer, nullable=True)
enrollment_plan_start_date: Mapped[date | None] = mapped_column(Date, nullable=True)
enrollment_plan_end_date: Mapped[date | None] = mapped_column(Date, nullable=True)
enrollment_plan_note: Mapped[str | None] = mapped_column(Text, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
+20 -2
View File
@@ -1,7 +1,7 @@
import uuid
from datetime import datetime
from datetime import date, datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String, func
from sqlalchemy import Boolean, Date, DateTime, ForeignKey, Integer, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
@@ -14,8 +14,26 @@ class Study(Base):
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
code: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True)
name: Mapped[str] = mapped_column(String(200), nullable=False)
project_full_name: Mapped[str | None] = mapped_column(String(500), nullable=True)
sponsor: Mapped[str | None] = mapped_column(String(200), nullable=True)
protocol_no: Mapped[str | None] = mapped_column(String(100), nullable=True)
lead_unit: Mapped[str | None] = mapped_column(String(255), nullable=True)
principal_investigator: Mapped[str | None] = mapped_column(String(255), nullable=True)
main_pm: Mapped[str | None] = mapped_column(String(255), nullable=True)
research_analysis: Mapped[str | None] = mapped_column(Text, nullable=True)
research_product: Mapped[str | None] = mapped_column(String(255), nullable=True)
control_product: Mapped[str | None] = mapped_column(String(255), nullable=True)
indication: Mapped[str | None] = mapped_column(String(255), nullable=True)
research_population: Mapped[str | None] = mapped_column(String(255), nullable=True)
research_design: Mapped[str | None] = mapped_column(Text, nullable=True)
plan_start_date: Mapped[date | None] = mapped_column(Date, nullable=True)
plan_end_date: Mapped[date | None] = mapped_column(Date, nullable=True)
planned_site_count: Mapped[int | None] = mapped_column(Integer, nullable=True)
planned_enrollment_count: Mapped[int | None] = mapped_column(Integer, nullable=True)
enrollment_monthly_goal_note: Mapped[str | None] = mapped_column(Text, nullable=True)
enrollment_stage_breakdown: Mapped[str | None] = mapped_column(Text, nullable=True)
summary_note: Mapped[str | None] = mapped_column(Text, nullable=True)
objective_note: Mapped[str | None] = mapped_column(Text, nullable=True)
phase: Mapped[str | None] = mapped_column(String(50), nullable=True)
status: Mapped[str] = mapped_column(String(20), nullable=False, default="DRAFT")
is_locked: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
@@ -0,0 +1,25 @@
import uuid
from datetime import date, datetime
from sqlalchemy import Date, DateTime, ForeignKey, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class StudyCenterConfirm(Base):
__tablename__ = "study_center_confirms"
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"), index=True, nullable=False)
site_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("sites.id"), index=True, nullable=False)
source_setup_item_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
confirmer: Mapped[str | None] = mapped_column(String(255), nullable=True)
confirm_status: Mapped[str] = mapped_column(String(20), nullable=False)
confirm_date: Mapped[date | None] = mapped_column(Date, nullable=True)
note: Mapped[str | None] = mapped_column(Text, nullable=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()
)
@@ -0,0 +1,24 @@
import uuid
from datetime import datetime
from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class StudyMonitoringStrategy(Base):
__tablename__ = "study_monitoring_strategies"
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"), index=True, nullable=False)
source_setup_item_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
strategy_type: Mapped[str] = mapped_column(String(50), nullable=False)
detail: Mapped[str] = mapped_column(Text, nullable=False)
frequency: Mapped[str] = mapped_column(String(50), nullable=False)
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, 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()
)
+27
View File
@@ -0,0 +1,27 @@
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Integer, UniqueConstraint, func
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class StudySetupConfig(Base):
__tablename__ = "study_setup_configs"
__table_args__ = (UniqueConstraint("study_id", name="uq_study_setup_config_study"),)
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, index=True)
version: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
config: Mapped[dict] = mapped_column(JSONB, nullable=False)
publish_status: Mapped[str] = mapped_column(default="DRAFT", nullable=False)
published_config: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
published_by: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
published_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
saved_by: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=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()
)
@@ -0,0 +1,29 @@
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Integer, UniqueConstraint, func
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.db.base_class import Base
class StudySetupConfigVersion(Base):
__tablename__ = "study_setup_config_versions"
__table_args__ = (
UniqueConstraint("study_id", "version", name="uq_setup_config_versions_study_version"),
UniqueConstraint("study_id", "display_version", name="uq_setup_config_versions_study_display_version"),
)
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
study_setup_config_id: Mapped[uuid.UUID] = mapped_column(
UUID(as_uuid=True), ForeignKey("study_setup_configs.id"), nullable=False, index=True
)
study_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("studies.id"), nullable=False, index=True)
version: Mapped[int] = mapped_column(Integer, nullable=False)
display_version: Mapped[int] = mapped_column(Integer, nullable=False)
source_version: Mapped[int | None] = mapped_column(Integer, nullable=True)
config: Mapped[dict] = mapped_column(JSONB, nullable=False)
published_by: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
published_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())