Capstone: A Complete, Working Flexible-Routing Site

Website Rebuild with Astro

Chapter 12 · Capstone: A Complete, Working Flexible-Routing Site

Sam — the same site admin persona from every capstone in this series, reused a fifth and final time — logs into this course's own deployed Astro 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 five-framework Website Rebuild series.

Step 1 — Visiting the Live Deployment

Sam opens the site. Apache's own mod_proxy_http forwards the request to the standalone Node server, kept alive under PM2's own supervision on the same already-live Apache the site has always run behind.

Step 2 — Logging In

Sam enters the legacy admin credential. @auth/astro's own Credentials provider runs its authorize() callback, and bcryptjs — the identical package the Next.js rebuild already used — verifies it against the stored $2y$-tagged hash with no configuration needed.

Step 3 — Building the Five-Level Chain

Through the hand-built admin interface — no free admin, no scaffold generator, the most minimal starting point of all five siblings — Sam creates programming, then general-purpose-languages, then java, then fundamentals, then chapter-1. Each save calls Chapter 2's own explicit computeFullPath helper, since Drizzle has no lifecycle hooks to do it automatically.

Step 4 — Viewing the Page

Visiting the full five-segment path, Chapter 3's [...path].astro resolves it with a single Drizzle query — no getStaticPaths() anywhere — and Chapter 4's PageLayout renders the breadcrumb and set:html={page.body} content, styled by Chapter 5's dark theme.

Step 5 — Editing the Title, Now Actually Protected

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 getSession(request) check 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.

Step 6 — Reorganizing: Paying the Real Cascade Cost

Sam decides fundamentals belongs under a different parent. Chapter 10's movePage updates fundamentals' own fullPath first, then updateDescendantPaths recurses down and updates chapter-1's path too — the real payment of the cascade cost Chapter 2 deliberately deferred at the very start of the course.

Step 7 — Attempting to Delete a Page With Children

Sam tries to delete java, which still has fundamentals beneath it. Chapter 2's onDelete: 'restrict' database 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 own capstone needed, not Rails' smoother built-in path.

Step 8 — Confirming the Kanji Migration Held Up

Sam visits the kanji page. Chapter 7's resolution holds on both fronts: the routing and rendering were already solved by Chapters 2 and 4, and JavaScript's own UTF-16 string model — the same one Next.js already relied on — never risked corrupting the character. The database's own utf8mb4 charset, set explicitly on the mysql2 connection since no automatic default existed here, stores it correctly.

Step 9 — A Quick N+1 Sanity Check

Sam checks the query log while loading the breadcrumb-heavy Chapter 1 page. Chapter 6's db.query.pages.findFirst({ with: ... }) is doing its job — the same deliberately-planted N+1 pattern caught a fifth time, resolved via Drizzle's own relational API, verified as genuinely mirroring Prisma's own include.

Step 10 — Confirming the Deploy Itself Is Healthy

Sam confirms PM2 shows the Node process running cleanly, and that Apache's own mod_proxy_http is forwarding requests correctly — the last confirmation in a series that has now rebuilt the same real site five separate times.

Chapter Attribution

StepChapter(s) Applied
1. Visiting the deployment11 — Deployment
2. Logging in9 — Admin Authentication
3. Building the five-level chain2 — URL & Content Model, 10 — Admin CRUD
4. Viewing the page3 — Routing, 4 — Views, 5 — Styling
5. Editing the title8 — Dynamic Content & Forms, 9 — Admin Authentication
6. Reorganizing2 — deferred cascade cost, 10 — movePage
7. Delete refusal2 — onDelete: 'restrict', 10 — Admin CRUD
8. Kanji migration7 — Rendering Content & the Kanji Edge Case
9. N+1 sanity check6 — The Database: Drizzle ORM
10. Deploy health check11 — Deployment

Honest Scope Note

What this course deliberately doesn't cover
  • 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
Astro's own honest contributions to this series
Two genuinely Astro-specific findings, grounded in real, verified facts: the TypeScript circular-reference workaround Drizzle's self-referencing schema needs (Chapter 2), and mod_proxy_http as a genuinely third distinct Apache deployment mechanism (Chapter 11) — alongside real, direct reuse rather than manufactured uniqueness, where it was honest to reuse: the identical bcryptjs package and the identical Auth.js library the Next.js rebuild already used (Chapter 9).

The Website Rebuild Series Is Now Complete

Five frameworks, one real site, rebuilt five separate times: Next.js, Django, Laravel, Ruby on Rails, and now Astro. 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.

Hands-On Exercises

Exercise 1

Trace Step 6's reorganization through the code: what does movePage() update first, and what does updateDescendantPaths() update afterward?

📄 View solution
Exercise 2

Explain 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 solution
Exercise 3

Name two genuinely Astro-specific findings from this course — not shared with any sibling — and explain the real technical fact each one is grounded in.

📄 View solution

Course Complete

  • 12/12 chapters — Website Rebuild with Astro is now complete
  • Standout findings named honestly throughout — Drizzle's TypeScript workaround (Ch2), genuine Prisma kinship (Ch6), the literal same Auth.js library as Next.js (Ch9), a third Apache mechanism (Ch11)
  • Real limits named honestly too — no built-in validation or CSRF protection (Ch8), no free admin or scaffold generator (Ch10)
  • Fifth and final course in the Website Rebuild series — alongside Next.js, Django, Laravel, and Rails
  • The entire five-framework Website Rebuild series is now complete