Root cause of lost PREP 2016 quiz: deleting a section (e.g. to recreate
with different page ranges) cascade-deleted ALL quizzes attached to it,
destroying the quiz AND all its questions permanently.
Fixes:
- Section.quizzes relationship: removed cascade="all, delete-orphan"
Deleting a section no longer touches quizzes at all
- Quiz.section_id FK: changed to ON DELETE SET NULL, nullable=True
If a section is deleted, quizzes keep working (section_id becomes null)
- DB migration: drops old FK constraint and recreates with SET NULL
Also answers the question about deleting a bank question in a quiz:
- quiz_question_links FK has ON DELETE CASCADE — deleting a question
silently removes it from all quizzes
- This needs a warning UI (not yet implemented — no delete button in bank)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- FastAPI backend with JWT auth, roles (admin/moderator/user)
- PDF upload (up to 500MB) with streaming, PyMuPDF text extraction
- ChromaDB vectorization per page with metadata
- LiteLLM AI question extraction from PDF (not generation)
- Image extraction from PDF pages, graceful fallback
- Quiz modes: timed (countdown timer) + learning (answers shown inline)
- Page-by-page question navigation with dot navigator
- TTS endpoint using LiteLLM (Google Vertex / OpenAI voices)
- Admin dashboard: AI model management per task, user role management
- Moderator role: upload PDFs, create sections, generate quizzes
- Spaced repetition reminders via SMTP email (SM-2 intervals)
- APScheduler daily reminder jobs
- Celery + Redis for background PDF processing
- React frontend with all pages
- Docker Compose deployment (nginx + backend + celery + redis)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>