An AI-powered study platform for university students. Turns lecture notes and past papers into a personalised, adaptive study experience — planning, practice, and games in one place.
Built by Siddhi and Heza.
| Layer | Technology |
|---|---|
| Frontend | Next.js 14 (App Router), React, TypeScript, Tailwind CSS |
| Backend | FastAPI (Python), deployed on Vercel |
| Database / Auth / Storage | Supabase (PostgreSQL + Auth + Storage) |
| AI | Anthropic Claude (claude-sonnet-4-6) |
- Daily task list pulled from the study plan
- Streak tracking and weekly activity graph (counts focus sessions, Gauntlet plays, and question answering)
- Stats: total focus minutes, tasks completed, day streak
- AI generates a full task breakdown from a syllabus or course description
- Tasks scheduled across available days respecting exam dates and disruptions (blocked periods)
- Adaptive rescheduling: tell the agent what changed and it rebalances the remaining plan
- Customisable Pomodoro timer (25/5, 50/10, or custom)
- Animated focus scenes: coffee pour, growing plant, candle — progress through stages as the session advances
- Space bar to start/pause; done screen with confetti
- Upload PDFs per module; multi-page note workspace
- AI chat grounded on the uploaded PDF
- Fork any note into a new page
- Create and manage flashcard sets per module
- Flip cards, track progress through a set
- Past paper extraction — upload a PDF exam paper; Claude extracts every question with model answers and topic labels
- AI generation — generate MCQ, short answer, essay, or mixed question sets from any uploaded lecture PDF; optionally specify count and custom instructions
- Adaptive regeneration — when regenerating, the prompt is automatically enriched with which topics the user got wrong or hasn't attempted yet
- MCQ UI — A/B/C/D option buttons, two-step select → Check flow, green/red reveal with explanation
- Written answer grading — Claude grades responses as Excellent / Good / Developing / Insufficient with constructive, second-person feedback
- Session score tracking — live score bar showing MCQ correct/total and average written grade across the session
- Bank management — view all banks per module, drill into a specific bank, delete banks
- Goblet of Fire — Socratic Q&A tutor powered by Claude. Upload a PDF, get broken into topics, earn stars per topic through back-and-forth discussion
- Module exam setup — In Games → Goblet of Fire, select a module and save its question types (MCQ, short answer, essay, problem solving, oral), exam duration, reference-material rules, and marking guidance. Gauntlet uses these for questions and feedback across that module’s PDFs; reset to defaults for Socratic discussion. Duration guides pacing, not a countdown.
- Jeopardy — Flashcard game-show mode; pick a set and race through questions
- Profile management (name, degree, year)
- Manage courses and exam dates
- Add disruptions (blocked study periods)
study-planner-agent/
├── backend/
│ ├── app/
│ │ ├── api/
│ │ │ ├── agent.py # Study plan generation
│ │ │ ├── flashcards.py # Flashcard CRUD
│ │ │ ├── onboarding.py # Profile, courses, disruptions
│ │ │ ├── questions.py # Question bank (extract, generate, grade)
│ │ │ ├── study.py # Pomodoro, stats, rescheduling
│ │ │ ├── tasks.py # Task CRUD
│ │ │ ├── tutor.py # Gauntlet game (Socratic tutor)
│ │ │ └── whiteboard.py # Notes, PDF chat
│ │ └── agent/
│ │ └── scheduler.py # Deterministic scheduling engine
│ └── vercel.json
└── frontend/
└── src/
├── app/
│ ├── dashboard/ # Home dashboard
│ ├── focus/ # Pomodoro timer + scenes
│ ├── flashcards/ # Flashcard sets + Jeopardy
│ ├── games/ # Game hub + Gauntlet
│ ├── questions/ # Question bank
│ ├── whiteboard/ # PDF notes workspace
│ ├── modules/ # Course management
│ └── settings/ # Profile + preferences
└── lib/
├── api.js # Typed API client
├── supabase.ts # Supabase client
└── noteRenderer.tsx # Markdown/note rendering
Before deploying module exam context, apply backend/migrations/20261103_gauntlet_exam_config.sql to the target Supabase database, then deploy the backend and frontend. See migration and rollback instructions.
Rooms automatically checkpoint conversations, topic position and stars and resume on reopening without another initial AI turn. Apply backend/migrations/20261109_gauntlet_progress.sql before deploying autosave; the earlier exam-context SQL alone does not add this column. See migration and rollback instructions.
cd backend
pip install -r requirements.txt
uvicorn app.main:app --reloadRequires .env:
SUPABASE_URL=...
SUPABASE_SERVICE_KEY=...
ANTHROPIC_API_KEY=...
cd frontend
npm install
npm run devRequires .env.local:
NEXT_PUBLIC_SUPABASE_URL=...
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
NEXT_PUBLIC_API_URL=http://localhost:8000
Whiteboard auto-flashcards use POST /flashcards/generate-from-url with JSON containing pdf_url, user_id, course_id, title and optional instructions. Only public whiteboard PDFs under the configured SUPABASE_URL and the matching user/course storage path are accepted; downloads are capped at 20 MiB and redirects are disabled. Multipart PDF generation remains available at /flashcards/generate.
GoF prefers PyMuPDF text extraction when available to avoid embedded-font character-map corruption, with pypdf as fallback. New topic extraction and tutoring retain the full supported PDF text up to 100,000 characters, rather than silently clipping at 30,000; longer sources must be split. Existing cached room text is not automatically re-extracted. Topic extraction accepts JSON objects or arrays, including fenced or explanatory wrappers, and validates topics before caching. Its response cap is 4,000 output tokens (previously 2,000); this is a ceiling, not a fixed charge. Truncated/invalid topic replies produce a specific error without an extra automatic extraction call or cached bad data. Model selection is unchanged.
For a failed request, copy the specific Network request's URL, HTTP status and response detail, omitting tokens and signed query strings. A missing query.user_id response belongs to a query-based endpoint; /tutor/start uses a JSON body with pdf_url and optional room_id, not a user_id query. DNS errors need the failing hostname to distinguish API, storage and external asset failures.
Whiteboard signed uploads store new PDFs under unique ASCII object keys (user/course/<uuid>.pdf) while keeping the original filename in page metadata. Re-uploading the same displayed filename creates a new object rather than overwriting one used by another page or room. Existing PDF URLs are unchanged. Storage errors are shown with their message and HTTP status; signed URLs/tokens must not be shared in diagnostics. No storage policy or size-limit changes are required for this fix.