
- Set up project structure with FastAPI and SQLite - Implement user authentication with JWT - Create models for learning content (subjects, lessons, quizzes) - Add progress tracking and gamification features - Implement comprehensive API documentation - Add error handling and validation - Set up proper logging and health check endpoint
121 lines
4.6 KiB
Python
121 lines
4.6 KiB
Python
from __future__ import annotations
|
|
|
|
import enum
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import Boolean, Column, DateTime, Enum, ForeignKey, Integer, String, Text
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from app.db.base_class import Base
|
|
|
|
|
|
class DifficultyLevel(enum.Enum):
|
|
EASY = "easy"
|
|
MEDIUM = "medium"
|
|
HARD = "hard"
|
|
|
|
|
|
class Subject(Base):
|
|
"""
|
|
Subject model representing a learning area (e.g., Math, Science, Language).
|
|
"""
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
name = Column(String, index=True, nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
image_url = Column(String, nullable=True)
|
|
order = Column(Integer, default=0)
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
lessons = relationship("Lesson", back_populates="subject", cascade="all, delete-orphan")
|
|
|
|
|
|
class Lesson(Base):
|
|
"""
|
|
Lesson model representing a specific learning unit within a subject.
|
|
"""
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
subject_id = Column(Integer, ForeignKey("subject.id"), nullable=False)
|
|
title = Column(String, index=True, nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
content = Column(Text, nullable=False)
|
|
image_url = Column(String, nullable=True)
|
|
order = Column(Integer, default=0)
|
|
difficulty = Column(Enum(DifficultyLevel), default=DifficultyLevel.EASY)
|
|
points = Column(Integer, default=10) # Points awarded for completing the lesson
|
|
duration_minutes = Column(Integer, default=15) # Estimated time to complete the lesson
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
subject = relationship("Subject", back_populates="lessons")
|
|
quizzes = relationship("Quiz", back_populates="lesson", cascade="all, delete-orphan")
|
|
progress = relationship("UserProgress", back_populates="lesson")
|
|
|
|
|
|
class Quiz(Base):
|
|
"""
|
|
Quiz model representing a set of questions related to a lesson.
|
|
"""
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
lesson_id = Column(Integer, ForeignKey("lesson.id"), nullable=False)
|
|
title = Column(String, index=True, nullable=False)
|
|
description = Column(Text, nullable=True)
|
|
time_limit_minutes = Column(Integer, default=10) # Time limit to complete the quiz
|
|
pass_percentage = Column(Integer, default=70) # Percentage required to pass
|
|
points = Column(Integer, default=20) # Points awarded for passing the quiz
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
lesson = relationship("Lesson", back_populates="quizzes")
|
|
questions = relationship("Question", back_populates="quiz", cascade="all, delete-orphan")
|
|
|
|
|
|
class Question(Base):
|
|
"""
|
|
Question model representing a single quiz question.
|
|
"""
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
quiz_id = Column(Integer, ForeignKey("quiz.id"), nullable=False)
|
|
text = Column(Text, nullable=False)
|
|
image_url = Column(String, nullable=True)
|
|
explanation = Column(Text, nullable=True) # Explanation of the correct answer
|
|
points = Column(Integer, default=5) # Points for this question
|
|
order = Column(Integer, default=0)
|
|
is_active = Column(Boolean, default=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
quiz = relationship("Quiz", back_populates="questions")
|
|
answers = relationship("Answer", back_populates="question", cascade="all, delete-orphan")
|
|
user_answers = relationship("UserAnswer", back_populates="question")
|
|
|
|
|
|
class Answer(Base):
|
|
"""
|
|
Answer model representing a possible answer to a question.
|
|
"""
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
question_id = Column(Integer, ForeignKey("question.id"), nullable=False)
|
|
text = Column(Text, nullable=False)
|
|
is_correct = Column(Boolean, default=False)
|
|
explanation = Column(Text, nullable=True)
|
|
order = Column(Integer, default=0)
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
question = relationship("Question", back_populates="answers")
|
|
user_answers = relationship("UserAnswer", back_populates="answer")
|