Platform architecture
How the pieces fit: a React application, a domain-structured API, background workers, and managed AWS underneath.
The shape of the system
Three deployed services behind one load balancer, plus the managed data layer. The web application is a static bundle; the API and the worker are separate services so that a long-running generation job can never starve an interactive request.
- Browser/API
- 1Static bundle — API → Browser
- 2REST + Bearer token — Browser → API
- 3Job progress (SSE) — API → Browser
- Within API · Aurora Postgres, Redis queue, S3 objects, background workers
Web application
React with TypeScript, built by Vite and served as a static bundle. Routing is client-side, split into four role-scoped route groups plus the public routes: the guest quiz taker, the phone capture handoff, and this documentation portal.
- Server state is cached and revalidated per query key, so navigating back to a screen does not refetch everything blindly.
- Proctoring runs entirely on-device in a web worker — face and voice signals become abstract flag events; frames and audio never leave the browser.
- The bundle carries no institution-specific content. Branding is configuration, resolved at runtime.
API
An Express application organised by domain rather than by technical layer — each domain owns its router, service, repository and schema.
There are around forty domains, from course and assessment through to ivr and paper-upload. A request enters at a router, is validated against a schema, executes in a service, and touches the database only through that domain’s repository — which is where institution scoping is enforced.
Requests are rate-limited per user and per IP, and LLM-backed endpoints carry a much tighter limit of their own because their cost is measured in tokens rather than milliseconds.
Workers and jobs
Anything that takes longer than a request is a job. The queue is durable across deploys.
Generation work — syllabus extraction, lesson authoring, materials, grading, concept tagging — is submitted as a job and picked up by a worker service. Jobs resume from their last completed gate instead of restarting when a worker is replaced, so a deploy mid-generation costs minutes rather than the whole course.
Progress streams back to the browser, which is why the syllabus screen can show a live, staged view of what the pipeline is doing rather than a spinner.
Data layer
Infrastructure
Everything is defined in Terraform — network, database, compute, storage, identity, WAF, observability and DNS are separate modules, so a change to the certificate policy is reviewable independently of a change to task sizing.
- Containers run on ECS Fargate behind an Application Load Balancer, with per-service autoscaling.
- A WAF sits in front with global rate rules; ALB access logs are retained.
- GuardDuty and CloudTrail are enabled, with alarms routed to a notification topic.
- A wildcard certificate covers per-institution subdomains, so adding a tenant does not require a certificate change.