Nobody has started this yet — be first.
Business impact
Nothing stops a single Reserve call from claiming a SKU's entire remaining stock in one request. For a genuine flash sale (the exact scenario this project is built around), that means one request -- a bug in a client, a scraper, or someone gaming the sale -- can claim all 100 units before anyone else gets a chance, defeating the point of a fair sale entirely.
Problem
checkMaxReserveQuantity exists only as a panicking TODO(ticket-18) stub; there is no way to cap how much a single Reserve call can claim.
Current behavior
A Reserve call over any intended cap currently panics with "TODO(ticket-18): checkMaxReserveQuantity not implemented" instead of being rejected cleanly.
Expected behavior
Service.SetMaxReserveQuantity(n int64) opts a Service into rejecting any single Reserve call asking for more than n units with a new ErrQuantityTooLarge, even when there's enough total stock to satisfy it. The default (unset) behavior is unlimited, exactly as today -- this is opt-in, not a behavior change for existing callers.
Steps to reproduce
go test ./tickets/tests/... -run TestTicket18 -vWhy this matters
The cap must be checked before any database work happens (no point opening a transaction for a request that's going to be rejected on quantity alone), and it must not affect Service instances that never call SetMaxReserveQuantity -- Reserve's existing call sites and this project's own test suite must keep working unchanged.
Suggested approach
Reserve already has an early quantity check (qty <= 0) right at the top, before it opens a transaction -- the new check belongs right after it, and only when a cap has actually been configured. Look at checkMaxReserveQuantity's stub and its call site in Reserve for where this is already wired up.
Acceptance criteria
Verification
TEST_DATABASE_URL=postgresql://... go test ./tickets/tests/... -run TestTicket18 -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
Sign in to create it automatically, or do it yourself:
$git checkout -b feat/max-reserve-quantityFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/max-reserve-quantitySubmit 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 inSKIP LOCKEDhttp://localhost:8081localhost:5434flash-saleeveryday-widgetcurl localhost:8081/healthzgo run ./cmd/loadtest -url http://localhost:8081 -sku flash-sale -concurrency 10000Work the tickets in tickets/docs/ (ordered easy → hard); each names one dedicated Go test in tickets/tests/:
export TEST_DATABASE_URL=postgresql://inventory:inventory@localhost:5432/inventory_test?sslmode=disable
go test ./tickets/tests/... -run TestTicket24 -v # a single ticket
./tickets/run_tickets.sh # all 25, clean pass/fail summary
Tickets that don't touch Postgres (02, 07, 17, 19) run fine without TEST_DATABASE_URL; the rest t.Skip cleanly, not fail, if it's unset.
Level 2
Implement a feature
Extend the system within its own patterns.