ABCsteps lesson path

Milestone: Online Leaderboard Works

Connect frontend, API, and database, then verify that leaderboard data survives beyond a page refresh. Build one artifact, keep one review trail, and make the work easy to inspect later.

Lesson
15
Time
45 min
Access
public lesson

Learning objective

Connect the full stack and test persistence end to end.

Lab outcome

Ship a working leaderboard milestone.

Module milestone

Build a small full-stack leaderboard with persistent data.

Lesson proof workflow

Read, build, then review the evidence.

  1. Vue.js hero workflow iconStep 1ReadStart with Full-stack integration before touching tools.
  2. Node.js hero workflow iconStep 2BuildBuild toward: Ship a working leaderboard milestone.
  3. Cloudflare hero workflow iconStep 3ReviewReview the evidence using Leaderboard logic.

Toolchain

A real milestone connects frontend, API, and persistent state.

These are the practical surfaces used in this lesson. Learn the habit first, then connect it to the wider engineering ecosystem.

Vue.js iconVue.jsInterface

Render leaderboard state clearly.

Node.js iconNode.jsAPI

Move data through a backend boundary.

Cloudflare iconCloudflareDemo surface

Verify the working system through a reachable path.

Proof of work

Leave one inspectable trail from this lesson.

The useful output is not a passive note. It is a small artifact another person can inspect: a working file, a command result, a commit, a screenshot, a README note, or a demo link.

Lesson lab: Ship a working leaderboard milestone.

Tool and platform logos are ecosystem references only: no affiliation, endorsement, interview access, hiring promise, salary promise, or placement guarantee.

Vue.js proof icon

Build

Produce the artifact

Complete the lab and keep the result visible: Ship a working leaderboard milestone.

Node.js proof icon

Record

Save review evidence

Capture what changed, what broke, and how Full-stack integration became clearer through the work.

Cloudflare proof icon

Explain

Write the vocabulary

Use your own words for State persistence and Leaderboard logic; this is what makes the lesson inspectable later.

Skills companies recognize

Translate the lesson into inspectable work language.

This lesson turns one small lab into the language a learner can use in a README, demo note, or technical conversation. The point is not to collect logos; the point is to explain work clearly enough that another engineer can inspect it.

Where this skill appears

Integrated milestones matter because teams trust systems that can be tested end to end.

Full-stack deliveryQA engineeringProduct demos

Ecosystem references

AWS skill ecosystem logoGoogle Cloud skill ecosystem logoMicrosoft skill ecosystem logoGitHub skill ecosystem logoCloudflare skill ecosystem logoOpenAI skill ecosystem logoGoogle skill ecosystem logo

Platform and company logos are ecosystem references only: no affiliation, endorsement, interview access, hiring preference, salary outcome, or placement guarantee.

Vue.js skill proof icon

README line

Name the artifact

Lab proof: Ship a working leaderboard milestone. Connect it to Full-stack integration so the result reads like work, not a passive note.

Node.js skill proof icon

Review line

Explain the stack

Use Vue.js, Node.js, Cloudflare to explain State persistence and what changed between the first attempt and the inspected result.

Cloudflare skill proof icon

Conversation line

Answer with evidence

If a team asks about Leaderboard logic, use this proof line: Show the working leaderboard, the API boundary, the persisted data, and the end-to-end check.

Proof translation

Vue.js proof translation icon

Skill signal

Full-stack integration is the market word. The lesson makes it visible through a small working artifact.

Node.js proof translation icon

Proof artifact

The inspectable artifact is: Ship a working leaderboard milestone.

Cloudflare proof translation icon

Interview answer

Use State persistence and Leaderboard logic to explain what changed, what failed, and how you verified it.

Paid guidance

Read publicly. Upgrade when guidance will help you finish.

This lesson remains part of the public written syllabus. Paid help is online-only and human-led: video walkthroughs as they roll out, live class context, WhatsApp Q&A, and project review around the same work.

No account wall, automated checkout, or placement promise is introduced here. Enrollment stays human-led by WhatsApp or call, and the useful proof remains the learner's own artifact.

Vue.js paid guidance icon

Public

Written lesson stays open

Read the prepare and review material for lesson 15 on the public site before buying anything.

Node.js paid guidance icon

Recorded

Recorded and live guidance clarify the work

Paid guidance can add founder-led video walkthroughs as they roll out and live online class context; the teaching explains the work, but does not replace the written lesson.

Cloudflare paid guidance icon

Human

Questions use real context

When stuck, useful guidance starts from the route, error, screenshot, repo fragment, and the lab artifact: Ship a working leaderboard milestone.

Phase 1 · Briefing

Lesson briefing

Before You Study (5 mins)

Lesson focus: Module C taught four things: AI products are API systems (Lesson 11), the frontend-backend boundary (Lesson 12), build your own REST API (Lesson 13), persist data with SQLite (Lesson 14). Today is the closing verification ritual — same shape as the Module B milestone, deeper system. By the end, your Snake game's real-time leaderboard works end-to-end: a player on one phone scores 1,200, a player on another phone refreshes the leaderboard, sees the new entry. That round-trip — phone → public URL → your container → your API → your database → back — is what every full-stack engineer ships, and you've now built every piece of it.

What you should have ready:

  • Your full-stack system from Lessons 11-14: frontend (Snake game), backend (Express API), database (SQLite)
  • Cloudflare Tunnel from Lesson 07 (or running again) to expose the system publicly
  • Two devices ready — your laptop and your phone (or two phones)
  • About 60 minutes
  • One friend you can text the URL to — the social verification matters

The Concept

A full-stack milestone verifies that all the layers compose. Software engineering rewards composition: each lesson taught one piece in isolation; the milestone proves the pieces hold their shape when assembled. The pieces:

text
       ┌──────────────────┐                      ┌──────────────────────────────┐
       │  Phone / browser │  HTTPS / JSON        │  Your laptop                 │
       │  (frontend)      │ ─────────────────▶   │                              │
       │  Snake game      │                      │  Cloudflare Tunnel           │
       │  HTML/CSS/JS     │                      │  ────────────                │
       │                  │                      │  Docker container            │
       │                  │                      │  ────────────                │
       │                  │                      │  Express API (port 3001)     │
       │                  │                      │  ────────────                │
       │                  │                      │  SQLite (./data/scores.db)   │
       └──────────────────┘                      └──────────────────────────────┘
              │                                            │
              │ ◀────────────── leaderboard JSON ──────────┘
              ▼
       Player sees scores
       from everyone

Eleven lessons of work — Lessons 01 through 14 — collapsing into a single 200-millisecond round-trip when a phone in Mumbai requests /api/scores and gets back JSON containing scores written from a laptop on the other side of the room.

The discipline of a milestone is not "build something new." It is verify what you built actually works on a network you don't control. Three things commonly fail at this point and won't be obvious until you check:

  1. The CORS configuration that worked locally may block the production domain. Your dev machine accepts http://localhost:3000; the real frontend now runs on https://your-tunnel.trycloudflare.com. The cors middleware needs to permit it.
  2. The database file lives inside the Docker container. If the container restarts, the data may or may not persist depending on whether you mounted a volume. Production-grade systems use Docker volumes (-v ./data:/app/data); demo systems often forget and lose data on every container restart.
  3. The LLM API key that lives in your local .env may not be inside the Docker container. Container builds don't copy .env by default (and shouldn't — secrets shouldn't bake into images). The right fix is to pass them at runtime: docker run -e GEMINI_API_KEY=....

Each of these three things is a real gotcha that catches every full-stack newcomer the first time. Hitting each of them once is part of the lesson.

The other thing milestones do is make the work shareable. By the end of Module C, you have a system worth showing — a real leaderboard, multi-user, public, persistent. The artefacts you produce today become the second portfolio entry of the course (after the Module B milestone). Two milestones into the curriculum, you have shipped more end-to-end software than most CS undergraduates ship in three years.

Quick Concepts

TermSimple Meaning
End-to-end testVerify the full path from user input to system output, on a real environment
Docker volumeA directory mounted from the host into the container so data survives container restart
Environment variableA runtime configuration value (process.env.X) injected without baking into the image
Race conditionTwo requests arriving close enough in time that they interfere — relevant for high-write systems
Multi-userMore than one person using the system at the same time, seeing each other's data
Portfolio artefactA piece of your work that exists outside your laptop and can be shared with one URL

What We Will Build

By the end of this lesson, you will have done these specific things:

  1. Verified the local dev stack — Snake game on http://localhost:3000, API on http://localhost:3001, calls succeed, scores persist across server restart. Run curl -s http://localhost:3001/api/scores | jq . — see real data.
  2. Added a leaderboard UI to the Snake game — a sidebar or modal that shows the top 10 scores by score DESC. Update the leaderboard:
    • On page load (initial render).
    • Every 30 seconds via setInterval (so a player on one device sees scores from another player without manual refresh).
    • Immediately after the player's own score is submitted.
  3. Containerized the backend with the database persistence baked in. Update your backend's Dockerfile:
    dockerfile
    FROM node:20-alpine
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci --only=production
    COPY . .
    RUN mkdir -p /app/data
    EXPOSE 3001
    CMD ["node", "server.js"]
    

    Build the image: docker build -t snake-backend .
  4. Ran the container with a mounted volume so the SQLite file survives container restart:
    bash
    docker run -d \
      --name snake-backend \
      -p 3001:3001 \
      -v $(pwd)/data:/app/data \
      -e GEMINI_API_KEY=your_real_key \
      snake-backend
    

    Stopped and restarted the container; verified scores persisted.
  5. Tunneled both services — frontend on port 3000, backend on port 3001. Two terminal tabs:
    bash
    cloudflared tunnel --url http://localhost:3000     # frontend tunnel
    cloudflared tunnel --url http://localhost:3001     # backend tunnel
    

    Got back two *.trycloudflare.com URLs.
  6. Updated the frontend to point at the public backend URL instead of http://localhost:3001. Updated the backend's CORS to permit the public frontend URL.
  7. Loaded the public frontend URL on your phone over mobile data. Played the game. Watched the score POST to the public backend, saved to SQLite inside the container running on your laptop, then read back via GET when the leaderboard refreshed. Felt the round-trip.
  8. Sent the URL to a friend. They played the game. Their score appeared in your leaderboard. You played again; they refreshed; they saw your new score. The system is now multi-user.
  9. Wrote the second MILESTONE.md — what you built, what you verified, who played, what surprised you. This becomes the second portfolio entry alongside the Module B MILESTONE.md.

The "felt the round-trip" in step 7 is the moment that matters. Until then, full-stack is a diagram; after it, full-stack is a thing your hands have built.

Think About

Before studying, consider:

  1. The Module B milestone proved your frontend worked from anywhere on the internet. The Module C milestone proves the full system (frontend + backend + database) works for multiple users at once. What further capability would the Module D milestone need to demonstrate? (Hint: AI features, polish, documentation, real users.)
  2. Your leaderboard right now has one obvious vulnerability — anyone can submit any score they want, including 999,999,999. Your validation rejects negative numbers but not absurdly large ones. What real-world products do to defend against this? (Hint: server-side game-state validation, rate limits, signed receipts. The defense is technical and social — and once you ship something with users, you start caring about it.)

By the End

After this lesson, you'll:

  • Have a leaderboard UI that updates live (every 30 seconds + immediately after submission)
  • Have your backend containerized with a mounted volume so data persists
  • Have both frontend and backend tunneled with public HTTPS URLs
  • Have CORS configured for the production origin (not just localhost)
  • Have played the game on your phone, scored, and watched it appear in the leaderboard
  • Have a friend's score appear in your leaderboard — the multi-user moment
  • Have a second MILESTONE.md capturing the achievement
  • Be ready for Module D — adding AI features and polish to the system you just built

Module C composes. Eleven lessons, one running system, real users. 🔗