Lesson Complete!
Rewrite Every Endpoint
What you rewrote
Every CRUD endpoint now uses the database session instead of the in-memory dict:
| Endpoint | Before | After |
|---|---|---|
POST /expenses | counter += 1, dict insert, file write | session.add, session.commit, session.refresh |
GET /expenses | Python loop with optional filter | select(Expense) with optional .where() |
GET /expenses/{id} | if expense_id not in expenses dict check | session.get(Expense, expense_id) |
DELETE /expenses/{id} | expenses.pop(expense_id), file write | session.delete, session.commit |
PATCH /expenses/{id} | dict.update(), file write | sqlmodel_update, session.commit, session.refresh |
The error handling, middleware, and validation are unchanged — those were already correct. Only the storage layer changed.
What comes next
The GET /summary endpoint has a temporary implementation that loops through all expenses in Python. Lesson 3 replaces it with a proper SQL aggregation query — and adds date range filtering and description search to GET /expenses while it's at it.