Skip to content

About

cpproad: interactive C++ course (345 learncpp.com lessons) with sandboxed Judge0 grading, spaced review, and a bring-your-own-key AI tutor.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

419 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cpproad

Learn C++ through the learncpp.com curriculum — 345 lessons, auto-graded exercises, a sandboxed compiler, and an AI tutor that runs on your own API key.


What it is

cpproad turns the learncpp.com curriculum (34 chapters, 345 lessons) into an interactive course: read the lesson, write code in the browser, run it against real test cases, ask the tutor for a hint when you're stuck, and get the concept back tomorrow in review.

Free, open signup, no paid tier, no gated content.

Stack

Layer What runs it
App + API Next.js App Router, TypeScript strict mode, Vercel
Data + auth Supabase Postgres, magic-link auth, RLS on every table
Code execution Judge0 on the RapidAPI shared host
Tutor Gemini 2.5 Flash, streaming, user-supplied key

Content is data, not a runtime LLM call

Lesson summaries, exercises, and concept checks are authored offline and stored as plain files under scripts/regenerated/v2/<lesson>/ — summary.md and exercises.json. They're validated by scripts/validate_v2.ts and pushed into Postgres by scripts/push_v2.ts.

Serving a lesson is a database read. Nothing in the request path calls a model, so content is diffable in git, reviewable in a PR, and costs nothing per pageview. Content is paraphrased into cpproad's own voice, not scraped verbatim.

Tutor

Bring your own Gemini key. It's AES-256-GCM encrypted before it reaches the database and decrypted per request — cpproad never proxies a shared key, so tutor usage bills to the person using it. Without a key, /api/chat returns 403 rather than falling back to anything.

Hints escalate across four tiers: nudge → concept → structure → worked example. The tier comes from conversation state, so the tutor can't open with the answer.

Exercises and grading

Submissions compile and run in a sandboxed Judge0 instance, then get diffed against per-exercise test cases. Fork bombs, network egress, filesystem writes, OOM, infinite loops, and process enumeration were verified to fail closed as of 2026-06-11.

Production runs against RapidAPI's shared host, which means patch level, isolation, and rate limits are outside our control. A self-hosted gVisor setup is staged in infra/judge0/ and is not production-ready — the gVisor runtime is commented out and workers run privileged. Re-harden before deploying it.

Review scheduling

Every concept check a user answers writes both an attempt row and its scheduler state (interval_index, next_due) in one RPC. GET /api/review/due returns up to 20 due cards and nothing else touches the scheduler — all writes funnel through applyAttempt in lib/content/review.ts so the two tables can't drift apart.

GitHub sync (optional)

Connect a GitHub account and passed submissions get committed to your own public cpproad-submissions repo via the Contents API, so practice shows up on your contribution graph. Scope requested is public_repo; the token is encrypted at rest. Inert until an operator registers an OAuth app.

Contributing

Contributions are open, especially from people who want to teach: sharpen a lesson explanation, write a better exercise, fix a wrong test case, or flag where the curriculum glosses over a concept.

Every contribution starts with an issue. No unsolicited pull requests — open an issue, let it get triaged, then submit a PR referencing it. This keeps duplicate work down and means nobody burns a weekend on something already rejected or already in flight.

  • Bug — open an issue with steps to reproduce.
  • Wrong or unclear content — open an issue tagged content naming the chapter and lesson number. The source files are under scripts/regenerated/v2/; fix them like any other file and scripts/validate_v2.ts will gate the merge.
  • Feature — describe the problem before the solution. Feature PRs without a prior issue get asked to open one.

Local setup

Requires Node.js and the Supabase CLI (via npx).

npm install
cp .env.example .env.local   # fill in the values below
git config core.hooksPath .githooks   # blocks committing .env files
npx supabase db push         # apply database migrations
npm run dev

Environment variables

Variable Purpose
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY Supabase project (public)
SUPABASE_SERVICE_ROLE_KEY Server-only; bypasses RLS
JUDGE0_URL, JUDGE0_AUTH_TOKEN Judge0 code execution (currently RapidAPI shared host)
API_KEY_ENCRYPTION_SECRET Encrypts user Gemini keys and GitHub tokens (openssl rand -base64 32)
GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET Optional GitHub sync
NEXT_PUBLIC_STATSIG_CLIENT_KEY, STATSIG_SERVER_SECRET_KEY Statsig analytics and feature gates (server key required at runtime)

No server-side LLM key is needed: the tutor uses each user's own Gemini key, and lesson content is pre-generated under scripts/regenerated/v2/.

External services

Supabase (Postgres + auth), Judge0 via RapidAPI, Google Gemini (user-supplied keys), Statsig, GitHub OAuth (optional), Vercel (hosting).

Tests and checks

npm test               # vitest run
npm run lint
npm run format:check

Status

  • Implemented: lessons served from Postgres, in-browser editor with Judge0 grading, BYOK Gemini tutor with tiered hints, spaced-repetition review, optional GitHub sync.
  • Unfinished: self-hosted gVisor Judge0 in infra/judge0/ is staged but not hardened (gVisor runtime commented out, privileged workers); GitHub sync is inert until an operator registers an OAuth app.

License

MIT — see LICENSE.

About

cpproad: interactive C++ course (345 learncpp.com lessons) with sandboxed Judge0 grading, spaced review, and a bring-your-own-key AI tutor.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages