A checkpoint revision platform for Zone01 students to practice Go (and more) coding exercises in a real exam-like environment.
zcheck-simulator/
├── backend/ # Django + DRF + Channels + Celery
├── frontend/ # React + Monaco Editor
├── .gitignore
└── README.md
| Layer | Choice |
|---|---|
| Frontend | React, Monaco Editor, React Router |
| Backend | Django 5, Django REST Framework, SimpleJWT |
| Real-time | Django Channels, Daphne (ASGI), Redis |
| Task Queue | Celery + Redis |
| Code Execution | Custom Docker sandboxes per language (one container per submission) |
| Database | PostgreSQL |
| Proxy | Nginx |
- Docker + Docker Compose
- Node.js 18+
- Python 3.12+
git clone <repo>
cd zcheck-simulatorBackend environment:
cd backend
cp .env.example .env
# Edit .env — set SECRET_KEY, DOMAIN, DB passwordFrontend environment:
cd frontend
cp .env.example .env
# Edit .env — set REACT_APP_API_URL and REACT_APP_WS_URLEach language runs in its own isolated Docker sandbox.
Go runner (z01 package fetched automatically at build time):
docker build -t zcheck-go-runner:latest backend/docker/go-runner/z01 is pulled from
github.com/01-edu/z01during the image build and cached inside the image. No files to copy manually. Network is disabled at runtime — students cannot make HTTP calls from their code.
Python runner:
docker build -t zcheck-python-runner:latest backend/docker/python-runner/JavaScript runner:
docker build -t zcheck-js-runner:latest backend/docker/js-runner/cd backend
docker-compose up -dThis starts:
django— Daphne ASGI server (HTTP + WebSocket), runs migrations + collectstatic on bootcelery— async code execution workerredis— message broker + channel layerdb— PostgreSQLnginx— reverse proxy
Migrations run automatically on first start. No manual
migrateneeded.
# Seed Go Elementary Programming exercises
docker-compose exec django python manage.py seed_go_exercises
# Create your admin account
docker-compose exec django python manage.py createsuperusercd frontend
npm install
npm startFrontend runs at http://localhost:3000
Only required if you add new models or change existing ones:
docker-compose exec django python manage.py makemigrations users
docker-compose exec django python manage.py makemigrations exercises
docker-compose exec django python manage.py makemigrations submissions
docker-compose exec django python manage.py makemigrations runner
docker-compose exec django python manage.py migrate
runnerhas no models —No changes detectedis expected.
| URL | Description |
|---|---|
http://localhost:3000 |
Student app |
http://localhost:3000/admin |
Admin panel (staff only) |
http://localhost:8000/api/ |
REST API |
http://localhost:8000/django-admin/ |
Django admin (fallback) |
ws://localhost:8000/ws/submissions/<id>/ |
WebSocket — submission results |
/disclaimer
→ Student sets optional timer (hours + minutes)
→ Reads exam rules, checks agreement
→ Browser enters fullscreen
↓
/practice
→ Fetches available levels from exercise bank
→ Starts session in DB
→ Level 1 (5%): random exercise assigned — locked in
→ Submit → pass → Level 2
→ Submit → fail → retry same exercise
→ Give up → Terminate button → session ends
→ ...up through all available levels
→ All levels complete OR terminated OR timer runs out
↓
Session Summary screen
→ Shows each level: exercise name, attempts, PASS/FAIL
→ Overall score and completion %
→ Options: Dashboard or Try Again
POST /api/submit/ {exercise_slug, code, session_id}
↓
1. Import validator — instant check (forbidden/illegal imports)
↓
2. 202 Accepted — submission ID returned immediately
↓
3. WebSocket opens: ws/submissions/<id>/?token=<jwt>
↓
4. Celery picks up task → ONE Docker container spins up
↓
5. Code compiles ONCE → binary runs against all test cases
↓
6. Results pushed via WebSocket:
- Public test cases: full detail (stdin, expected, actual, error)
- Hidden test cases: PASS/FAIL only — no input/output revealed
↓
7. accepted → auto-advance to next level (after 1.5s)
failed → show error in terminal, student fixes and resubmits
| Status | Meaning |
|---|---|
pending |
Queued, not yet picked up |
running |
Executing in Docker |
accepted |
All test cases passed ✅ |
wrong_answer |
Some test cases failed |
compile_error |
Code did not compile |
runtime_error |
Code crashed during execution |
time_limit |
Exceeded language timeout |
illegal_import |
Used a forbidden package (e.g. fmt when only z01 allowed) |
Hidden Test Cases — Anti-Hardcoding
- Public test cases — shown in full on failure: input, expected output, actual output
- Hidden test cases — only show
✅ Test N (hidden): PASSEDor❌ Test N (hidden): FAILED - Students never see hidden test case inputs or expected outputs, even after submission
- Makes hardcoding the expected output impossible
Exercises are organised by difficulty percentage. The session advances level by level:
| Level | % | Example exercises |
|---|---|---|
| 1 | 5% | only1, onlya, onlyb, onlyf, onlyz |
| 2 | 10% | checknumber, countalpha, countcharacter, printf, printifnot, rectperimeter, retainfirsthalf |
| 3 | 20% | cameltosnakecase, countrepeats, digitlen, firstword, fishandchips, gcd, hashcode, lastword, longestword, repeatalpha, searchreplace |
| 4 | 35% | cleanstr, expandstr, findprevprime, fromto, iscapitalized, itoa, passwordentropy, printmemory, printrevcomb, thirdtimeisacharm, weareunique, zipstring |
| 5 | 50% | addprimesum, canjump, chunk, concatalternate, concatslice, fprime, hiddenp, inter, reversestrcap, saveandmiss, union, wdmatch |
| 6 | 65% | fifthandskip, notdecimal, revconcatalternate, slice |
| 7 | 75% | findpairs, revwstr, rostring, wordflip |
| 8 | 85% | itoabase, options, piglatin, romannumbers |
| 9 | 95% | brackets, rpncalc |
| 10 | 100% | brainfuck, grouping |
Only levels that have exercises in the bank are shown. If a level has no exercises yet, it is skipped automatically.
Accessible to staff users only. Appears in navbar as a purple "Admin" link.
| Section | What you can do |
|---|---|
| Overview | Stats at a glance |
| Exercises | Full CRUD — description, starter code, import rules, difficulty, main file config |
| Test Cases | Per exercise — add/edit/delete, mark public or hidden, set order |
| Checkpoints | Create checkpoint events, assign language |
| Languages | Add language, set Docker image, timeout, memory limit, forbidden imports |
| Users | View and search students, manage roles, enable/disable accounts, reset passwords, view full submission and session history, inspect submitted code |
- Search users by username or email
- Toggle active status and staff/admin role via PATCH
- Reset any user's password directly from the admin UI
- Expand any user row to browse their full submission history with filters (checkpoint, exercise, date range, status, sort order)
- Click the
</>button on any submission to view the exact code submitted
A free-practice area outside of sessions. Accessible from the dashboard.
- Browse and filter exercises by language, checkpoint, and difficulty
- Two-tab Monaco editor: editable
main.go+ student solution file - Run test cases without starting a session — results streamed via WebSocket
- Full submission history per exercise shown inline
Recommended: Oracle Cloud Free Tier (4 vCPU, 24GB RAM — free forever)
# On the VPS (Ubuntu 22.04)
git clone <repo>
cd zcheck-simulator/backend
# Build runner images
docker build -t zcheck-go-runner:latest docker/go-runner/
docker build -t zcheck-python-runner:latest docker/python-runner/
docker build -t zcheck-js-runner:latest docker/js-runner/
# Configure environment
cp .env.example .env && nano .env
# Start everything
docker-compose up -d
# Seed data and create admin
docker-compose exec django python manage.py seed_go_exercises
docker-compose exec django python manage.py createsuperuser
# Build frontend
cd ../frontend
npm install && npm run build
# Serve build/ via Nginx (already configured in docker-compose nginx service)- Django backend — models, API, auth, JWT
- WebSocket real-time submission results (Channels + Daphne)
- Import validator — per exercise forbidden/allowed imports
- One-container Docker execution engine (compile once, run all test cases)
- React frontend — Auth, Dashboard, Practice Session, History, Checkpoint Map
- Disclaimer page with exam rules, timer setter, fullscreen
- Level-by-level session progression (pass to advance, retry or terminate on fail)
- Session timer — student-set, auto-terminates on expiry
- Session summary — per-level results, attempts, pass/fail
- Admin UI — Exercises, Test Cases, Checkpoints, Languages, Users
- Admin user management — search, role editing, password reset, submission history, code viewer
- Exercise sandbox — free practice outside sessions, Monaco editor, WebSocket results
- docker-compose — auto-migrate and collectstatic on startup
- Docker runner images — Go (z01 auto-fetched), Python, JS
- Full exercise + test case bank (5 seeded, 40+ remaining)
- Python and JavaScript checkpoint support