Project Roadmap
One Project, Many Milestones
The study tracker project of this course is one application that grows over the whole course. You do not create a new project in each part. Instead, you keep extending the same project folder until it becomes the final submission.
Each part adds one bounded capability, so the project grows without becoming too large to understand.
The course also uses a second recurring schema context in many regular chapters: a course-platform schema that supports concept learning and SQL practice. This page is only about the study tracker side. Its purpose is to show how the project schema grows across the course.
Project Structure at a Glance
The project stays in one folder for the whole course. Even though the features change, the main structure stays quite stable:
compose.yamlstarts PostgreSQL and the web application together.start.shwaits for the database, applies migrations, and starts the app.migrations/contains schema and seed SQL files.app/main.pycontains the FastAPI routes.app/db.pycontains the database connection helper.app/migrate.pyapplies migration files in a controlled order.app/templates/contains the Jinja templates used to render HTML.
New migrations and templates are added to those folders as the project grows; the containers themselves stay the same.
You do not need to memorize all of this at once. The important point is that the project keeps the same general shape while the database features become richer.
One Request Through the Project
A small request such as GET /decks usually follows this path:
- the browser sends a request,
- FastAPI matches a route in
app/main.py, - the route opens a database connection through
app/db.py, - PostgreSQL runs the SQL query,
- the route passes the rows to a template,
- and the template renders HTML back to the browser.
That same request path appears again and again later in the course.
Local Workflow in Practice
A typical local development cycle looks like this:
- run
docker compose up --build, - let PostgreSQL become healthy,
- let
start.shapply the migrations, - open the application in the browser,
- make a change to a route, query, template, or migration,
- refresh, re-run, or restart if needed,
- and verify the effect both in the browser and in the database when appropriate.
That is the practical rhythm behind each new or modified feature. You will get more comfortable with it as you go.
How the Project Grows
The project adds one bounded capability at a time. A short summary of each released part follows. Later parts will be added here as they are released.
Part 1: Walking Skeleton
A running application with Docker Compose, PostgreSQL, and one read-only /decks page that renders seeded rows. Guided through the Part 1 checkpoint.
Part 2: Reading More from the Database
One more read-only feature: a /decks/newest page that shows the most recently added deck. Guided through the Part 2 checkpoint.
Part 3: Safe Writes and CRUD
Parameterized queries are introduced, and the project gains a full create, read, update, and delete flow for decks. The chapter-level practice track builds the same CRUD flow for a smaller tags feature. Guided through the Part 3 checkpoint.
Part 4: Relational Features
The project grows from single-table pages to relational ones. cards belong to decks (one-to-many), and card_tags connect cards to tags (many-to-many). The deck detail page shows its cards, and the card detail page shows its tags. The two applied chapters, Chapter 9 and Chapter 10, together play the role of the project checkpoint for this part.
A Useful Habit Throughout the Project
At the start of each new part, ask:
- What already works?
- What is the one new capability for this part?
- How will I know that the capability works from both the browser and the database perspective?
That small checkpoint makes the project much easier to manage over the whole course.