Skip to content

Repository files navigation

JudgeMyCode

JudgeMyCode is a React/Vite interview workspace backed by a Go API and PostgreSQL. The supported development workflow can use either loopback-only PostgreSQL in Docker or an explicitly configured managed PostgreSQL database, while the API and frontend run directly on the host.

One-command local development

Prerequisites:

  • Go 1.25 or newer compatible toolchain
  • Node.js 22.12+ and npm
  • Docker with Compose v2 when using the default local database mode
  • curl, lsof, and cksum (included by default on macOS and most Unix systems)
  • For every local execution language: Python 3, a JDK (javac/java), and a C++17 compiler (g++). Missing toolchains do not prevent the application from starting; that language reports RUNTIME_UNAVAILABLE when used.

From this directory:

./run-local.sh

The command is safe to repeat. In the default DATABASE_MODE=local, it starts and waits for Docker PostgreSQL, applies migrations, and loads local demo users and the problem catalog. With DATABASE_MODE=remote (or --remote-db), it uses the non-loopback DATABASE_URL, skips Docker, applies migrations only, and never automatically seeds users or catalog data. Both modes install locked frontend dependencies when needed, rebuild/restart the API and Vite processes, and wait for both HTTP endpoints.

Yes: run-local.sh starts the database dependency, backend, and frontend. To start again after stopping—or to rebuild/restart after code changes—run the same command:

./run-local.sh

Use ./run-local.sh --setup-only when you want dependencies, migrations, seeds, and npm packages prepared without starting the API or frontend.

Service Local address
Frontend http://127.0.0.1:5173
API http://127.0.0.1:5050/api
PostgreSQL 127.0.0.1:5432 or the configured managed service

Runtime logs are under logs/; validated PID files are backend.pid and frontend.pid.

./stop-local.sh                 # API + frontend
./stop-local.sh --dependencies  # also stop PostgreSQL; data volume is kept

The Makefile exposes the same workflow:

make setup     # dependencies, configured database schema, local-only seeds
make dev       # frontend + API using the configured database mode
make stop      # application processes only
make stop-all  # application + local Docker PostgreSQL
make check     # shell, Go, TypeScript, and Compose checks
make test      # Go tests and race detector
make build     # API binary and production frontend bundle

Managed PostgreSQL / Aiven

Store the development connection URI in interviewhub-backend-go/.env.local, which is ignored by Git and excluded from Docker builds. Never put it in frontend variables, .env.example, source code, documentation, or logs. A production deployment must inject DATABASE_URL through its secret manager rather than copying an env file into the image.

DATABASE_MODE=remote
DATABASE_URL='postgres://<user>:<url-encoded-password>@<host>:<port>/<database>?sslmode=require'
DATABASE_MAX_OPEN_CONNS=5
DATABASE_MAX_IDLE_CONNS=2
DATABASE_CONN_MAX_LIFETIME=15m
DATABASE_CONN_MAX_IDLE_TIME=5m

The URI must stay quoted if it contains &, $, spaces, or other shell-significant characters. sslmode=require encrypts the connection. For server identity verification, download Aiven's project CA into the ignored interviewhub-backend-go/.local-secrets/ directory and use sslmode=verify-full&sslrootcert=/absolute/path/to/aiven-ca.pem.

For a new hosted database, initialize the built-in problem catalog once and deliberately; remote full-stack startup otherwise performs schema migrations only:

cd interviewhub-backend-go
./scripts/seed-db.sh --skip-migrate
cd ..
./run-local.sh

Do not use --users, --force-users, or --reset-problems against the hosted database. ./stop-local.sh --dependencies never stops or deletes a remote database.

Repository layout

  • interviewhub-backend-go/: Go API with internal/httpapi as the composition/router boundary, embedded SQL migrations, PostgreSQL adapter, and local execution engine.
  • interviewhub-lld/: React 19, TypeScript, Vite, and Monaco frontend organized around src/app, feature modules under src/features, and shared infrastructure under src/shared.
  • run-local.sh / stop-local.sh: idempotent local lifecycle.
  • .github/workflows/ci.yml: backend, frontend, script, Compose, and image checks.

Execution is asynchronous: run/submit returns an execution ID, and the client polls the owned execution resource until it reaches COMPLETED, FAILED, or TIMED_OUT.

Workspace autosave uses server revisions instead of timestamps. Every write is compare-and-swap; a stale browser receives 409 Conflict and must explicitly keep its local draft or load the server version. Each open tab also keeps its own recovery journal, so tabs cannot silently overwrite one another's unsaved work.

Administrator problem edits also use compare-and-swap with the problem's updatedAt revision. The guarded statement update and starter/test replacement are one PostgreSQL transaction, and catalog seed/reset operations share the same mutation lock. A stale editor therefore receives 409 Conflict instead of silently replacing another administrator's work.

A plain run executes once with custom standard input. A selected public test runs with its server-owned input and expected output, “Run all tests” evaluates all public tests, and submit evaluates public plus hidden tests before writing submission history. Client-supplied assertions are never trusted.

Submit jobs capture an immutable catalog/test snapshot at queue admission and persist its SHA-256 evaluationRevision. Later administrator edits therefore cannot change an in-flight grade, and historical assertion values are removed from submission responses.

Submission history uses owner-scoped keyset pagination (50 rows by default, 100 maximum) and lightweight indexed summaries; source files and execution output are loaded only through the owner/admin detail endpoint. User progress, including solved problem IDs, is calculated in one PostgreSQL aggregate rather than by downloading and scanning a tenant's history in the browser.

Refresh credentials rotate once, are serialized with logout at the database family boundary, and retain the original absolute expiry. The browser uses a cross-tab lock plus principal/login-epoch lineage, so concurrent tabs adopt one replacement and a delayed request can never replay under a newly signed-in account. Failed logouts are kept as independent per-credential records in a bounded, deduplicated revocation queue, so concurrent tabs cannot lose one another's work; the queue is retried at startup, when connectivity returns, on cross-tab changes, and around later sign-ins. One required browser Web Lock serializes every credential mutation; unsupported browsers fail closed instead of relying on an expiring client lease. A separate drain lock keeps old network revocations from blocking a new login, and each HTTP request carries the bearer captured with its originating session and body. The API bounds refresh and logout requests independently by source and hashed opaque credential, and PostgreSQL family operations use the direct family_id index.

AI feedback is optional. Configure an OpenAI-compatible chat-completions endpoint with AI_API_URL, AI_API_KEY, and AI_MODEL; AI_REQUEST_TIMEOUT defaults to 20s and AI_MAX_OUTPUT_TOKENS to 700. With no key/provider configured, the API returns a clear unavailable/configuration error and never fabricates feedback. Staging/production also requires AI_EXTERNAL_GUARD=true as an explicit acknowledgement that a distributed quota and spend guard exists upstream.

Security boundary

EXECUTION_ENABLED=true is written only for the explicit local-development workflow. The current runner executes candidate programs on the API host and is not a security sandbox. Never expose it to untrusted users. Production must set EXECUTION_ENABLED=false until a dedicated network-disabled judge service with CPU, memory, process, filesystem, output, and wall-time isolation is implemented.

The Compose file intentionally contains PostgreSQL only. Redis and the placeholder worker were removed because no durable queue/worker implementation exists yet.

See backend documentation, API documentation, and the production architecture contract.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages