Nobody has started this yet — be first.
Business impact
Budgets currently support List (all of the caller's budgets) and Delete (by id), but not fetching one specific budget by id -- so a client that wants to show or confirm a single budget's details (e.g. before editing it) has to fetch the entire list and search client-side.
Problem
internal/budgets/repo.go has Upsert, List, Delete, GetLimit (which returns just the numeric limit, not a full Budget, and is keyed by user+category rather than by budget id) -- no Get-by-id. No GET /budgets/{id} route exists; today it 404s from ServeMux's default.
Current behavior
GET /budgets/{id} has no route and no repo method backing it at all -- there is simply no way to fetch a single budget's full details by id.
Expected behavior
GET /budgets/{id} (auth required) returns the full budget if owned by the caller, 404 otherwise -- the same ownership pattern Delete already uses (WHERE id = $1 AND user_id = $2).
Steps to reproduce
As an authenticated user with an existing budget, GET /budgets/{id}.
Why this matters
This is the simplest of this project's "add a missing single-resource GET" tickets -- Repo.Delete right above it in the same file is the direct template: same two-argument shape, same WHERE clause pattern, just a SELECT instead of a DELETE.
Suggested approach
Add a Repo.Get(ctx, id, userID) (*Budget, error) mirroring Repo.Delete's ownership-scoped WHERE clause and List's row-scanning shape (including the joined category name); wire a handler and GET /budgets/{id} route the same way DELETE /budgets/{id} is wired.
Acceptance criteria
Verification
go test ./practicetickets/... -run TestTicket08 -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/budget-get-by-idFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/budget-get-by-idSubmit 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 indocker-compose.ymlmigrations/0001_init.sqldocker-entrypoint-initdb.dexpense_trackerdbappcurl http://localhost:8082/healthz
To run locally against your own Postgres instead: cp .env.example .env (edit if your Postgres isn't on localhost:5434), then make migrate (applies migrations/*.sql via psql) and make run (go run ./cmd/server).
Work the tickets in PRACTICE_TICKETS.md (TICKET-01 through TICKET-10); each names one Go test in practicetickets/:
go test ./practicetickets/... -run TestTicket01 -v # a single ticket
./practice_tickets_run.sh # all 10, clean pass/fail summary
This project's own integration suite (cmd/server/*_test.go) needs a real, reachable Postgres -- point TEST_DATABASE_URL at any empty/disposable database (migrations are applied automatically, and every test truncates+reseeds before it runs) and run make test. The practicetickets/ suite defaults to postgres://postgres:postgres@localhost:5434/expense_tracker_test if TEST_DATABASE_URL is unset.
Level 2
Implement a feature
Extend the system within its own patterns.