# 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 ```bash cp .env.example .env npm install npm run prisma:generate npm run dev ``` The backend runs on [http://localhost:4000](http://localhost:4000). The SQLite tables are created automatically when the backend starts. For frontend hot reload in a second terminal: ```bash npm run dev --workspace frontend ``` Then open [http://localhost:5173](http://localhost:5173). ## Docker Create a production `.env` next to `docker-compose.yml`: ```bash 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: ```bash 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.