Overview
EduMate uses PostgreSQL with SQLAlchemy ORM for data persistence. The application has two primary models: User and Assessment.
All models are defined in backend/models.py and schemas in backend/schemas.py
Database Configuration
Connection Setup
Location: backend/database.py:1-24
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
SQLALCHEMY_DATABASE_URL = "postgresql://edumate_user:edumate_pass@localhost:5432/edumate"
# Create the engine that talks to Postgres
engine = create_engine(SQLALCHEMY_DATABASE_URL)
# Create a session factory
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Base class for our database models
Base = declarative_base()
Update the database credentials before deploying to production!
Models
User Model
Location: backend/models.py:5-11
Stores user authentication and profile information.
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
name = Column(String)
email = Column(String, unique=True, index=True)
password_hash = Column(String)
Table Structure
Primary key with auto-increment.Constraints:
User’s email address.Constraints:Used for authentication and password reset
Bcrypt hashed password.Never store plain text passwords! Uses bcrypt with SHA256 pre-hashing for passwords > 72 bytes.
Assessment Model
Location: backend/models.py:13-21
Stores generated MCQ assessments and their metadata.
class Assessment(Base):
__tablename__ = "assessments"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id"))
chapter_name = Column(String)
bloom_factors = Column(JSONB) # Stores {remember: 5, apply: 2, etc.}
content_json = Column(JSONB) # Stores the massive output from Gemini
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
Table Structure
Primary key with auto-increment.Constraints:
Foreign key reference to the User who created this assessment.Constraints:Relationship:
- Many-to-one with User model
Name/topic of the assessment chapter.Example:"Introduction to Data Structures"
JSON object storing Bloom’s Taxonomy distribution.Structure:{
"remember": 5,
"understand": 3,
"apply": 4,
"analyze": 3,
"evaluate": 2,
"create": 3
}
Uses PostgreSQL’s JSONB type for efficient querying and indexing
Complete MCQ assessment generated by Gemini AI.Structure:{
"mcqs": [
{
"question_no": "1",
"bloom_level": "remember",
"question": "What is...",
"answer_options": ["A", "B", "C", "D"],
"correct_answer": "A",
"explaination": "..."
}
]
}
Timestamp of assessment creation.Constraints:
- Timezone-aware
- Auto-generated (server default)
- Not nullable
Schemas (Pydantic Models)
Location: backend/schemas.py
User Schemas
class UserCreate(BaseModel):
name: str
email: str
password: str
class UserResponse(BaseModel):
id: int
name: str
email: str
class Config:
from_attributes = True
Authentication Schemas
class Token(BaseModel):
access_token: str
token_type: str
class ForgotPasswordRequest(BaseModel):
email: str
class ResetPasswordRequest(BaseModel):
token: str
new_password: str
Assessment Schemas
class AssessmentHistoryItem(BaseModel):
id: int
chapter_name: str
questions: int
created_at: datetime
status: str = "completed"
class Config:
from_attributes = True
class AssessmentDetail(BaseModel):
id: int
chapter_name: str
content: Any
class Config:
from_attributes = True
Database Initialization
Location: backend/server.py:26
Tables are automatically created on application startup:
from .database import engine
from . import models
# Create Postgres tables if they don't exist
models.Base.metadata.create_all(bind=engine)
Run this once to create all tables. SQLAlchemy will not modify existing tables.
Relationships
Database Session Management
Location: backend/database.py:19-24
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Used as a FastAPI dependency:
@app.post("/api/signup")
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
# Database operations
db.add(new_user)
db.commit()
db.refresh(new_user)
Manual Database Setup
If you need to create the database manually:
# Connect to PostgreSQL
psql -U postgres
# Create database and user
CREATE DATABASE edumate;
CREATE USER edumate_user WITH PASSWORD 'edumate_pass';
GRANT ALL PRIVILEGES ON DATABASE edumate TO edumate_user;
Change the default credentials in production!