Nobody has started this yet — be first.
Business impact
Once a timeout is scheduled (e.g. the 15-minute auto-void window on an authorized payment), there's no way to extend it short of waiting for it to fire and manually re-authorizing. A support agent who needs to give a merchant "a bit more time" before an auto-void has no lever to pull.
Problem
The route (POST /v1/payments/{id}/timeouts/reschedule), handler, request body parsing, and Service.RescheduleTimeout passthrough all exist; only Store.RescheduleTimeout's actual SQL is a panicking stub.
Current behavior
POST /v1/payments/{id}/timeouts/reschedule returns 500 with a panic logged: Store.RescheduleTimeout not implemented.
Expected behavior
POST /v1/payments/{id}/timeouts/reschedule with body {"deadline_at": "<RFC3339 timestamp>"} should push out (or pull in) the deadline of the payment's currently pending payment_timeouts row, without touching the payment's own state or version -- this is purely a change to when the timeout fires, not a state transition.
Steps to reproduce
go run ./cmd/paystate
curl -s -X POST localhost:8080/v1/payments/<id>/timeouts/reschedule
-d '{"deadline_at": "2030-01-01T00:00:00Z"}'
Why this matters
This is a straightforward UPDATE payment_timeouts SET deadline_at = $1 WHERE payment_id = $2 AND status = 'pending' -- the interesting part is recognizing that a payment could (structurally) have more than one payment_timeouts row across its lifetime (old fired/invalidated ones from earlier states), so the WHERE clause needs status = 'pending' to target only the live one.
Suggested approach
Look at Store.InvalidatePendingTimeouts right above Store.RescheduleTimeout in internal/payment/store.go for the WHERE payment_id = $1 AND status = 'pending' predicate shape -- you need the same predicate, but an UPDATE ... SET deadline_at = $newDeadline instead of SET status = 'invalidated'.
Acceptance criteria
Verification
TEST_DATABASE_URL=postgresql://... go test ./tickets/tests/... -run TestTicket19 -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/reschedule-timeoutFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin feat/reschedule-timeoutSubmit 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 composepaystate/paystate/go.modreplace reliable => ../reliabledocker compose up --buildpaystate/context: ..docker-compose.ymlCREATED_TIMEOUTAUTHORIZED_TIMEOUTWork the tickets in tickets/docs/ (ticket-01 through ticket-25); each names one Go test in tickets/tests/:
TEST_DATABASE_URL=postgresql://... go test ./tickets/tests/... -run TestTicket01 -v # a single ticket
TEST_DATABASE_URL=postgresql://... ./tickets/run_tickets.sh # all 25, clean pass/fail summary
Tickets that don't touch Postgres (02, 03, 04, 05, 06, 14, 15, 24) run fine without TEST_DATABASE_URL set; the rest report FAIL with a "TEST_DATABASE_URL not set" message if it's missing. make test-race runs the full go test -race -p 1 ./... suite the same way.
Level 2
Implement a feature
Extend the system within its own patterns.