Nobody has started this yet — be first.
Business impact
A watchlist app's whole value is letting you glance at what you just added. Right now GET /api/movies returns the user's oldest entries first. For anyone with more than a page of movies, the thing they added five seconds ago is buried at the bottom of the last page instead of sitting at the top -- every session starts with "did my add actually work?" followed by paging all the way to the end to check. It's the kind of bug that doesn't crash anything, just quietly makes the app feel broken and unpolished from the very first real use.
Problem
POST three movies in a row, then GET /api/movies -- the response's items list comes back oldest-created-first (ascending by created_at), not newest-first.
Current behavior
A freshly created movie entry shows up at the bottom of the list instead of the top, and the effect compounds with every page a user has.
Expected behavior
GET /api/movies must return the current user's movies newest first -- the most recently created entry at index 0 -- regardless of watched filtering or pagination page.
Steps to reproduce
curl -s -X POST localhost:5000/api/movies -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json" -d '{"title": "Oldest"}'
curl -s -X POST localhost:5000/api/movies -H "Authorization: Bearer $TOKEN"
-H "Content-Type: application/json" -d '{"title": "Newest"}'
curl -s localhost:5000/api/movies -H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Why this matters
list_movies() builds the query with an order_by call on MovieEntry.created_at that has no .desc()/.asc() modifier. An order_by on a plain column with no explicit direction sorts ascending by default -- oldest values first. This is a one-token mistake (a missing .desc()) but it inverts the entire list for every caller, on every page.
Suggested approach
Look at list_movies() in app/blueprints/movies/views.py, right after the watched filter is applied and just before .paginate(...) is called. Compare the ordering direction against what a "recently added" feed actually needs. You don't need to touch pagination, filtering, or the schema -- this is a single ordering direction fix.
Acceptance criteria
Verification
cd flask/movie_watchlist && .venv/bin/python -m pytest practicetickets/test_ticket01_movie_list_ordering.py -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
$git checkout -b fix/movie-list-orderingFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/movie-list-orderingSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign inRun the existing test suite (uses an in-memory SQLite DB, no setup needed):
.venv/bin/python -m pytest -v # 33 passed, 0 failed on a clean checkout
cp .env.example .env
# edit .env: set SECRET_KEY, JWT_SECRET_KEY, POSTGRES_PASSWORD to real values
docker compose up --build
This builds the web image, starts Postgres (db), waits for its healthcheck, then runs flask db upgrade and starts gunicorn -- all with one command, no manual migration step. The API is then available at http://localhost:5000.
Work the tickets in practicetickets/ (TICKET_01 through TICKET_07); each names one pytest test file in the same directory. This directory is outside pytest.ini's testpaths = tests, so a bare pytest run from the project root never picks these up -- they only run when pointed at directly:
cd flask/movie_watchlist
.venv/bin/python -m pytest practicetickets/test_ticket01_movie_list_ordering.py -v # a single ticket
./practicetickets/run_tickets.sh # all 7, clean pass/fail summary
run_tickets.sh also unsets TEST_DATABASE_URL/DATABASE_URL for its own run, so a leftover Postgres URL from a different project in your shell doesn't get picked up instead of the in-memory SQLite DB these tests are written against.
Level 1
Fix a bug
Read existing behaviour, correct it.