BytecodeApps/docverse-api
0
1from sqlalchemy import Column, String, Boolean, DateTime, Numeric, ForeignKey, LargeBinary2from sqlalchemy.dialects.postgresql import UUID3from sqlalchemy.orm import declarative_base, relationship4from sqlalchemy.sql import func5import uuid6 7Base = declarative_base()8 9class User(Base):10 __tablename__ = 'users'11 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)12 email = Column(String(255), unique=True, nullable=False, index=True)13 password_hash = Column(String(255), nullable=False)14 first_name = Column(String(100))15 last_name = Column(String(100))16 role = Column(String(50), default='user')17 created_at = Column(DateTime(timezone=True), server_default=func.now())18 updated_at = Column(DateTime(timezone=True), onupdate=func.now())19 20 reports = relationship("Report", back_populates="user", cascade="all, delete")21 22class Report(Base):23 __tablename__ = 'reports'24 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)25 user_id = Column(UUID(as_uuid=True), ForeignKey('users.id', ondelete='CASCADE'), nullable=False, index=True)26 file_name = Column(String(255), nullable=False)27 file_path = Column(String, nullable=False)28 report_type = Column(String(50))29 status = Column(String(50), default='processing')30 extracted_text_encrypted = Column(LargeBinary) # BYTEA for AES31 summary_encrypted = Column(LargeBinary)32 created_at = Column(DateTime(timezone=True), server_default=func.now())33 updated_at = Column(DateTime(timezone=True), onupdate=func.now())34 35 user = relationship("User", back_populates="reports")36 lab_results = relationship("LabResult", back_populates="report", cascade="all, delete")37 medications = relationship("Medication", back_populates="report", cascade="all, delete")38 risk_flags = relationship("RiskFlag", back_populates="report", cascade="all, delete")39 40class LabResult(Base):41 __tablename__ = 'lab_results'42 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)43 report_id = Column(UUID(as_uuid=True), ForeignKey('reports.id', ondelete='CASCADE'), nullable=False, index=True)44 test_name = Column(String(100), nullable=False)45 test_value = Column(Numeric(10, 2))46 unit = Column(String(50))47 reference_range = Column(String(100))48 flag = Column(String(50))49 created_at = Column(DateTime(timezone=True), server_default=func.now())50 51 report = relationship("Report", back_populates="lab_results")52 53class Medication(Base):54 __tablename__ = 'medications'55 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)56 report_id = Column(UUID(as_uuid=True), ForeignKey('reports.id', ondelete='CASCADE'), nullable=False, index=True)57 drug_name = Column(String(200), nullable=False)58 dosage = Column(String(100))59 frequency = Column(String(100))60 instructions = Column(String)61 created_at = Column(DateTime(timezone=True), server_default=func.now())62 63 report = relationship("Report", back_populates="medications")64 65class RiskFlag(Base):66 __tablename__ = 'risk_flags'67 id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)68 report_id = Column(UUID(as_uuid=True), ForeignKey('reports.id', ondelete='CASCADE'), nullable=False, index=True)69 flag_type = Column(String(100))70 severity = Column(String(50))71 description = Column(String, nullable=False)72 resolved = Column(Boolean, default=False)73 created_at = Column(DateTime(timezone=True), server_default=func.now())74 75 report = relationship("Report", back_populates="risk_flags")76 