A personal LeetCode practice app with bilingual problem content, curated study lists, company tags, progress tracking, AI-generated explanations, and a local online judge.
The project is a TypeScript monorepo:
client/- React 19 SPA, Vite, Tailwind CSS v4, shadcn/ui-style components, wouter routing.server/- Express, tRPC, scheduled sync endpoints, OAuth/session plumbing, judge runtime.shared/- Zod schemas and shared types used by both client and server.drizzle/- MySQL schema and migrations.
- GitHub repo:
teddy8023mars/leetcode-tracker - Default branch:
master - CI: GitHub Actions runs
pnpm checkandpnpm test - Test baseline:
42test files /130tests passing - Main local workflow: use git worktrees for new feature work
- Problem list with search, difficulty/status/company/topic filtering, and pagination.
- Problem detail page with bilingual content fallback, related problems, tags, company labels, official/AI solutions, and a side-by-side solve panel.
- Local code editor powered by Monaco with Python/Java/C++ templates.
- Online judge pipeline with generated test suites, cached submissions, verdicts, and first-failing-case details.
- User progress tracking with todo/reviewing/done states and SM-2 spaced repetition fields.
- Sync pipeline for LeetCode study plans, LeetCode detail data, Chinese content fallback, and company tags.
- Owner-only manual sync controls and heartbeat-protected scheduled endpoints.
Requirements:
- Node.js 24
- pnpm 10.4.1
- MySQL if you want real persisted data
pnpm install
cp .env.example .env
pnpm devThe dev server starts Express and Vite together. By default it tries port 3000
and will use the next available port if needed.
Without DATABASE_URL, the server still boots, but most data-backed screens return
empty data. That is useful for frontend-only work, but real sync/progress/judge
history requires a database.
Do not commit .env. Start from .env.example.
Important variables:
DATABASE_URL- MySQL connection string used by Drizzle.JWT_SECRET- session cookie signing secret.OWNER_OPEN_ID- enables owner-only sync actions for that OAuth user.OAUTH_SERVER_URL,VITE_OAUTH_PORTAL_URL,VITE_APP_ID- Manus OAuth/app wiring.HEARTBEAT_SECRET- protects/api/scheduled/*endpoints.BUILT_IN_FORGE_API_URL,BUILT_IN_FORGE_API_KEY- OpenAI-compatible Forge endpoint used for translation and test generation.BOOTSTRAP_SKIP_CN,BOOTSTRAP_SKIP_LLM- optional bootstrap switches for long-running sync jobs.
pnpm dev # Run Express + Vite dev server
pnpm build # Build client and bundle server into dist/
pnpm start # Run production build
pnpm check # TypeScript type check
pnpm test # Vitest test suite
pnpm format # Prettier write
pnpm db:push # Generate and run Drizzle migrationsSingle test example:
pnpm vitest run server/__tests__/sync.leetcode.detail.test.tsUse a new worktree for every feature or cleanup:
git fetch origin
git worktree add /private/tmp/leetcode-tracker-my-feature -b codex/my-feature origin/master
cd /private/tmp/leetcode-tracker-my-feature
pnpm install --frozen-lockfileBefore pushing:
pnpm check
pnpm test
git diffKeep commits small and behavior-focused. Good commit examples:
fix: stabilize scheduled sync testsfeat: add review dashboarddocs: add project setup guide
The app exposes a typed tRPC API at /api/trpc. The root router is assembled in
server/routers.ts and currently includes:
problems- list/detail/solutions/company tagslistsandcompanies- metadata for curated lists and company tagsprogress- local progress and spaced repetitionjudge- authenticated code submission and submission historyaiSolutions- cached AI explanations and admin generationsync- sync status and owner-only manual triggersauthandsystem- session and system plumbing
The primary schema lives in drizzle/schema.ts. Tests use an in-memory SQLite
helper in server/testHelpers/inMemoryDb.ts, so schema changes usually need a
matching test DDL update.
Sync jobs are registered in server/sync/index.ts and executed through the
orchestrator in server/sync/orchestrator.ts. Scheduled HTTP endpoints live in
server/scheduled.ts and are protected by HEARTBEAT_SECRET.
The judge writes temporary files, runs user code in subprocesses with time and memory limits, and stores submissions. It is suitable for local/dev use; a real production deployment should replace it with a stronger sandbox.
- Developer log
- M1 verification report
- Planning/spec history under
docs/superpowers/
- Prefer GitHub issues for new features before implementation.
- Keep
.env.exampleupdated when adding environment variables. - Run
pnpm checkandpnpm testbefore every push. - For database schema changes, update Drizzle schema, migrations, and in-memory test DDL together.