URL Shortener Tutorial · Module 11 of 11

Capstone & Review

By the end of this tutorial you'll have a polished, public, portfolio-grade repo: clean code, a strong README with an architecture diagram, an ADR log, a 5-minute walkthrough video, and an explicit open-source license.

~3–4 hrsREADMEADRsDemoLicense
← Back to Module 11 overview
Definition of Done

What You'll Have

  • A self code review pass — issues found and fixed.
  • A self security review against your threat model — issues found and fixed.
  • A polished README.md with hero blurb, architecture diagram, run-locally section, contributing notes.
  • 5–10 ADRs under docs/adr/.
  • A 5-minute demo video linked from the README.
  • A LICENSE file (MIT or Apache-2.0 recommended).
The Steps

Polish It

STEP 1

Self code review

Open your repo in your editor and walk every file. Look for:

  • Dead code, commented-out blocks, leftover console.log.
  • Weak names — data, tmp, foo. Rename to what they actually are.
  • Functions over ~30 lines. Split if there's a clean seam; leave alone if not.
  • Missing tests for new branches you added late.
  • TODOs that are real — file them as issues; delete the ones that aren't.
  • Inconsistent error handling — one place does throw, another does return null.

Track findings in a checklist; fix them in a single PR.

STEP 2

Self security review

Walk your docs/threat-model.md from Module 09. For each threat, find the test or code that mitigates it. If something doesn't have a test, add one.

  • Run npx gitleaks detect on full history.
  • Run npm audit --omit=dev; fix or document waivers.
  • Confirm curl -I on prod shows expected security headers.
  • Verify ownership tests pass (Module 05); SSRF tests pass (Module 09).
STEP 3

Pick and add a license

npx license mit -o "Your Name" > LICENSE
# or apache-2.0, etc.

Reference: see the Open Source & Licensing deep dive.

STEP 4

Polish the README

Use this skeleton:

# URL Shortener

Production-grade URL shortener built as a learning project.
Live demo: https://<your-app>.fly.dev

## Features
- Anonymous & authenticated short-link creation
- Vanity aliases
- Click analytics with daily rollups
- Per-IP rate limiting
- Cache-aside (Redis), read replica routing, idempotent worker
- Observability: structured logs, Prometheus metrics, OTel traces, SLOs

## Architecture
![architecture](docs/architecture.svg)

## Run locally
```sh
git clone …
cp .env.example .env
docker compose up -d
npm ci
npm run migrate:up
npm run dev      # web
npm run worker   # in another terminal
```

## Tech
- Node 20 / TypeScript / Express
- Postgres 16, Redis 7
- BullMQ for background jobs
- pino, prom-client, OpenTelemetry, Grafana
- GitHub Actions, GHCR, Fly.io

## Docs
- [Design](docs/design.md)
- [Threat model](docs/threat-model.md)
- [SLOs](docs/slo.md)
- [ADRs](docs/adr)
- [Runbooks](docs/ops)

## Demo
[5-minute walkthrough](https://…)

## License
MIT
STEP 5

Draw the architecture diagram

Quickest path: write the diagram in mermaid.live and export an SVG to docs/architecture.svg.

flowchart LR
  U(User) --> CDN[CDN/Edge]
  CDN --> LB[Load Balancer]
  LB --> A1[App #1]
  LB --> A2[App #2]
  A1 & A2 --> R[(Redis)]
  A1 & A2 --> PW[(Postgres primary)]
  A1 & A2 --> PR[(Postgres replica)]
  A1 & A2 --> Q[[BullMQ queue]]
  Q --> W[Worker]
  W --> PW
  A1 & A2 --> OTLP[Jaeger/OTLP]
  A1 & A2 --> PROM[Prometheus]
STEP 6

Write the ADR log

Create docs/adr/0001-pick-typescript.md and similar for each major decision. Template:

# ADR 0001 — Pick TypeScript + Express

## Status
Accepted, 2026-XX-XX.

## Context
Need a stack with strong types, a low operational footprint, and a wide hiring pool.

## Decision
Use Node 20 + TypeScript + Express.

## Consequences
- Most ecosystem support; fast to ship.
- Less type safety than e.g. Rust or Go.
- Will revisit if perf becomes a bottleneck.

Cover: stack, base62 ID scheme, cache-aside vs write-through, JWT vs server sessions, BullMQ vs Postgres-as-queue, Postgres replica strategy, Fly.io vs alternatives, MIT vs Apache-2.0.

STEP 7

Record the demo

5 minutes max. Suggested arc:

  • 0:00 — what it is, in one sentence.
  • 0:30 — architecture diagram walkthrough.
  • 1:30 — create a link, follow the redirect, check stats.
  • 3:00 — show the Grafana dashboard during a small load test.
  • 4:00 — show one chaos drill (kill Redis), explain graceful degradation.
  • 4:30 — wrap with what you'd do next.

Tools: Loom, OBS, or Quicktime. Upload to YouTube unlisted; link in README.

STEP 8

The 10-minute newcomer test

Hand the repo URL to a friend (or a fresh clone on a different machine). They should:

  1. git clone
  2. Read the README
  3. Run the app locally
  4. Hit http://localhost:3000/health

… in under 10 minutes. If they get stuck, the README is the bug. Fix and repeat.

STEP 9

Final commit and announcement

git checkout -b module-11
git add .
git commit -m "module 11: capstone polish — readme, adrs, license, demo"
git push -u origin module-11

Merge to main, tag a release:

git tag -a v1.0.0 -m "v1.0.0 — track complete"
git push origin v1.0.0
gh release create v1.0.0 --generate-notes

Optional: write a blog post per module. One of the highest-leverage things you can do for your future career.

You're Done

Where to Go Next

  • Stretch features: custom domains, link expiration, QR codes, abuse detection, an admin dashboard, a CLI client.
  • Read Designing Data-Intensive Applications by Martin Kleppmann; sketch how you'd scale this to 100B links.
  • Try a harder track: a webhook delivery service, a feature-flag service, or a real-time collaborative tool.
  • Show the work. Push the link to LinkedIn, your portfolio, and a community site (HN/Reddit/Lobste.rs).