Phase 00
How Modern Full-
Stack Applications
Work
A visual mental model for browsers, frontend
rendering, APIs, business logic, persistence,
authentication and state ownership.
Book 1 · Full-stack mental model
Course baseline: September 17, 2026 · Windows-first · Project-driven · Production-oriented
Contents
1. A request is a journey 7. The API boundary
2. Browser responsibilities 8. State ownership
3. Frontend responsibilities 9. Failure paths
4. Backend responsibilities 10. The complete request lifecycle
5. Database responsibilities 11. Knowledge checks
6. Authentication vs authorization
Phase 00 | Page 2 of 10
A request is a journey through
responsibilities
When a user clicks Create Task, no single framework “does the feature.” Multiple layers cooperate.
Becoming a full-stack developer means understanding that journey well enough to diagnose it when
something goes wrong.
Browser
Next.js frontend
HTTP API request
NestJS controller + service
Prisma data access
Supabase PostgreSQL
Figure 1 - Core application request path - This is the central diagram we will repeatedly expand throughout the
course.
Layer 1: the browser
The browser renders HTML and CSS, runs client-side JavaScript, stores limited client state, sends
network requests, receives responses, enforces web security rules such as CORS, and reports failures
in developer tools. It does not decide authoritative business rules just because it can run code.
Layer 2: Next.js
Next.js is the presentation application. It owns routes, pages, layouts, rendering choices, UI
composition, navigation and interaction. Later it also coordinates client-side server state through
TanStack Query. The course deliberately prevents Next.js from becoming a second backend full of
duplicated business rules.
Phase 00 | Page 3 of 10
Layer 3: HTTP
HTTP is the contract boundary between independently running applications. A request carries a
method, URL, headers and optional body. A response carries a status code, headers and optional
body. This boundary is valuable because the frontend and backend can evolve independently as long
as they honor the contract.
Method Path Headers Body
POST /tasks Auth, Content-Type JSON
NestJS route receives the request
Figure 2 - HTTP request anatomy - The API boundary is explicit; it is not a function call disguised as networking.
Layer 4: NestJS + Fastify
NestJS provides the application architecture for controllers, providers, dependency injection, guards,
interceptors and modules. Fastify is the HTTP platform underneath NestJS in this course. Controllers
translate HTTP into application calls; services own business behavior.
Phase 00 | Page 4 of 10
HTTP request
Controller
Validation / auth boundary
Service business logic
PrismaService
Database
Figure 3 - Backend responsibility chain - Keep controllers thin enough that business rules remain reusable and
testable.
ASP.NET CORE BRIDGE
If you know ASP.NET Core: a Nest controller is conceptually similar to a controller, providers/
services use dependency injection, guards/interceptors overlap with filter/middleware concerns,
and PrismaService loosely occupies the “database access gateway” role that DbContext often
plays. The mapping is useful, but the frameworks are not identical.
Layer 5: Prisma
Prisma is not PostgreSQL. It is the application-facing ORM/data-access layer. It turns model
definitions into typed database operations and manages schema changes through migrations. In our
architecture, Prisma stays behind NestJS so browser code never receives database credentials.
Layer 6: PostgreSQL
PostgreSQL is authoritative persistent storage for application data: users, memberships, projects,
tasks, comments, audit history and other relational records. Supabase hosts PostgreSQL for the
course, but the relational concepts remain standard PostgreSQL concepts.
Phase 00 | Page 5 of 10
Authentication is not authorization
Authentication answers “who are you?” Authorization answers “are you allowed to perform this
action on this resource?” Those questions happen at different points and should remain conceptually
separate.
User signs in
Supabase Auth
Access token (JWT)
Next.js sends Bearer token
NestJS validates token
Service receives trusted identity
Figure 4 - Future authentication flow - Authentication establishes a trustworthy identity before business logic
evaluates permissions.
Later, authorization adds another decision:
Phase 00 | Page 6 of 10
Verified user
Requested action
Membership / role / ownership check
Allowed?
Execute business operation
Figure 5 - Authorization decision - A valid identity is necessary but not sufficient; permissions and resource ownership
still matter.
State ownership
Many frontend applications become difficult because every kind of state is placed in one global store.
The course teaches state by ownership instead.
Server-owned state Client-owned state
TanStack Query Local / URL / Form state
tasks · projects · users · API results dialogs · filters · inputs · navigation
Persistent truth Domain behavior
PostgreSQL Services / optional stores
authoritative business data rules and interaction logic
Figure 6 - State ownership map - Different categories of state deserve different tools and lifecycles.
Phase 00 | Page 7 of 10
Failure paths are part of the architecture
A professional mental model includes failure. Network requests time out. Validation rejects input.
Authentication expires. Authorization denies access. Database constraints conflict. Bugs throw
exceptions. The goal is not to pretend failures are rare; the goal is to know which layer should detect,
translate, log and present them.
Database Prisma Service HTTP
constraint error decision 409
UI message
“Already exists”
Figure 7 - Failure translation - Errors should become more meaningful as they travel toward the user.
Phase 00 | Page 8 of 10
The full lifecycle
User interaction
React / Next.js UI
TanStack Query or API client
HTTP + JWT
NestJS controller
Guard / validation
Service
Prisma
PostgreSQL
Response + cache update
UI re-renders
Figure 8 - Complete vertical slice - This is the mental model you should be able to narrate from memory by the end of
Phase 00.
Knowledge checks
1. Why should Next.js not receive a PostgreSQL password?
2. What responsibility would be lost if all business logic lived in controllers?
3. What is the difference between authentication and authorization?
Phase 00 | Page 9 of 10
4. Where does durable business data live?
5. Why is HTTP useful even when frontend and backend are in one monorepo?
6. Give one example of server state and one example of local UI state.
YOU ARE READY WHEN
You can narrate the request path without memorizing framework slogans: user → UI → HTTP →
controller → service → Prisma → PostgreSQL → response → UI.
Phase 00 | Page 10 of 10