Validate what comes in, shape what goes out, and give every outcome its proper status code.

So Phase 1 gave my app a memory — a real database that remembers users and expenses even after a restart. Small problem: the only way to actually talk to it was a Python script I ran by hand. The app could remember things, but it was mute. Nobody on the internet could add an expense, list their spending, or delete a typo.

Phase 2 fixes that. This is where the app grows a mouth — real HTTP endpoints you hit through the browser. The buzzword is CRUD: Create, Read, Update, Delete. The four things basically every app does to data. I went in thinking "it's just four functions, how hard can it be" and came out having learned about request/response contracts, dependency injection, and roughly six different HTTP status codes — mostly by triggering them wrong first. Let me dump what I learned [and the parts that tripped me up, because there were, uh, several].

The Structure is as follows. Lets call it PHASE 2 — The Endpoints:

Set up the request/response contracts (two Pydantic schemas: one for input, one for output)