Skip to content

Repository files navigation

Code-Craft

A full-stack competitive programming judge — a LeetCode/Codeforces-style platform where users solve algorithmic problems and compete in timed contests. User-submitted code is compiled and executed against test cases inside isolated, resource-limited Docker sandboxes, with results streamed back over WebSockets.

Built as a Turborepo monorepo spanning a Next.js frontend, a Python (FastAPI + Celery) execution engine, a submission webhook service, and a WebSocket server, all backed by PostgreSQL and Redis.

Demo login: username demo · password password123


Features

  • Multi-language execution — submit solutions in C++, Python, and JavaScript (Rust scaffolded).
  • Sandboxed code runner — every submission runs in a throwaway Docker container with memory, CPU, PID, and network limits (see Security).
  • Contests — timed rounds with problem sets, live leaderboards, and a time-decaying scoring system.
  • Boilerplate generator — parses a per-problem Structure.md spec and auto-generates function stubs + a full I/O harness for each language.
  • Username/password auth — credentials-based auth via NextAuth + bcrypt (JWT sessions).
  • Async pipeline — submissions are queued and processed by Celery workers, decoupling the web tier from execution.

Architecture

                  ┌──────────────────────────────────────────────────────┐
                  │                      Browser                          │
                  └──────────────┬───────────────────────▲───────────────┘
                                 │ submit code            │ live results
                                 ▼                        │ (WebSocket)
        ┌────────────────┐   ┌───────────────┐    ┌───────┴────────┐
        │  web (Next.js) │──▶│   executor    │    │   ws server    │
        │  :3000         │   │ FastAPI :8000 │    │   :4000        │
        │  problems,     │   │  + Celery     │    └───────▲────────┘
        │  contests, auth│   │   workers     │            │
        └───────┬────────┘   └──────┬────────┘            │
                │                   │ enqueue / run        │ publish
                │                   ▼                      │
                │            ┌─────────────┐         ┌─────┴────────┐
                │            │  Docker     │         │  submission  │
                │            │  sandbox    │────────▶│  webhook     │
                │            │ (per run)   │ callback│  :3002       │
                │            └─────────────┘         └─────┬────────┘
                │                                          │
                ▼                   ┌──────────────────────┴───────┐
        ┌───────────────┐          │                              │
        │  PostgreSQL    │◀─────────┘                       ┌──────▼──────┐
        │  (Prisma)      │                                  │    Redis    │
        └───────────────┘                                  │ broker/queue│
                                                            └─────────────┘

Flow: the web app writes a submission and calls the executor → the executor enqueues a Celery task → a worker runs the code in a Docker sandbox → the result is POSTed to the submission webhook → the webhook persists it and publishes to Redis → the WebSocket server pushes the verdict to the browser in real time.

Monorepo layout

Path Description
apps/web Next.js 14 app — problems, contests, leaderboards, auth (App Router)
apps/executor FastAPI API + Celery workers that compile & run code in Docker sandboxes
apps/submission-webhook Express service handling judge callbacks, scoring & persistence
apps/ws WebSocket server for live submission updates
apps/boilerplate-generator Generates language stubs from each problem's Structure.md
apps/problems Problems-as-files (statement, test inputs/outputs, reference solution)
packages/db Prisma schema, client, migrations & seed
packages/common Shared Zod schemas & language config
packages/redis-utils Redis pub/sub helpers
packages/ui Shared React component library (shadcn-style)

Tech stack

Frontend: Next.js 14, React 18, TypeScript, Tailwind CSS, NextAuth Backend: FastAPI, Celery, Express, Node.js Data: PostgreSQL (Prisma ORM), Redis Infra: Docker / Docker Compose, Turborepo


Getting started

Option A — Docker Compose (recommended)

Brings up the entire stack (Postgres, Redis, all services) and automatically runs migrations + seeds the database:

docker compose up --build

Then open http://localhost:3000 and sign in with demo / password123.

The executor shells out to docker run to sandbox submissions, so it needs access to the Docker socket in a production setup.

Option B — Local development

Prerequisites: Node ≥ 18, Python 3.11, Docker, and a running PostgreSQL + Redis.

# 1. Install dependencies
yarn install

# 2. Configure environment (copy the examples and fill in values)
cp .env.example .env
cp apps/web/.env.example apps/web/.env
cp packages/db/.env.example packages/db/.env
cp apps/executor/.env.example apps/executor/.env

# 3. Set up the database
yarn db:generate      # generate Prisma client
yarn db:migrate       # apply migrations
yarn db:seed          # seed 100 problems + 12 contests + demo user

# 4. Run the web app + node services
yarn dev

# 5. Run the Python executor (separate terminals)
yarn dev:python       # FastAPI
yarn dev:celery       # Celery worker

Security & sandboxing

User code is never run on the host. Each submission executes in a fresh, ephemeral Docker container with strict limits (apps/executor/code/language_executor_factory.py):

Control Setting Protects against
Memory cap --memory=128m memory exhaustion
CPU cap --cpus=0.5 CPU starvation
No network --network=none data exfiltration / SSRF
PID limit --pids-limit=128 fork bombs
No privilege escalation --security-opt no-new-privileges container escapes
Wall-clock timeout 30s on the subprocess infinite loops
Ephemeral --rm state leaking between runs

Testing

yarn test            # run the suite once
yarn test:watch      # watch mode

Unit tests (Vitest) cover the pure logic: the boilerplate ProblemDefinitionParser (parsing + per-language code generation) and the contest scoring function (time-decay, difficulty mapping, zero-window edge case).


Useful scripts

Command Description
yarn dev Run all JS/TS apps via Turborepo
yarn build Build all apps & packages
yarn lint Lint the workspace
yarn test Run unit tests
yarn db:migrate Apply Prisma migrations
yarn db:seed Seed the database

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages