Capstone: A Complete, Working Flexible-Routing Site
Website Rebuild with Next.js
Chapter 12 · Capstone: A Complete, Working Flexible-Routing Site
Sam — the site's own admin — logs in and does one real, ordinary session's worth of work. Every step below draws on a specific earlier chapter of this course, closing with a chapter-attribution table and an honest scope note. Sam is the same recurring persona every one of this course's own five already-complete siblings reuses for its own capstone — this telling of the story is, chronologically, the most recently written of the six, even though it's the very first in the series' own numbering.
Step 1 — Opening the Site
Sam visits the site's own domain. nginx terminates HTTPS (Chapter 11's own certbot certificate) and proxies to the Next.js production server, kept running unattended under PM2.
Step 2 — Logging In
Sam enters the same admin credential the old PHP site always used. NextAuth's authorize() callback runs, and bcrypt.compare() verifies it against the stored $2y$-tagged hash with no special configuration — nothing was ever reset. A signed JWT session is established.
Step 3 — Building the Chain, Live
Through the hand-built admin interface — no free admin panel, no scaffold generator — Sam creates five real pages, one level at a time:
programming(top-level)general-purpose-languages(underprogramming)java(undergeneral-purpose-languages)fundamentals(underjava)chapter-1(underfundamentals)
Five real levels deep — no longer the illustrative example this course opened with in Chapter 1.
Step 4 — Visiting It Live
Sam opens /programming/general-purpose-languages/java/fundamentals/chapter-1 directly. The [...path] catch-all route joins the five URL segments into one string and resolves the page in a single fullPath lookup — no five-level chase. PageShell renders the breadcrumb through Chapter 6's own include-based fix, one query for the whole ancestor chain rather than five separate ones, and the dark theme applies through the single global stylesheet import.
Step 5 — The Kanji Check
Sam creates one more page — 水 — under programming. It saves, routes, and renders through the exact same pipeline as every other page: no special-casing, no depth exception, no separate rendering path. Chapter 7's own verified finding holds: nothing in this pipeline ever slices a path string by index, so it never mattered whether the character needed one UTF-16 code unit or a surrogate pair.
Step 6 — A Safe Edit
Sam edits chapter-1's own title through the now-protected updatePageTitle — Chapter 8's mutation, Chapter 9's auth() check standing in front of it. Loading the page again immediately afterward shows the new title — Chapter 8's own updateTag call guarantees this, not just usually true.
Step 7 — Reorganizing: Paying Chapter 2's Own Deferred Cost
Sam decides java belongs under a new archive section instead. Through the searchable flat-list parent picker, Sam reparents it. movePage's own recursive CTE finds both real descendants — fundamentals and chapter-1 — in one query, and each one's own fullPath is recomputed correctly, in dependency order. The cost Chapter 2 named and deliberately deferred gets paid here, for real, against a real five-level chain — not a toy example.
Step 8 — The Delete Refusal
Sam tries to delete fundamentals, forgetting it still has chapter-1 beneath it. The database's own onDelete: Restrict constraint refuses the raw delete; Prisma surfaces it as P2003; Chapter 10's own try/catch converts it into a real, readable message — not a crashed request.
Chapter Attribution
| Step | Chapter(s) applied |
|---|---|
| 1 — Opening the site | Chapter 11 (deployment) |
| 2 — Logging in | Chapter 9 (legacy-credential-compatible auth) |
| 3 — Building the chain | Chapter 2 (the self-referencing schema), Chapter 10 (the admin interface) |
| 4 — Visiting it live | Chapter 3 (routing), Chapter 6 (the eager-loading fix), Chapter 4/5 (layout, styling) |
| 5 — Kanji check | Chapter 7 (the edge case resolution) |
| 6 — Safe edit | Chapter 8 (the mutation, updateTag), Chapter 9 (the fix that protects it) |
| 7 — Reorganizing | Chapter 2 (the deferred cost), Chapter 10 (movePage, the real payoff) |
| 8 — Delete refusal | Chapter 2 (onDelete: Restrict), Chapter 10 (P2003, caught) |
movePage. Chapter 1's own "bring your own backend" observation becomes Chapter 9's real, hand-configured login. This capstone isn't a new demonstration — it's every earlier chapter's own decision, paying off exactly where it was always going to.
Hands-On Exercises
Explain why visiting the five-level-deep chapter URL in Step 4 only requires one database lookup for the page itself, rather than five, tracing the answer back to a specific design decision made in Chapter 2.
📄 View solutionWalk through Step 7's own reorganization and explain exactly which rows movePage's recursive CTE finds, and in what order they get updated, and why that order matters.
📄 View solutionPick any one row from the chapter-attribution table and explain, in your own words, why that step genuinely couldn't have worked correctly without the specific chapter(s) it's attributed to.
📄 View solutionChapter 12 Quick Reference
- 8 real steps, 11 prior chapters — one realistic admin session, building the exact chain this course opened with, no longer hypothetical
- This course's own throughline, closed out: every step traces to a real, specific decision made earlier — the deferred cascade cost, the array-vs-string routing gotcha, the deliberate auth gap — nothing arbitrary
- Honest scope note: single-admin, no revision history, no media uploads, no automated tests, no i18n beyond kanji, no real search ranking
- Website Rebuild with Next.js is now complete — 12/12 chapters