healthtech-api / app /models /course.py
Hamza4100's picture
Upload 40 files
2732fa3 verified
"""Course and Module models for content organization."""
from datetime import datetime
from enum import Enum as PyEnum
from sqlalchemy import Column, String, Boolean, DateTime, Enum, Text, Integer, ForeignKey
from sqlalchemy.orm import relationship
from uuid import uuid4
from app.database import Base
class ContentType(str, PyEnum):
PDF = "pdf"
VIDEO = "video"
MARKDOWN = "markdown"
QUIZ = "quiz"
EXTERNAL_LINK = "external_link"
class DifficultyLevel(str, PyEnum):
BEGINNER = "beginner"
INTERMEDIATE = "intermediate"
ADVANCED = "advanced"
class Course(Base):
__tablename__ = "courses"
id = Column(String(36), primary_key=True, default=lambda: str(uuid4()))
title = Column(String(255), nullable=False)
slug = Column(String(255), unique=True, nullable=False, index=True)
description = Column(Text, nullable=True)
thumbnail_url = Column(String(500), nullable=True)
difficulty = Column(Enum(DifficultyLevel), default=DifficultyLevel.BEGINNER)
is_published = Column(Boolean, default=False)
is_featured = Column(Boolean, default=False)
estimated_hours = Column(Integer, default=0)
order_index = Column(Integer, default=0)
# Creator
created_by = Column(String(36), ForeignKey("users.id"), nullable=True)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
modules = relationship("Module", back_populates="course", cascade="all, delete-orphan", order_by="Module.order_index")
enrollments = relationship("Enrollment", back_populates="course", cascade="all, delete-orphan")
def __repr__(self):
return f"<Course {self.title}>"
class Module(Base):
__tablename__ = "modules"
id = Column(String(36), primary_key=True, default=lambda: str(uuid4()))
course_id = Column(String(36), ForeignKey("courses.id"), nullable=False)
title = Column(String(255), nullable=False)
description = Column(Text, nullable=True)
order_index = Column(Integer, default=0)
is_published = Column(Boolean, default=False)
# Unlock requirements
prerequisite_module_id = Column(String(36), ForeignKey("modules.id"), nullable=True)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
course = relationship("Course", back_populates="modules")
lessons = relationship("Lesson", back_populates="module", cascade="all, delete-orphan", order_by="Lesson.order_index")
prerequisite = relationship("Module", remote_side="Module.id")
def __repr__(self):
return f"<Module {self.title}>"
class Lesson(Base):
__tablename__ = "lessons"
id = Column(String(36), primary_key=True, default=lambda: str(uuid4()))
module_id = Column(String(36), ForeignKey("modules.id"), nullable=False)
title = Column(String(255), nullable=False)
description = Column(Text, nullable=True)
content_type = Column(Enum(ContentType), nullable=False)
content_url = Column(String(500), nullable=True) # File URL or external link
content_text = Column(Text, nullable=True) # For markdown content
duration_minutes = Column(Integer, default=0)
order_index = Column(Integer, default=0)
is_published = Column(Boolean, default=False)
# Vector store reference
vector_namespace = Column(String(255), nullable=True)
# Timestamps
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
module = relationship("Module", back_populates="lessons")
progress_records = relationship("Progress", back_populates="lesson", cascade="all, delete-orphan")
quizzes = relationship("Quiz", back_populates="lesson", cascade="all, delete-orphan")
def __repr__(self):
return f"<Lesson {self.title}>"