Invite-only

Classroom Glen

Structured courses, an AI study buddy, and exam-style assessment with AI-assisted marking.

A private learning platform for VCE students. Invite-only, built to production standards.

what the platform serves sample routes
  • GET /healthzok
  • POST /api/auth/loginPBKDF2 · signed cookie
  • GET /api/me/enrolmentsthe caller’s own courses
  • POST /api/tutor/conversations/:id/messages/streamSSE stream
  • GET /api/operator/statusoperator only

What it is

A small platform, run like a real one

Classroom Glen is an invite-only learning platform for VCE (Victorian Certificate of Education) students in Australia. Students get structured courses, an AI study buddy, and exam-style assessment with AI-assisted marking. Parents get oversight, activity emails and study plans.

It was built multi-tenant and data-driven from day one, so growing means switching on signup and billing, not a rewrite. One active cohort today.

See how it is built →

Courses · versioned content packs

VCE General Mathematics, Units 1 & 2 13 modules · 158 sessions
VCE Mathematical Methods, Units 1 & 2 24 modules · 248 sessions
VCE Business Management, Units 3 & 4 exam technique · 37 sessions

All courses are enrichment, written with original problems and marking keys. No publisher or VCAA material is hosted, and no formal VCE enrolment is implied.

Feature highlights

Everything a serious study platform needs

Course delivery, AI tutoring, exam workflow and parent oversight. Each one gated, capped and logged.

Structured course player

Sequenced sessions with worked examples, checklists and exam-style problems. Mathematics is typeset with KaTeX.

A study buddy that knows the subject

Maths Buddy and Business Buddy: a subject-aware tutor on Claude Haiku that streams replies live over SSE. Every conversation is consent-gated, capped and logged.

Exam workflow, end to end

Timed papers served as PDFs from R2 behind signed URLs (≤120 s), capped attempts, and photo upload of handwritten work.

AI-assisted marking

Multi-dimension marking on Claude Opus with a confidence-gated auto-release. Low-confidence marks queue for human review, and students can appeal.

Parents see what matters

A multi-guardian model (M:N) with 10 per-guardian permission toggles, per-course activity emails, and parent-owned study plans with reminders.

A safety net, not an afterthought

A safety pre-pass on every tutor turn, a crisis-flag sweep, and an operator triage queue.

One console to run it all

An 8-tab operator portal: dashboards, people, courses, exam provisioning, grading and appeals, privacy and DSAR queues, ops health, cost rollups.

Privacy tooling built in

A consent ledger, data export (DSAR), a scheduled deletion purge, and a PII-free audit log holding ids and hashed emails only.

By the numbers

Small platform, production discipline

440+
Sessions across 3 courses and 74 modules
90+
Exam-style assessments with marking rubrics
20
Database migrations, zero rewrites
31
Server test files, including a tenant-isolation and IDOR matrix
≤120 s
Signed URL lifetime for every private file
100%
AI calls made server-side, zero API keys in the browser

Architecture

The whole platform, on the edge

One Worker holds all the server logic. Everything inside the dashed boundary is a managed Cloudflare primitive; outside it sit the browser and the two external services the Worker calls.

Hosting and compute Storage Async and scheduled Client and external services
hover or focus a node to trace its wires
Classroom Glen system architecture The browser loads a React single-page app from Cloudflare Pages and calls same-origin /api/* routes on a Cloudflare Worker running Hono, the only server logic. One dashed boundary encloses all seven managed Cloudflare primitives: Pages, the Worker, Cron, KV, D1, R2 and Queues. Inside the Worker sits the deny-by-default canExercise gate, and a denial returns a plain 404. The student-scoped store reads leave from the gate itself: SQL against D1, the relational source of truth for users, sessions, courses, grades, consents and the audit log, and signed URLs of at most 120 seconds against private R2 buckets. The KV session cache and rate-limit counters are not student-scoped, so that wire leaves the Worker above the gate and never touches it. Below the gate, three more wires clear it entirely: marking jobs are enqueued on Cloudflare Queues and consumed by the Worker itself, the Worker calls Anthropic Claude directly using Haiku for the tutor and the safety pre-pass and Opus for marking and appeals, and the Worker calls Resend for email. An hourly Cron trigger drives invite expiry, deletion purge, activity emails, study reminders, the crisis sweep and encrypted backups. CLOUDFLARE CLIENT EXTERNAL SERVICES loads the SPA /api/* cache · not gated SQL · student-scoped signed URLs ≤120 s enqueue · consume server-side AI calls email hourly triggers Browser students parents the operator Cloudflare Pages static assets · React SPA app.classroom-glen.website Cloudflare Worker Hono · TypeScript /api/* · /healthz canExercise() gate every student-scoped read deny by default → 404 the only server logic Cloudflare Cron hourly invite expiry · deletion purge activity emails · reminders crisis sweep · backups Cloudflare KV not the source of truth session cache · rate-limit counters Cloudflare D1 SQLite at the edge users · sessions · courses grades · consents · audit log Cloudflare R2 private buckets only content packs · uploads · papers signed URLs · ≤120 s lifetime Cloudflare Queues async AI marking · dead-letter consumed by the Worker Anthropic Claude server-side only Haiku · tutor + safety pre-pass Opus · marking + appeals Resend SPF · DKIM · DMARC verification · activity email · alerts

Scroll the diagram sideways to see the storage and service columns.

The gate lives inside the Worker, and the wires show it: the student-scoped store reads leave from the gate itself, deny by default, and a denial is indistinguishable from “not found”: a plain 404. The KV session cache and rate-limit counters are not student-scoped, so that wire leaves above the gate and never touches it. Marking jobs go on a queue that the Worker consumes itself, so nothing but the Worker calls Claude.

Explore the interactive diagram →

Tech stack

One job each

Seven managed Cloudflare primitives carry the platform. Two outside services are called from the Worker, and never from the browser: Anthropic Claude and Resend. The last row is the test toolchain, which runs on the same workerd runtime the platform deploys onto.

Cloudflare WorkersAPI and all server logic (Hono + TypeScript)
Cloudflare PagesReact SPA (Vite + TypeScript + Tailwind)
Cloudflare D1Relational truth, 20 migrations
Cloudflare R2Private blobs, signed URLs ≤120 s
Cloudflare KVSession cache and rate limits
Cloudflare QueuesAsync AI marking, dead-letter queue
Cloudflare CronHourly housekeeping and backups
Anthropic ClaudeHaiku for tutor and safety, Opus for marking and appeals
ResendEmail: verification, digests, alerts
Vitest + MiniflareTests run on the same workerd runtime that deploys

Privacy and security by design

The rules the platform cannot break

Classroom Glen handles children’s data. These are not policies pinned to a wall, they are invariants enforced in code, on every request.

01

Deny by default

Every student-scoped read passes the permission gate canExercise(actor, student, permission) before anything is returned. Denials are indistinguishable from “not found”, a plain 404, so there is no way to enumerate what you cannot see.

02

Consent is anchored

AI processing, email and accounts each need explicit guardian consent, re-checked on every send and every turn, not just at signup.

03

AI is server-side, capped and logged

Every tutor and marker call goes through consent, then spend caps, then per-student daily caps, then a safety pre-pass, and lands in an AI processing ledger.

04

The audit log is PII-free

IDs and hashed emails only. The record of what happened never becomes a second copy of who it happened to.

05

Nothing public in storage

Every file lives in a private bucket, reachable only through a signed URL that expires within 120 seconds.

06

Secrets never touch git

Secrets live in the deployment secret store. Sessions use PBKDF2 with signed cookies, and the operator signs in with a password plus TOTP.

07

Children’s data is a liability, not an asset

Export and deletion are first-class flows, backups are encrypted, and there is no analytics or tracking script on any page, including this one.