An adaptive learning platform for Ontario high school students, powered by knowledge graphs and intelligent recommendation algorithms.
- Models Ontario curriculum (Physics SPH3U, Chemistry SCH3U, etc.) as an interconnected graph
- Tracks prerequisite relationships between concepts
- Enables intelligent pathfinding for personalized learning sequences
- Analyzes student performance history
- Recommends problems tailored to current proficiency level
- Uses Neo4j graph traversal to find optimal next concepts
- Implements Bayesian Knowledge Tracing to model student understanding
- Updates knowledge state after each answer
- Predicts mastery probability for each concept node
- Multiple Choice: Instant feedback with explanation
- Fill-in-Blank: Case-insensitive with whitespace normalization
- Calculation: Tolerance-based numeric comparison
- Async processing via Redis task queue
| Component | Technology |
|---|---|
| API | FastAPI + Python 3.12 |
| Relational DB | PostgreSQL (users, courses, submissions) |
| Graph DB | Neo4j (knowledge graph, mastery tracking) |
| Task Queue | Redis (background grading) |
| Frontend | iOS (SwiftUI) |
| Package Manager | uv |
iOS App
↓ REST API
FastAPI Server
├─→ PostgreSQL (user data, quizzes)
├─→ Neo4j (knowledge graph, relationships)
└─→ Redis Queue → Worker (async grading)
Design principle: Keep it simple. Redis for queuing, no heavy message brokers.
# 1. Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Start databases
docker-compose up -d
# 3. Install dependencies
uv sync
# 4. Run API server
uv run uvicorn app.main:app --reload
# 5. Run worker (separate terminal)
uv run python -m app.worker.workerAPI docs: http://localhost:8000/docs
POST /users/register # Sign up
POST /users/login # Get JWT token
GET /questions/random # Get adaptive question
POST /submissions # Submit answer (async graded)
GET /courses/{id} # Course with knowledge graph
POST /courses/{id}/enroll # Enroll and initialize mastery
- Student enrolls in a course → Creates mastery relationships in Neo4j
- Requests question → Algorithm finds best concept based on:
- Current mastery level (BKT probability)
- Prerequisite satisfaction
- Difficulty progression
- Submits answer → Worker grades asynchronously and updates:
- Mastery probability in Neo4j
- Historical performance in PostgreSQL
- Next question → Repeats with updated knowledge state
Import curriculum via CSV:
# Knowledge nodes
curl -X POST http://localhost:8000/knowledge-nodes/bulk-import \
-F "file=@nodes.csv" -F "course_code=SPH3U"
# Questions
curl -X POST http://localhost:8000/questions/bulk-import \
-F "file=@questions.csv"
# Concept relationships
curl -X POST http://localhost:8000/relations/bulk-import \
-F "file=@relations.csv"See example_data/ for CSV formats.
uv run pytest # Run all tests
uv run pytest -v # Verbose mode
uv run pytest -x # Stop on first failure138 tests, 97% pass rate
app/
├── core/ # Config, database, security
├── models/ # SQLAlchemy + Neo4j models
├── routes/ # API endpoints
├── worker/ # Async task handlers
│ ├── worker.py # Main worker loop
│ ├── handlers.py # Grading logic
│ └── bulk_import_handlers.py
└── main.py # FastAPI app
- Neo4j: Perfect for modeling curriculum graphs and traversing concept relationships
- PostgreSQL: Battle-tested for transactional data (users, submissions)
- Redis: Lightweight queue, no need for RabbitMQ complexity
- uv: 460x faster than conda (0.13s vs 60s for dependencies)
- FastAPI: Modern async Python, auto-generated docs
MIT
Built for Ontario high school students