Skip to content

Work / Learning Platform / Architecture

Learning Platform architecture

A website and one API, both on Vercel. The API keeps accounts and progress in Postgres, and reads every lesson from the instructor's GitHub repo each time a student opens it. No bill is recorded anywhere.

last verified 2026-10-30

Known cost a month
$0–20
Vercel Hobby is free, Pro is $20 a seat. Which plan runs, and the database host, are not recorded.
What makes cost grow
Lesson views
Each view makes one GitHub call per slide or phase, with no cache. Function time, database size and email also grow.
Second limit
100 / 15 min
Requests per address. A fast student or a class behind one address can get 429s.

How it fits together

Pick something a user does to see its path and what it costs.

In the browserVercelOutside servicesWebsiteWebsiteNext.js 16, the student and instructor screensNot readAPIAPINestJS and GraphQL, one serverless function · 30 s maxVercelPostgresPostgresAccounts, enrolments, progress, answers, course metadataHost unclearGitHubGitHubHolds every lesson, slide and question as filesFree APIAWS SESAWS SESVerification, reset and welcome emailsNot readGoogle and GitHub sign-inGoogle and GitHub sign-inOptional sign-in with a provider$0 (free tiers)
No bill read
one GitHub call per slide or phase, on every view
  1. The browser asks the API for the lesson.
  2. The API reads the lesson list from Postgres.
  3. For each slide and phase it fetches the file from GitHub, all at once. Nothing is cached.
  4. A missing file comes back empty. Any other GitHub error fails the whole lesson.
  5. The text goes to the browser. It is never stored in Postgres.

Cost

Every number says where it came from.

ServicePays forTodayGrows withBasis
WebsiteNext.js 16, the student and instructor screensNot readPage views and build minutesNot known
APINestJS and GraphQL, one serverless function · 30 s max$0 on Hobby, $20 a seat on Pro; plan not recordedFunction time: every request, every lesson readStatedprevious wiki/concepts/architecture.md; no bill read
PostgresAccounts, enrolments, progress, answers, course metadataNot readStudents, answers, database sizeNot known
Google and GitHub sign-inOptional sign-in with a provider$0 (free tiers)NothingStatedprevious wiki/concepts/architecture.md; no console read

What breaks when something fails

If this failsThe user seesTheir dataBasis
WebsiteNo site. Nothing else is affected.Safe, held by the API and PostgresAssumedThe website holds no data of its own; apps/website/vercel.json
APISign-in, lessons and answers all stop. A failed start is retried on the next request.Safe in PostgresIn codeapps/server/api/index.ts ensureReady; apps/server/vercel.json maxDuration 30
GitHubLessons open without their text, or the page errors if GitHub answers with a failure other than 'not found'. A sync fails and shows 'Sync failed'.Content is safe in the repo. Metadata stays in Postgres.In codeapps/server/src/lib/git/git.service.ts fetchContentBase64; curriculum.service.ts runSync

Where the data goes

Lesson text, slides, questions, codeThe instructor's GitHub repo. Read live, never stored.
Email addressesSent to AWS SES for each email
BackupsProvider snapshots; no backup was checked

What we do not know yet

  • The real monthly bill: no Vercel, database or SES cost is recorded.
  • Which Postgres host holds production. The runbooks name Supabase and Neon; .context/ops/release.yml says provider null.
  • Which Vercel plan runs. vercel.json asks for a 30 s limit, but the runbook says Hobby is capped at 10 s.
  • The wiki and runbook still say lesson text is cloned to /tmp and lost on a cold start, with task 5.10 pending. The code now reads each file through GitHub's API and has no clone. The docs are out of date.
  • Whether SES is out of its sandbox. This decides whether email verification can be turned on.
  • A reset email can fail with no sign to the user, and no alert exists. Error tracking was skipped (task 5.6); only Vercel logs.
  • How many users exist. No count or traffic figure is recorded, so no growth chart is drawn.
  • No test suite, by decision. Nothing checks the flows above.
  • Whether backups are on and have been restored. The runbook asks for a drill each quarter; none is recorded.