| """ |
| Database models (tables) for the application. |
| Uses SQLAlchemy ORM to define table structure. |
| """ |
|
|
| from sqlalchemy import Column, String, DateTime, ForeignKey, Text, Float, Integer |
| from sqlalchemy.dialects.postgresql import UUID |
| from sqlalchemy.sql import func |
| from sqlalchemy.orm import relationship |
| import uuid |
| from app.database.database import Base |
|
|
|
|
| class User(Base): |
| """ |
| User table stores user authentication information. |
| |
| Columns: |
| id: Unique user identifier (UUID) |
| full_name: User's full name |
| email: User's email (unique, used for login) |
| password_hash: Hashed password (never store plain passwords!) |
| created_at: When user account was created |
| last_login: Last successful login timestamp |
| """ |
| __tablename__ = "users" |
| |
| id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
| full_name = Column(String(255), nullable=False) |
| email = Column(String(255), unique=True, nullable=False, index=True) |
| password_hash = Column(String(255), nullable=False) |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) |
| last_login = Column(DateTime(timezone=True), nullable=True) |
| |
| |
| diagnoses = relationship("Diagnosis", back_populates="user", cascade="all, delete-orphan") |
| segmentations = relationship("Segmentation", back_populates="user", cascade="all, delete-orphan") |
|
|
|
|
| class Diagnosis(Base): |
| """ |
| Diagnosis table stores disease diagnosis results. |
| |
| Columns: |
| id: Unique diagnosis identifier |
| user_id: Foreign key to users table |
| disease_name: Predicted disease (e.g., "Breast Cancer") |
| severity: Normal or Abnormal |
| stage: Disease stage (e.g., "Ductal Carcinoma") |
| confidence_*: Model confidence scores (0-1) |
| *_image_url: S3 URLs for images (NOT actual image data) |
| explainability_text: AI-generated explanation |
| created_at: When diagnosis was performed |
| """ |
| __tablename__ = "diagnoses" |
| |
| id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
| user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False) |
| |
| |
| disease_name = Column(String(100), nullable=False) |
| severity = Column(String(50), nullable=False) |
| stage = Column(String(100), nullable=True) |
| |
| |
| confidence_disease = Column(Float, nullable=True) |
| confidence_severity = Column(Float, nullable=True) |
| confidence_stage = Column(Float, nullable=True) |
| |
| |
| original_image_url = Column(Text, nullable=False) |
| heatmap_url = Column(Text, nullable=True) |
| |
| |
| explainability_text = Column(Text, nullable=True) |
| |
| |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) |
| |
| |
| user = relationship("User", back_populates="diagnoses") |
|
|
|
|
| class Segmentation(Base): |
| """ |
| Segmentation table stores cell segmentation results. |
| |
| Columns: |
| id: Unique segmentation identifier |
| user_id: Foreign key to users table |
| original_image_url: S3 URL for original image |
| segmented_mask_url: S3 URL for segmentation mask |
| cell_count: Number of cells detected |
| created_at: When segmentation was performed |
| """ |
| __tablename__ = "segmentations" |
| |
| id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) |
| user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False) |
| |
| |
| original_image_url = Column(Text, nullable=False) |
| segmented_mask_url = Column(Text, nullable=False) |
| |
| |
| cell_count = Column(Integer, nullable=True) |
| |
| |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) |
| |
| |
| user = relationship("User", back_populates="segmentations") |