Skip to content

System Architecture

High-level shape

diagram100%
rendering diagram…

drag to pan · ctrl / ⌘ + scroll to zoom

Three properties define the design:

  1. No dedicated backend service. Everything a backend would own is covered by a managed piece: persistence and authorization by Firestore + security rules, request/response endpoints by Pages Functions, scheduled work by Workers, code execution by Judge0. The tradeoff (authorization logic in rules instead of API code) is discussed in Challenges #4.
  2. Content is data, not code. Markdown never enters the Vite module graph — see Question Bank & Content Runtime.
  3. Secrets live server-side only. AI keys, the Judge0 auth token, the GitHub token for Docy, and the Firebase service-account key exist only in Cloudflare env vars / Wrangler secrets. The browser holds nothing sensitive; the public Firebase config is guarded by rules, not secrecy.

Request lifecycles

A DSA submission (Run / Submit)

diagram100%
rendering diagram…

drag to pan · ctrl / ⌘ + scroll to zoom

Concurrency to Judge0 is capped at 1 — measured empirically as optimal for the single-core free-tier VM (see Code Execution).

An AI-graded concept answer

diagram100%
rendering diagram…

drag to pan · ctrl / ⌘ + scroll to zoom

Lecture notes (Docy) into the learning workspace

SubjectLayout/list-notes (directory listing) → /get-notes?path=… per lecture → markdown rendered with KaTeX + annotations layered on top (Notes System). The GitHub token authorizing access to the private Docy repo never leaves the Function.

Where state lives

StateHomeWhy
Identity/sessionFirebase Auth (indexedDB persistence)Survives refresh mid-exam; no cookie plumbing
User data (events, submissions, drafts, annotations, revisions, OA attempts/templates)users/{uid}/… subcollectionsOwner-only rules are trivial to state and audit
Solve progress per sectionprogress/{uid}One doc per user, cheap snapshot
Community percentile dataproblemStats/{slug}Public-read aggregate, bucketed
Shared OA templatespublicOAs/{templateId}Public-read, owner-write
Question metadataStatic JSON shards (/content-index/*.json)CDN-cached, no DB reads for browsing
Question bodiesStatic .md (+ .tests.json sidecars) / jsDelivr for CPFetched on demand, cache-friendly
UI state (theme, sidebar)React contexts + localStorageNot worth a network round-trip

Full schema: Database Schema & Rules.

Failure & resilience posture

  • AI: a 9-provider fallback chain — an outage or 429 on one provider falls through to the next; the echo stub keeps the UI honest when no key is configured (AI Pipeline).
  • Judging: browser-driven judging survives tab closure via the OA Worker, which claims jobs with Firestore updateTime preconditions so it can never double-judge against a live tab (Workers).
  • Reminders: per-minute Cloudflare cron with optimistic-lock claims and delivered flags; the retired GitHub Actions cron remains only as a manual backstop (Scheduling).
  • Deploys: stale-SPA issues are prevented by _headers cache-control (HTML never cached, hashed assets immutable) — see Build & Deployment.

Ediky Workflow — internal engineering documentation.