from datetime import datetime, timezone from sqlalchemy import DateTime, ForeignKey, Integer, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base def utc_now() -> datetime: return datetime.now(timezone.utc) class Patient(Base): __tablename__ = "patients" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) first_name: Mapped[str] = mapped_column(String(120), nullable=False) last_name: Mapped[str] = mapped_column(String(120), nullable=False) birth_date: Mapped[str | None] = mapped_column(String(20), nullable=True) phone: Mapped[str | None] = mapped_column(String(60), nullable=True) email: Mapped[str | None] = mapped_column(String(180), nullable=True) procedure: Mapped[str | None] = mapped_column(String(160), nullable=True) status: Mapped[str | None] = mapped_column(String(40), default="actif") consent_signed: Mapped[str | None] = mapped_column(String(20), default="non") notes: Mapped[str | None] = mapped_column(Text, nullable=True) immich_album_id: Mapped[str | None] = mapped_column(String(80), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) photos: Mapped[list["Photo"]] = relationship(back_populates="patient", cascade="all, delete-orphan") consultations: Mapped[list["Consultation"]] = relationship(back_populates="patient", cascade="all, delete-orphan") documents: Mapped[list["Document"]] = relationship(back_populates="patient", cascade="all, delete-orphan") class Photo(Base): __tablename__ = "photos" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) patient_id: Mapped[int] = mapped_column(ForeignKey("patients.id"), nullable=False, index=True) immich_asset_id: Mapped[str] = mapped_column(String(80), nullable=False, index=True) immich_album_id: Mapped[str] = mapped_column(String(80), nullable=False) kind: Mapped[str] = mapped_column(String(40), default="original") filename: Mapped[str] = mapped_column(String(255), nullable=False) notes: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) patient: Mapped[Patient] = relationship(back_populates="photos") class Consultation(Base): __tablename__ = "consultations" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) patient_id: Mapped[int] = mapped_column(ForeignKey("patients.id"), nullable=False, index=True) consultation_date: Mapped[str | None] = mapped_column(String(40), nullable=True) procedure: Mapped[str | None] = mapped_column(String(160), nullable=True) reason: Mapped[str | None] = mapped_column(Text, nullable=True) plan: Mapped[str | None] = mapped_column(Text, nullable=True) follow_up: Mapped[str | None] = mapped_column(Text, nullable=True) status: Mapped[str | None] = mapped_column(String(40), default="prévu") notes: Mapped[str | None] = mapped_column(Text, nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) patient: Mapped[Patient] = relationship(back_populates="consultations") class Document(Base): __tablename__ = "documents" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) patient_id: Mapped[int] = mapped_column(ForeignKey("patients.id"), nullable=False, index=True) consultation_id: Mapped[int | None] = mapped_column(ForeignKey("consultations.id"), nullable=True, index=True) document_type: Mapped[str] = mapped_column(String(60), default="consentement_photo") title: Mapped[str] = mapped_column(String(220), nullable=False) status: Mapped[str] = mapped_column(String(40), default="brouillon") content: Mapped[str | None] = mapped_column(Text, nullable=True) signed_by: Mapped[str | None] = mapped_column(String(180), nullable=True) signed_at: Mapped[str | None] = mapped_column(String(40), nullable=True) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now) patient: Mapped[Patient] = relationship(back_populates="documents")