Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ExamBinary Technical Assessment — Node.js / TypeScript Solution

Senior Full-Stack / AI Engineer take-home for a multi-portal education platform (Students · Teachers · Parents). This repository contains the 7 hands-on code tasks, the 9 scenario screening answers, and the 4 system-design tasks, implemented in Node.js + TypeScript (the brief permits Node/TS in place of Python/FastAPI).

Runs with zero setup. npm install && npm test — no API keys, no Docker. Every external service (LLM, Redis, Mongo) is mocked behind an interface by default, with a real-service path behind environment flags.


Quick start

npm install
npm test          # 49 tests across all 7 code tasks
npm run typecheck # strict tsc --noEmit, zero errors

Run an individual task's live demo (all run offline against the mock provider):

npm run demo:task02   # strict JSON schema extraction
npm run demo:task04   # layout-aware chunking
npm run demo:task05   # OCR sanitize + fallback ladder
npm run demo:task07   # resilient gateway: backoff + jitter + model fallback
npm run demo:task10   # request coalescing + batching (130 calls → 4)
npm run demo:task01   # RBAC server  → http://localhost:4000  (curl examples printed)
npm run demo:task08   # SSE server   → http://localhost:4100  (curl examples printed)

To exercise the real Claude API, copy .env.example to .env, set LLM_PROVIDER=anthropic and ANTHROPIC_API_KEY=..., then re-run any demo.


Where each requirement lives

# Task Type Location
Part 1 Q1–3 Isolation / RAG fragmentation / LLM failure Screening docs/SCREENING_ANSWERS.md
1 Multi-Portal RBAC Middleware Code src/task01-rbac/
2 Strict JSON Schema Extraction Code src/task02-schema-extraction/
3 Real-Time Inter-Portal Event Chain Design docs/SYSTEM_DESIGN.md
Part 2 Q1–2 OCR ordering / vector isolation Screening docs/SCREENING_ANSWERS.md
4 Layout-Aware Ingestion & Chunking Code src/task04-chunking/
5 Resilient OCR Error Handling Code src/task05-ocr-sanitize/
6 Secure Document Signing & Storage Design docs/SYSTEM_DESIGN.md
Part 3 Q1–2 Surge mitigation / AI rate limiting Screening docs/SCREENING_ANSWERS.md
7 Resilient LLM API Gateway Code src/task07-llm-gateway/
8 Stream Processing / Real-Time Updates Code src/task08-stream/
9 GDPR/FERPA Data Lifecycle Design docs/SYSTEM_DESIGN.md
Part 4 Q1–2 Double-submit / context cost Screening docs/SCREENING_ANSWERS.md
10 Async Batching & Coalescing Wrapper Code src/task10-coalescing/
11 Real-Time Token Budgeting Gateway Design docs/SYSTEM_DESIGN.md

Full design rationale for every code task — what's happening, alternatives considered, and why I rejected them — is in docs/DEEP_DIVE.md.


What each code task demonstrates

  • Task 1 — RBAC / IDOR. Identity from a server-validated session (never a client header); a pure object-level authorization policy; 404-not-403 to prevent id enumeration; defense-in-depth row re-check.
  • Task 2 — Schema extraction. Forced tool-use for API-level schema constraint, Zod re-validation as the trust boundary, one self-correcting retry, and a safe fallback so the promise never rejects.
  • Task 4 — Chunking. Sentence-atomic packing (never severs a sentence), token-based budgeting, overlap, recursive hard-split fallback, and exact vector-DB-ready metadata.
  • Task 5 — OCR. Code-point sanitisation + exposed-JSON stripping, a content- quality score, and a confidence-and-structure-gated fallback ladder (passthrough → local cleanup → LLM reconstruct).
  • Task 7 — Gateway. Exponential backoff with jitter, transient-only retries, fail-fast on 4xx, cheaper-model fallback, and an attempt-trail error.
  • Task 8 — Streaming. HMAC pseudonymisation (+ AES-GCM option), pub/sub fan-out (Redis-swappable), per-owner channel isolation, SSE transport with validated input and leak-free cleanup.
  • Task 10 — Coalescing. Batch-by-size-or-time, identical-request coalescing, safe result mapping, mid-flush batch rotation, and a dispatch timeout.

Project structure

src/
  common/llm/         Provider abstraction: interface, Anthropic, mock, scripted, factory
  task01-rbac/        Express RBAC endpoint + pure policy + repository
  task02-schema-extraction/  Forced-tool extraction + Zod schema + safe fallback
  task04-chunking/    Recursive sentence-aware chunker + tokenizer
  task05-ocr-sanitize/  Sanitizer + quality scorer + strategy-fallback pipeline
  task07-llm-gateway/ ResilientLLMGateway (backoff/jitter/fallback)
  task08-stream/      crypto + pubsub + broadcaster + SSE server
  task10-coalescing/  RequestCoalescer (batching + coalescing)
tests/                Vitest suites (one per code task, 49 tests)
docs/                 SCREENING_ANSWERS.md · SYSTEM_DESIGN.md · DEEP_DIVE.md

Each task folder has a demo.ts runnable via the npm run demo:* scripts.


Key decisions & trade-offs (summary)

Decision Why Rejected alternative
TypeScript (strict) Type guardrails at the untrusted boundaries this assessment is about; pairs with Zod for runtime validation Plain JS (loses the guarantees)
Thin LLMProvider abstraction over Anthropic Offline-testable resilience/batching; one-line model fallback; normalised errors Direct SDK calls (untestable); LangChain (hides the mechanics being probed)
Mock-first, real services behind flags npm test runs instantly with no keys/Docker; interfaces keep the swap honest Docker Compose default (higher bar to run)
Forced tool-use + Zod (Task 2) Schema constrained at the API and re-validated locally Prompt-for-JSON + regex parse (brittle)
Sentence-atomic, token-sized chunks (Task 4) Severing is impossible by construction; sizes match vector limits Fixed character windows (the cause of the problem)
Backoff with jitter (Task 7) Prevents synchronised thundering-herd retry storms Plain exponential (clients retry in lockstep)
HMAC pseudonymisation (Task 8) Irreversible, stable, correlation-only — no raw id on the wire Sending raw ids; reversible encryption when not needed

The full version of this table, with the reasoning for every task, is in docs/DEEP_DIVE.md.


How AI was used (and validated)

The brief evaluates how well generated code is validated and production-proofed. That loop is part of the deliverable: the implementation was AI-assisted, then put through a multi-lens adversarial review (security, concurrency, spec-coverage, production-readiness, TypeScript) with each finding independently verified before fixing. Ten confirmed findings were applied — including replacing an ad-hoc crypto KDF with HKDF + production secret enforcement, adding a dispatch timeout to the coalescer, Zod-validating the streaming endpoint, isolating a throwing retry callback, and closing an SSE listener leak. Details in docs/DEEP_DIVE.md §1.5.


Environment & configuration

All configuration is optional — see .env.example. Highlights:

  • LLM_PROVIDER — mock (default) or anthropic.
  • ANTHROPIC_API_KEY — required only when LLM_PROVIDER=anthropic.
  • LLM_PRIMARY_MODEL / LLM_FALLBACK_MODEL — gateway model tiers.
  • STUDENT_ID_HMAC_SECRET — pseudonymisation/encryption secret. A dev default is used when NODE_ENV !== production; in production it is mandatory (the app refuses to fall back to a built-in value).

No real secrets are committed; .env is git-ignored and .env.example documents every variable.


Requirements

  • Node.js ≥ 20 (uses node:crypto HKDF, randomUUID, native fetch via the SDK).
  • npm 9+ (package-lock.json is committed for reproducible installs).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages