Eleven modules that take you from an empty Git repo to a deployed, observable, secure service — used as a vehicle to practice every major area covered in the deep dives. Each module is a small, shippable increment with concrete acceptance criteria. Finish the track and you'll have a portfolio-worthy project and working knowledge across the stack.
← Back to Learning TracksEvery good system starts with a one-page design doc and a repo that's pleasant to work in. Don't skip this — bad foundations compound.
.editorconfig, .gitignore, and a linter/formatter (ESLint+Prettier, Ruff+Black, etc.).main, require PRs, use short-lived branches.README.md: what it is, how to run it locally.git clone + one command starts the server./docs and links from the README.The smallest interesting slice: shorten a URL, redirect to it, delete it. Get the contract right before you add anything else.
POST /shorten, GET /:code (302 redirect), DELETE /:code.links(id, code, target_url, created_at, owner_id). Write a migration.http/https only).curl -X POST with a URL returns a short code./:code redirects (302) to the original.If your code isn't tested, future-you will be afraid to change it. Build the habit now while the codebase is small.
npm test (or equivalent) runs in under 30s for the unit suite.Reads dominate a shortener — most requests are repeat hits to popular links. Caching is the right hammer.
k6 or Locust — measure p50, p95, p99./docs/perf.Start the Module 04 tutorial →
Anonymous shorteners get abused fast. Add accounts, ownership, and basic rate limits.
Authorization: Bearer middleware.POST /shorten is rejected (or capped to a strict anon quota).Retry-After header.Don't block the redirect to write analytics. Push the work off the request path.
clicks table (or aggregates into rollups).GET /stats/:code — total clicks, by-day, top referrers/UAs.Start the Module 06 tutorial →
You can't fix what you can't see. Instrument the service before you scale it.
"It works on my machine" is a smell. Make build, test, and deploy boring and automatic.
docker-compose.yml for local dev (app + Postgres + Redis + worker).main deploys to production with zero downtime.A shortener is a surprisingly juicy attack surface. Threat-model it before someone else does.
.env.javascript:, file:, and private-IP targets are rejected.curl -I on the public URL shows expected security headers.Now make it survive failure. The interesting questions aren't "how fast?" but "how does it degrade?"
/docs/ops.The work isn't done until someone else can understand it. Polish, document, demo.
/docs/adr) with the 5–10 biggest decisions you made and why.