from __future__ import annotations from datetime import datetime from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy import String, ForeignKey, BigInteger from sqlalchemy.dialects.postgresql import UUID, ARRAY import uuid from typing import List, Optional class Base(DeclarativeBase): pass class Sessions(Base): __tablename__ = "sessions" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) code: Mapped[str] = mapped_column(String(8), unique=True, nullable=False) patient_id: Mapped[int] = mapped_column( ForeignKey("patients.id", ondelete="CASCADE"), nullable=False) patient: Mapped["Patients"] = relationship(back_populates="sessions") sent_at: Mapped[datetime] = mapped_column(nullable=False) consulted_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) doctor_id: Mapped[int] = mapped_column(ForeignKey("doctors.id")) session_status_history: Mapped[List["SessionStatusHistory"]] = relationship( back_populates="sessions", cascade="all, delete-orphan") session_date_time_history: Mapped[List["SessionDateTimeHistory"]] = relationship( back_populates="sessions", cascade="all, delete-orphan") paid_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) class SessionDateTimeHistory(Base): __tablename__ = "session_date_time_history" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) sessions_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("sessions.id", ondelete="CASCADE"), nullable=False) sessions: Mapped["Sessions"] = relationship(back_populates="session_date_time_history") updated_at: Mapped[datetime] = mapped_column(nullable=False, default=datetime.utcnow) consultation_date_time: Mapped[Optional[datetime]] = mapped_column(nullable=True) who_updated: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) class SessionStatusHistory(Base): __tablename__ = "session_status_history" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) sessions_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("sessions.id", ondelete="CASCADE"), nullable=False) sessions: Mapped["Sessions"] = relationship(back_populates="session_status_history") updated_at: Mapped[datetime] = mapped_column(nullable=False, default=datetime.utcnow) status: Mapped[str] = mapped_column(String(50), nullable=False, default="pending") who_updated: Mapped[Optional[str]] = mapped_column(String(50), nullable=True) class Admins(Base): __tablename__ = "admins" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True, nullable=False) created_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) available_payment_methods: Mapped[Optional[List[str]]] = mapped_column( ARRAY(String), nullable=True) class Patients(Base): __tablename__ = "patients" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True, nullable=False) phone: Mapped[Optional[str]] = mapped_column(nullable=True) created_at: Mapped[datetime] = mapped_column(nullable=False) updated_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) accepted_terms: Mapped[bool] = mapped_column(default=False, nullable=True) sessions: Mapped[List["Sessions"]] = relationship( back_populates="patient", cascade="all, delete-orphan") class Doctors(Base): __tablename__ = "doctors" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) code: Mapped[str] = mapped_column(unique=True, nullable=True) time_zone: Mapped[Optional[str]] = mapped_column(nullable=True) telegram_id: Mapped[int] = mapped_column(BigInteger, unique=True, nullable=False) name: Mapped[str] = mapped_column(nullable=False) available_formats: Mapped[Optional[List[str]] ] = mapped_column(ARRAY(String), nullable=True) is_active: Mapped[bool] = mapped_column(default=False, nullable=False) is_verified: Mapped[bool] = mapped_column(default=False, nullable=False) created_at: Mapped[datetime] = mapped_column(nullable=False) referral_code_id: Mapped[int] = mapped_column( ForeignKey("referral_codes.id"), nullable=False) specialties: Mapped[List[str]] = mapped_column( ARRAY(String), nullable=False, default=list) referral: Mapped["ReferralCode"] = relationship( back_populates="doctor", uselist=False) sessions: Mapped[List["Sessions"]] = relationship() form_links: Mapped[List["FormLink"]] = relationship( back_populates="doctor", cascade="all, delete-orphan") payment_methods: Mapped[List["PaymentMethod"]] = relationship( back_populates="doctor", cascade="all, delete-orphan") verification_requests: Mapped[List["VerificationRequests"]] = relationship( back_populates="doctor", cascade="all, delete-orphan") def __repr__(self) -> str: return f"" class ReferralCode(Base): __tablename__ = "referral_codes" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) code: Mapped[str] = mapped_column(unique=True, nullable=False) is_used: Mapped[bool] = mapped_column(default=False, nullable=False) created_at: Mapped[datetime] = mapped_column(nullable=False) used_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) doctor: Mapped[Optional["Doctors"]] = relationship( back_populates="referral", uselist=False) def __repr__(self) -> str: return f"" class VerificationRequests(Base): __tablename__ = "verification_requests" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) doctor_id: Mapped[int] = mapped_column( ForeignKey("doctors.id", ondelete="CASCADE"), unique=True, nullable=False) code: Mapped[str] = mapped_column(unique=True, nullable=False) sent_at: Mapped[datetime] = mapped_column(nullable=False) reviewed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True) status: Mapped[str] = mapped_column(default=False, nullable=False) # Связь поправлена — связь с doctor через doctor_id doctor: Mapped["Doctors"] = relationship( back_populates="verification_requests") def __repr__(self) -> str: return f"" class FormLink(Base): __tablename__ = "form_links" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) doctor_id: Mapped[int] = mapped_column( ForeignKey("doctors.id", ondelete="CASCADE"), unique=True, nullable=False) url: Mapped[str] = mapped_column(nullable=False) label: Mapped[Optional[str]] = mapped_column(nullable=True) is_active: Mapped[bool] = mapped_column(default=True, nullable=False) created_at: Mapped[datetime] = mapped_column(nullable=False) doctor: Mapped["Doctors"] = relationship(back_populates="form_links") class PaymentMethod(Base): __tablename__ = "payment_methods" id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) doctor_id: Mapped[int] = mapped_column( ForeignKey("doctors.id", ondelete="CASCADE"), unique=True, nullable=False) method: Mapped[str] = mapped_column(nullable=False) details: Mapped[Optional[str]] = mapped_column(nullable=True) payment_api_key: Mapped[str] = mapped_column(nullable=False) is_active: Mapped[bool] = mapped_column(default=True, nullable=False) is_primary: Mapped[bool] = mapped_column(default=True, nullable=False) created_at: Mapped[datetime] = mapped_column(nullable=False) doctor: Mapped["Doctors"] = relationship(back_populates="payment_methods")