2026-07-03 08:06:26 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 08:06:26 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 07:55:10 +03:00
2026-07-03 08:06:26 +03:00

Frontend Judge

A small classroom judge for 11th grade students practicing basic HTML, CSS, and JavaScript.

Features

  • Student shared-password access with browser-based HTML/CSS/JS editors.
  • Live iframe preview while students type.
  • Optional student name stored in the browser and attached to submissions.
  • Student-visible submission history per task and entered name.
  • Admin shared-password dashboard.
  • Ordered day groups with one group per task.
  • Markdown task descriptions.
  • Uploaded images or downloaded image URLs inserted into task markdown.
  • Reference HTML/CSS/JS that generates an expected screenshot.
  • Rule-based judging with DOM, text, attribute, CSS, element-count, and visual-match checks.
  • SQLite persistence and generated images stored in a Docker volume.

Local Development

cp .env.example .env
npm install
npm run prisma:generate
npm run dev

The backend runs on http://localhost:4000. The SQLite tables are created automatically when the backend starts.

For frontend hot reload in a second terminal:

npm run dev --workspace frontend

Then open http://localhost:5173.

Docker

Create a production .env next to docker-compose.yml:

ADMIN_PASSWORD=your-admin-password
STUDENT_PASSWORD=your-student-password
SESSION_SECRET=a-long-random-secret
PUBLIC_URL=https://your-domain.example

If a generated password or secret contains $, wrap the value in single quotes in .env, for example SESSION_SECRET='abc$123'. Docker Compose treats $ as variable interpolation otherwise.

Start the app:

docker compose up --build -d

If your server uses the legacy Compose binary, use docker-compose up --build -d.

Open:

  • Student app: http://localhost:4000
  • Admin app: http://localhost:4000/admin

Use HTTPS on the public server, ideally through your reverse proxy.

Judging Notes

Visual matching is intentionally tolerant. The browser renders both the reference solution and student submission with the same viewport, then compares screenshots. Use structure and CSS checks for hard requirements, and visual matching as a broader similarity signal.

The backend renders student JavaScript only inside Playwright, with short timeouts and network requests blocked during judging. The live preview uses a sandboxed iframe.

S
Description
No description provided
Readme
237 KiB
Languages
TypeScript 89.7%
CSS 9.3%
Dockerfile 0.8%
HTML 0.2%