From scattered katas to an app that boots
So far you've solved pieces: a SQL query here, a component there, a validator somewhere else. A real app is what happens when those pieces connect and the data flows between them. In this capstone you build an end-to-end task manager and run it.
A full-stack app is organized in layers, and each layer only talks to its neighbor:
[ UI / React ] the form and the list the user sees
│ calls
▼
[ Client ] asks the API for data and stores what it receives
│ fetch(url, ...)
▼
[ API / routes ] translates each request into a data operation
│ store.create(...)
▼
[ Data / store ] the "database" (here, in memory)
The flow of one action
Adding a task travels through all the layers and comes back:
- The user types and clicks Add (UI).
- The UI calls
client.add(text). - The client does
fetch("/tasks", { method: "POST", body: { text } }). - The API receives the route, validates and calls
store.create(text). - The store saves the task and returns it; the response bubbles back up.
- The client reloads the list and the UI re-renders with the new task.
The key: no layer jumps to one that isn't its neighbor. The UI never touches the store directly; it goes through the client and the API. That's what makes an app maintainable, testable and... actually runnable.