Thirteen modules, roughly 91 hours, one project that grows every module: a City Guide API with places, tags, users and saved lists.
The rules of the track, then a terminal you can drive, git that isn't scary, Python isolated per project, Postgres in a container, secrets in a file you never commit — and how to read an error instead of pasting it somewhere.
DNS, TCP, TLS and the plain-text HTTP request underneath every framework. Methods, status codes, headers, JSON — then send a request by hand with curl and watch it come back.
FastAPI routing, path vs query vs body, what Uvicorn does that FastAPI does not, full CRUD with real status codes, and your first pytest — all with no database at all, on purpose.
SELECT, JOIN, GROUP BY, keys and constraints, written directly in psql long before an ORM hides them — including indexes and the EXPLAIN ANALYZE output that tells you why something is slow.
Write the ten questions your API must answer, then the SQL for each, and only then the tables. The ER diagram comes last, as documentation of a decision already made.
SQLAlchemy models, the per-request session lifecycle that trips up every beginner, transactions that actually roll back, and Alembic so schema changes stop being manual.
Swap the hardcoded list for the database, separate what comes in from what goes out, and spend most of the module on the unhappy path: 404, 409, 422, the database being down, and the N+1 query you just wrote without noticing.
Hash a password, sign a token, verify it on every request — by hand, with nothing managed and nothing hidden. Then break it four ways on purpose and watch each failure.
Split auth into its own service that signs with a private key and publishes a public one, then rotate keys with no downtime. This is what a managed identity provider does — built locally, so it stops being a black box.
pytest fixtures, a throwaway database per run, testing authenticated endpoints, the difference between a unit and an integration test, and what a coverage number does and does not tell you.
Structured JSON request logs with timing and a request id, a health check that actually checks the database, and config that fails loudly at startup rather than quietly at 3am.
One Dockerfile, one compose file, migrations on boot, a real healthcheck. Your project now starts on a machine that has never seen it — and what a real deploy adds on top, without signing up for anything.
The skill the job is actually made of: a repeatable method for tracing one request through an unfamiliar codebase, the pull request workflow, and a capstone checkpoint you assess yourself.
Document structure, the box model, flexbox and grid, and what the browser actually builds from the bytes your server sent.
The event loop, promises and async/await, fetch, and why the browser is a fundamentally different execution model from your server.
Components, props, state, effects, and the rendering model — plus when a component should not hold state at all.
The module that actually makes this full-stack: CORS and why it exists, where a token may and may not be stored, loading and error states, and what your API's 422 looks like from the other side of the wire.
Validating on both sides and why both are mandatory, mapping server errors onto fields, and optimistic updates that roll back correctly.
What a bundler does, why a build step exists at all, static hosting versus server rendering, and serving a frontend from the same container as your API.