Nobody has started this yet — be first.
Business impact
Every user's month-end summary -- and every category budget-warning check, which reuses this exact date math -- silently undercounts spending by excluding anything dated on the final calendar day of the month. A user who pays rent or a subscription on the 30th/31st sees a "total spend this month" that's simply wrong, and -- worse -- a user relying on the budget-warning feature to catch overspending can blow through their limit on the last day of the month and never get warned, silently defeating the one feature that exists to prevent exactly that.
Problem
monthRange computes a half-open date range [start, end) used as expense_date >= start AND expense_date < end. end is currently computed one day too early -- the range stops on the second-to-last day of the month -- so anything dated the actual last day falls outside it.
Current behavior
An expense dated the last day of a month is silently missing from that month's summary total and category breakdown, as if it never happened.
Expected behavior
monthRange("2026-08") returns ("2026-08-01", "2026-09-01") -- a half-open range correctly covering every day of August, including the 31st.
Steps to reproduce
As an authenticated user, POST /expenses with expense_date: "2026-08-31". GET /expenses/summary?month=2026-08
Why this matters
Half-open ranges are the standard way to do correct, inclusive month-boundary math with plain date comparisons -- this is a boundary/off-by-one error in how end is derived from start.
Suggested approach
Look at how end is computed from start in monthRange and think about what date represents "the first moment of the next month" relative to start.
Acceptance criteria
Verification
go test ./practicetickets/... -run TestTicket02 -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/month-summary-drops-last-dayFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/month-summary-drops-last-daySubmit 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 1
Fix a bug
Read existing behaviour, correct it.