| from sqlalchemy import ( |
| create_engine, Column, Integer, String, Text, TIMESTAMP, ForeignKey, |
| Boolean, UniqueConstraint |
| ) |
| from sqlalchemy.ext.declarative import declarative_base |
| from sqlalchemy.orm import sessionmaker, relationship |
| from datetime import datetime |
| import os |
| from dotenv import load_dotenv |
|
|
| load_dotenv() |
|
|
| |
| |
| Database_URL = os.getenv( |
| "DATABASE_URL", |
| "postgresql://postgres:12345678@localhost:5432/medicine_assistant", |
| ) |
|
|
| |
| _connect_args = {"check_same_thread": False} if Database_URL.startswith("sqlite") else {} |
| engine = create_engine(Database_URL, connect_args=_connect_args) |
| SessionLocal = sessionmaker(bind=engine) |
|
|
| Base = declarative_base() |
|
|
|
|
| class Conversation(Base): |
| __tablename__ = "conversations" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, nullable=True) |
| title = Column(String(100), nullable=True) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| class Message(Base): |
| __tablename__ = "messages" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| conversation_id = Column(Integer, ForeignKey("conversations.id", ondelete="CASCADE")) |
| role = Column(String(10), nullable=False) |
| text = Column(Text, nullable=True) |
| image_path = Column(String(255), nullable=True) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| |
| |
| |
|
|
|
|
| class User(Base): |
| __tablename__ = "users" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| email = Column(String(255), unique=True, index=True, nullable=False) |
| password_hash = Column(String(255), nullable=False) |
| name = Column(String(120), nullable=True) |
| language = Column(String(5), default="en") |
| points = Column(Integer, default=0) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
| medications = relationship( |
| "UserMedication", back_populates="user", |
| cascade="all, delete-orphan" |
| ) |
| schedule_entries = relationship( |
| "ScheduleEntry", cascade="all, delete-orphan" |
| ) |
| dose_events = relationship( |
| "DoseEvent", cascade="all, delete-orphan" |
| ) |
| push_subscriptions = relationship( |
| "PushSubscription", cascade="all, delete-orphan" |
| ) |
| badges = relationship( |
| "Badge", cascade="all, delete-orphan" |
| ) |
|
|
|
|
| class UserMedication(Base): |
| __tablename__ = "user_medications" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), index=True) |
| drug_name = Column(String(120), nullable=False) |
| doses_per_day = Column(Integer, nullable=True) |
| meal_relation_cached = Column(String(255), nullable=True) |
| pack_quantity = Column(Integer, nullable=True) |
| refill_at = Column(TIMESTAMP, nullable=True) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
| user = relationship("User", back_populates="medications") |
|
|
|
|
| class ScheduleEntry(Base): |
| __tablename__ = "schedule_entries" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), index=True) |
| user_medication_id = Column( |
| Integer, ForeignKey("user_medications.id", ondelete="CASCADE") |
| ) |
| drug_name = Column(String(120), nullable=False) |
| dose_time = Column(String(5), nullable=False) |
| meal_note = Column(String(120), nullable=True) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| class DoseEvent(Base): |
| __tablename__ = "dose_events" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), index=True) |
| schedule_entry_id = Column( |
| Integer, ForeignKey("schedule_entries.id", ondelete="CASCADE"), nullable=True |
| ) |
| drug_name = Column(String(120), nullable=False) |
| scheduled_for = Column(TIMESTAMP, nullable=False, index=True) |
| |
| status = Column(String(12), default="pending", index=True) |
| responded_at = Column(TIMESTAMP, nullable=True) |
| pushed = Column(Boolean, default=False) |
| caregiver_notified = Column(Boolean, default=False) |
| points_awarded = Column(Integer, default=0) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| class PushSubscription(Base): |
| __tablename__ = "push_subscriptions" |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), index=True) |
| endpoint = Column(Text, unique=True, nullable=False) |
| p256dh = Column(Text, nullable=False) |
| auth = Column(Text, nullable=False) |
| created_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| class Badge(Base): |
| __tablename__ = "badges" |
| __table_args__ = (UniqueConstraint("user_id", "code", name="uq_user_badge"),) |
|
|
| id = Column(Integer, primary_key=True, index=True) |
| user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), index=True) |
| code = Column(String(40), nullable=False) |
| awarded_at = Column(TIMESTAMP, default=datetime.utcnow) |
|
|
|
|
| def get_db(): |
| db = SessionLocal() |
| try: |
| yield db |
| finally: |
| db.close() |