Skip to content

Best Practices ​

The principles this codebase actually follows — each one earned by a specific incident or constraint documented elsewhere on this site. Useful both as house style and as interview material, since every entry comes with a concrete story.

Design around the platform's constraints, early ​

The 20k-file Pages limit was designed around at ~1,200 questions, not discovered at 19,999 (Question Bank). Free-tier AI flakiness was answered with a nine-provider chain before an exam-day outage, after the first cascading failures (AI Pipeline). The pattern: read the platform's limits page first, then architect.

One implementation per concern ​

One markdown parser, one AI client, one judging path, one "where is the website" resolver. Every duplicated implementation in this project's history drifted and caused a bug — the 34-duplicate incident was a drifted duplicate of the lint rules (Tools Overview). If two things must agree, make them one thing, or make their agreement a tested contract (the twice-implemented grading contracts are the deliberate exception, and they carry tests).

Turn every incident into a gate ​

Compile timeout → banned include in lint. Wrong reference solution → mandatory verify_solution.py. Duplicate questions → live-content collision checks. Missing hints → pipeline validation. The instance gets fixed once; the class gets fixed forever. Corollary: a fix without a gate is half a fix.

Deterministic first, AI second ​

Aptitude and SQL decide correctness without a model and use AI only to explain (Aptitude, SQL). Where AI must judge (free-text CS answers), it's fenced: rubric-bound, JSON-coerced, chain-backed, honest-stubbed. Never let a model own a verdict that arithmetic can own.

Fail loudly, degrade honestly ​

The echo stub announces itself instead of imitating a model. Missing tokens 500 with a message instead of rendering an empty pane. Judge unavailability is a named verdict, not a hang. Silent degradation is how the reminder bug lived so long — the Worker "worked," it just skipped people (Scheduling).

Server timestamps own time; preconditions own concurrency ​

Exam timers derive from Firestore startedAt, never client state (OA Simulator). Workers claim work with updateTime/create preconditions instead of locks (Workers). Both replace "hope the client/cron behaves" with an invariant the database enforces.

Measure before optimizing — and accept surprising answers ​

Judge concurrency = 1 beat parallelism on the single-core VM. Virtualization beat memoization for long lists. The 1,153→855KB bundle drop came from measuring what actually shipped, not guessing (Performance).

Mirrored data must name its freshness mechanism ​

The email-sync bug in one sentence: a field copied once is a field that rots. Every mirror now answers "what keeps this fresh?" at the moment it's introduced (Authentication).

Scope honestly ​

Anti-cheat discourages, it doesn't proctor — and says so. problemStats documents the write-integrity limitation it accepts and the escalation path if stakes rise (Database). Claiming less than the system does is how the claims stay true.

Secrets: minimum scope, server-side, rotatable ​

The token incident produced the rule set: fine-grained read-only scope, Pages/Worker env only, rotation without redeploy, loud failure on absence (Docy). And the build-time/runtime split is absolute: VITE_* is public, Function env is secret.

Ediky Workflow — internal engineering documentation.