Mental math drills, an inventory-aware market-making simulator, and a probability/stats problem bank for quant trading interview prep. Spun out from the portfolio site so it can grow independently behind auth.
- Mental Math Trainer — timed arithmetic drills (configurable operations, digit sizes, round length) plus a sequences/pattern-recognition mode.
- Market-Making Game — the "make me a market" game from real trading interviews (Jane Street, Optiver, ...) in three flavors: card game, dice game, and Fermi estimates. You quote a two-sided bid/ask on a hidden total across rounds while information is revealed, against a counterparty that trades when it's profitable.
- Probability & Stats — a LeetCode-style problem bank: browse by index/title/
difficulty (★–★★★), filter by category, submit answers (decimals, fractions like
6/91, or expressions like(4/9)^4all accepted), with optional hints and full KaTeX-rendered solutions. Problems are authored in curated batches — each question written in original wording, solved, and verified numerically before import. A per-problem flag button lets users report suspect answers/parsing while the bank matures.
Scores and attempts persist per-user (Supabase), and /profile shows per-drill
stats including a cross-user percentile.
- Next.js 16 (App Router, Turbopack) + TypeScript + Tailwind CSS v4
- Supabase: Google OAuth sign-in + Postgres (attempt history, problem flags)
- KaTeX for math rendering
- Create a free project at supabase.com.
- In the Supabase dashboard, go to Authentication → URL Configuration and add
http://localhost:3000/auth/callback(and your production URL's/auth/callbackonce deployed) to the redirect allow list. Then under Authentication → Providers, enable Google (create an OAuth client in Google Cloud Console and paste the client ID/secret — Supabase shows the exact redirect URI to use). - Run each file in
supabase/migrations/(in order) in the dashboard's SQL Editor — they create thedrill_attemptstable, the percentile RPC, and theproblem_flagstable. - Copy
.env.local.exampleto.env.localand fill in the values from Project Settings → API:NEXT_PUBLIC_SUPABASE_URL=... NEXT_PUBLIC_SUPABASE_ANON_KEY=... NEXT_PUBLIC_SITE_URL=http://localhost:3000 - Install dependencies and run the dev server:
npm install npm run dev - Visit
http://localhost:3000, sign in with Google, and open/practice.
The app degrades gracefully without a Supabase project: drills work, but sign-in and score persistence no-op.
Problem content lives in the Supabase problems table, not in this repo (fields:
id, source, chapter, difficulty, category, title, question, hint,
answer_type, answer, tolerance, solution, tags — questions/hints/solutions
support KaTeX $...$ and $$...$$). Batches are authored locally in a gitignored
staging file and upserted with scripts/migrate-problems.mjs.
Content policy: no fabricated problems, and no problem text reproduced verbatim
from any source. Every question is written in original wording, and every answer
is verified numerically (exact computation or simulation) before it's upserted. Solutions and hints are original. Answers and
solutions never leave the server — checking goes through the check_answer /
reveal_solution RPCs (see supabase/queries/problem_bank_review.sql for how
flags + solve stats are reviewed).
Deploy to Vercel (connect this repo) and set the same three
env vars in the Vercel project settings. Update the Supabase redirect allow list
with your production /auth/callback URL, and set NEXT_PUBLIC_SITE_URL to your
production domain.
- More problem-bank batches (conditional probability, expectation games).
- Leaderboard across drills — requires moving answer checking server-side first.
- Spaced-repetition resurfacing of missed problems.
Code is MIT-licensed. Problem-bank content (questions, solutions, hints)
is not part of this repository — it lives in the app's database and is meant to be
practiced against in the app rather than repackaged. src/data/fermi_questions.json
contains factual reference values with verification noted inline.