Skip to content

Repository files navigation

Edge

A deterministic mental-math and estimation trainer for quant interview prep — arithmetic, percentages, probability & expected value, and market-making estimation.

The engineering, not the pitch, is the point of this project:

  • Deterministic scoring. Every problem is generated and graded with exact rational arithmetic (a bigint-backed Fraction type in core/) — no floating-point drift, no fuzzy matching, and no AI grading anywhere in the loop. A correctness verdict is a pure function of (problem, input).
  • Elo-adaptive difficulty. Each topic tracks a skill rating updated with a standard Elo expected-score formula (K = 32) after every answer. The next problem's difficulty tier is chosen to target a ~70% expected success rate.
  • Property-tested invariants. fast-check proves exactness, monotonic difficulty, determinism from a seed, Elo boundedness/direction, and that scoring never throws — see Test coverage below and docs/architecture.md.
  • Seeded & reproducible. A mulberry32 PRNG seeded from your session seed means the same seed and settings always regenerate the exact same problem sequence.

Scope note (v1): no accounts, no backend, no AI — session history lives in localStorage only. This is a deliberate v1 decision, not an oversight; see docs/architecture.md for what a v2 backend migration would look like.

Screenshots

Landing Landing page

Setup Session setup

Session Practice session

Summary Session summary

Dashboard Dashboard

Project structure

edge-trainer/
├── core/           # pure TypeScript — zero React/Next/UI imports, enforced by lint
│   ├── fraction.ts     # exact rational arithmetic (bigint-backed)
│   ├── prng.ts          # mulberry32 seedable PRNG
│   ├── generator.ts     # problem generation, 4 categories, difficulty tiers 1-10
│   ├── scoring.ts        # deterministic correctness checking + tolerance rules
│   ├── adaptive.ts       # Elo rating engine + next-difficulty selection
│   ├── stats.ts           # session statistics (accuracy, percentiles, rating trend)
│   ├── types.ts            # shared types
│   └── __tests__/           # unit + fast-check property tests
├── app/            # Next.js 14 App Router pages
├── components/ui/  # small hand-rolled shadcn-style primitives (no extra UI framework)
├── lib/            # browser-facing glue: localStorage schema, session runner
├── e2e/            # Playwright end-to-end specs
├── docs/           # architecture docs
└── .github/workflows/ci.yml

core/ never imports from react, next, or components//app//lib/ — enforced by an ESLint no-restricted-imports rule, checked in CI. See docs/architecture.md for the full data-flow diagram and the exact Elo/scoring formulas.

Getting started

Requires Node 20+ and pnpm (pinned via packageManager in package.json; corepack enable will pick it up automatically).

pnpm install
pnpm dev          # http://localhost:3000

Other scripts:

pnpm typecheck    # tsc --noEmit
pnpm lint         # next lint
pnpm test         # vitest — core/ unit + property tests
pnpm test:coverage
pnpm e2e          # Playwright end-to-end tests (spins up `pnpm dev` itself)
pnpm build        # production build

Test coverage

core/ is the part of this project where correctness actually matters — the UI is thin glue over it — so coverage is measured and reported for core/ specifically rather than the whole repo:

119 tests passing across 10 files (unit + fast-check property tests)

File          | % Stmts | % Branch | % Funcs | % Lines
--------------|---------|----------|---------|--------
All files     |   97.79 |    94.85 |    98.7 |   98.2
 fraction.ts  |   94.73 |    87.87 |      95 |  94.23
 generator.ts |   99.31 |      100 |     100 |   99.2
 adaptive.ts  |     100 |      100 |     100 |    100
 stats.ts     |     100 |      100 |     100 |    100
 types.ts     |     100 |      100 |     100 |    100
 prng.ts      |     100 |    83.33 |     100 |    100
 scoring.ts   |   91.66 |     90.9 |     100 |  96.66

Run pnpm test:coverage to regenerate (HTML report at coverage/index.html). The required invariants — exactness, monotonic difficulty, determinism, Elo boundedness/direction, and "scoring never throws" — are listed with their test files in docs/architecture.md.

Three Playwright E2E specs (e2e/) cover a fixed-count session end-to-end, a speed round, and a dashboard read of real localStorage state after a session — see pnpm e2e.

Deploy

Deploy target is Vercel — this is a standard Next.js 14 App Router project with no server-side environment variables required (everything is client-side/localStorage), so vercel / the Vercel Git integration works with zero configuration.

CI

.github/workflows/ci.yml defines a GitHub Actions pipeline that runs on every push/PR: install, typecheck, lint, core/ unit + property tests with coverage, then Playwright E2E. All of these pass locally (see Test coverage above); the pipeline itself is configured but not currently displayed via badge.

Non-goals (v1)

  • No AI/LLM features of any kind — see docs/architecture.md.
  • No accounts, auth, or backend database.
  • No social features, leaderboards, or cross-user comparison.
  • No mistake-review page yet (noted as future work).

About

Deterministic mental-math trainer for quant interview prep (exact rational arithmetic, Elo-adaptive difficulty, property-tested invariants). No AI/LLM anywhere in the grading loop

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages