Nobody has started this yet — be first.
Business impact
Store.List returns every matching row, unbounded, every time. A user with a few thousand saved bookmarks makes GET /bookmarks return a multi-thousand-item JSON array and a full scan on every page load, and there is no way for any client to page through results.
Problem
ListFilter already has Limit int and Offset int fields (scaffolding for this ticket, already added) so calling code compiles -- but Store.List completely ignores them; every call still returns every matching row.
Current behavior
Calling Store.List with ListFilter{Limit: 2} against 5 matching rows still returns all 5, not 2.
Expected behavior
Store.List applies LIMIT/OFFSET at the SQL level (not by slicing the Go result after fetching everything -- that defeats the point). Limit <= 0 means "no limit" (today's behavior, preserved); Offset <= 0 means "start from the beginning."
Steps to reproduce
Seed 5 bookmarks. store.List(ctx, ListFilter{Limit: 2}) // Expected: 2 rows back // Actual: 5 rows back -- Limit is silently ignored
Why this matters
This is the same lesson Store.List already teaches for tag/q -- the WHERE text and the parameter-args slice are built up together, in lockstep. LIMIT/OFFSET should be added the same way: parameterized placeholders appended after ORDER BY, not string-formatted literals.
Suggested approach
Store.List already incrementally builds query and appends ORDER BY created_at DESC, id DESC at the end -- do something analogous for LIMIT $N OFFSET $M, appending the values to the same args slice already used for the WHERE clause.
Acceptance criteria
Verification
go test ./practicetickets/... -run TestTicket05 -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 feat/no-pagination-supportFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/no-pagination-supportSubmit 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 inmigrations/0001_init.sqlcurl http://localhost:8081/healthz
# {"status":"ok"}
To run without Docker, point the DB_* env vars from .env.example at a reachable Postgres and run go run ./cmd/server -- it applies the same migrations on startup.
The project's own test suite (go test ./...) is an integration suite against a real Postgres; it looks for one via BM_TEST_DB_HOST/BM_TEST_DB_PORT/BM_TEST_DB_USER/BM_TEST_DB_PASSWORD/BM_TEST_DB_NAME (defaults point at localhost:15433, database bookmarks_test) and skips cleanly rather than failing if that database is unreachable:
docker run -d --name bm_test_pg -e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=bookmarks_test -p 15433:5432 postgres:16-alpine
Work the tickets in PRACTICE_TICKETS.md (TICKET-01 through TICKET-10, all in one file, ordered easy -> hard); each names one Go test under practicetickets/:
go test ./practicetickets/... -run TestTicket01 -v # a single ticket
./practice_tickets_run.sh # all 10, clean pass/fail summary table
Level 2
Implement a feature
Extend the system within its own patterns.