Capstone: A Complete, Working Flexible-Routing Site
Website Rebuild with Express
Chapter 12 · Capstone: A Complete, Working Flexible-Routing Site
Sam — the same site admin persona from every capstone in this series, reused a sixth and truly final time — logs into this course's own deployed Express version. Every step below draws on a specific earlier chapter, closing with an attribution table, an honest scope note, and the close of the entire six-framework Website Rebuild series.
Sam opens the site. Apache's own mod_proxy_http forwards the request to server.js, kept alive under PM2 — the identical mechanism Astro's own capstone already confirmed, reused honestly rather than reinvented.
Sam enters the legacy admin credential. bcryptjs — the same package verified in this series for a third time — checks it against the stored $2y$-tagged hash, and express-session establishes a real session on success.
Through the hand-built admin interface — no free admin, no scaffold generator, matching Astro's own most-minimal finding — Sam creates programming, then general-purpose-languages, then java, then fundamentals, then chapter-1. Each save calls Chapter 2's own computeFullPath helper directly, with no ORM lifecycle hook anywhere in sight.
Visiting the full five-segment path, Chapter 3's /*splat route resolves it with a single raw SQL query, and Chapter 4's EJS partials render the breadcrumb and <%- page.body %> content, styled by Chapter 5's plain, zero-processing stylesheet.
Sam edits the Chapter 1 page's title. Chapter 8's endpoint and Zod validation handle the submission exactly as before — but Chapter 9's requireAuth middleware is now in place, the first genuine "place for an auth check" this course ever had. Logged out, the identical request now returns a 401 instead.
Sam decides fundamentals belongs under a different parent. Chapter 10's movePage updates fundamentals' own path directly, then Chapter 6's own recursive CTE finds every descendant — just chapter-1, here, but genuinely unbounded regardless of how deep the real chain went — in a single query, ordered so one linear pass writes each new path correctly.
Sam tries to delete java, which still has fundamentals beneath it. Chapter 2's ON DELETE RESTRICT constraint refuses the operation, and Chapter 10's try/catch turns the raw database exception into a real, readable 409 response — the same ceremony Laravel's and Astro's own capstones needed, not Rails' smoother built-in path.
Sam visits the kanji page. Chapter 7's resolution holds on every front: routing and rendering were already solved by Chapters 2 and 4, JavaScript's own UTF-16 string model — shared with Next.js and Astro, confirmed a third time — never risked corrupting the character, and the database's own utf8mb4 charset, present in db.js since Chapter 2, stores it correctly with nothing rediscovered along the way.
Sam checks the query log while loading the breadcrumb-heavy Chapter 1 page. Chapter 6's WITH RECURSIVE query resolves the full ancestor chain in one call — genuinely unbounded, the concrete answer to a limitation five separate ORMs in this series each admitted but never actually solved.
Sam confirms PM2 shows server.js running cleanly, with no build artifact anywhere to verify — the last confirmation in a series that has now rebuilt the same real site six separate times.
Chapter Attribution
| Step | Chapter(s) Applied |
|---|---|
| 1. Visiting the deployment | 11 — Deployment |
| 2. Logging in | 9 — Admin Authentication |
| 3. Building the five-level chain | 2 — URL & Content Model, 10 — Admin CRUD |
| 4. Viewing the page | 3 — Routing, 4 — Views, 5 — Styling |
| 5. Editing the title | 8 — Dynamic Content & Forms, 9 — Admin Authentication |
| 6. Reorganizing | 2 — deferred cascade cost, 6 — recursive CTE, 10 — movePage |
| 7. Delete refusal | 2 — ON DELETE RESTRICT, 10 — Admin CRUD |
| 8. Kanji migration | 7 — Rendering Content & the Kanji Edge Case |
| 9. The series' own central finding | 6 — The Database: Raw SQL, No ORM |
| 10. Deploy health check | 11 — Deployment |
Honest Scope Note
- No multi-admin roles or permission levels — a single legacy admin credential only
- No revision history or audit log of content edits
- No media/image upload handling
- No automated tests or CI pipeline
- No internationalization beyond the kanji character-storage edge case itself
- No rate limiting or lockout policy on the login form
- No CSRF protection — a real, unaddressed gap named honestly in Chapter 8, never solved
- No migration tooling —
schema.sqlapplied by hand, a real gap named in Chapter 11
WITH RECURSIVE query, the concrete answer to the fixed-depth limitation five sibling ORMs each admitted but never solved, made possible specifically because no ORM stood between the code and the database; and Chapter 9's requireAuth middleware, a genuine positive finding that Express's own minimalism produces a real, general-purpose extensibility mechanism, not merely an absence of structure.
Hands-On Exercises
Trace Step 6's reorganization through the code: what does movePage() update directly, and how does the recursive CTE plus the linear write pass handle everything beneath it?
📄 View solutionExplain what changed between Step 5 in this capstone and the identical-looking action back in Chapter 8, and name the exact line of code responsible for the difference.
📄 View solutionName two genuinely Express-specific findings from this course — not shared with any sibling — and explain the real technical fact each one is grounded in.
📄 View solutionCourse Complete
- 12/12 chapters — Website Rebuild with Express is now complete
- Standout findings named honestly throughout — the recursive CTE payoff (Ch6), the real cascade limitation stated precisely (Ch10), a genuine positive minimalism finding (Ch9)
- Real limits named honestly too — no CSRF protection (Ch8), no migration tooling (Ch11)
- Sixth and truly final course in the Website Rebuild series — alongside Next.js, Django, Laravel, Rails, and Astro
★ The Website Rebuild Series Is Now Complete — Six Frameworks, 72 Chapters
One real site, rebuilt six separate times: Next.js, Django, Laravel, Ruby on Rails, Astro, and Express. Each course found its own genuine advantages and honest limits rather than declaring any single architecture simply "the best" — the same standard the Food Tracker Quartet set for comparative courses on this site. The series' own single longest-running thread — the breadcrumb's deliberately planted N+1 pattern, caught and fixed by a different mechanism in every course — reached its true conclusion here: five ORMs each admitted the same fixed-depth limitation for an arbitrary-depth ancestor chain, and it took the one course with no ORM at all to finally build the real, unbounded answer.