Build a small inspection feed for reviewer 29. The first page lists at most 25 cases in descending creation order, with the record ID breaking timestamp ties. A create form writes a new inspection through a server endpoint; a repeated request with the same key must return the first result. Keep the interface usable when its optional fetch layer fails.
Make this comfortable
Project: paginated inspection feed with safe writes
Build contract
- Model case and inspection records with database constraints, then expose a bounded read endpoint whose cursor encodes both ordered fields.
- Accept a caller-scoped idempotency key on creation, store its request fingerprint with the result, and reject a changed body under the same key.
- Render a server-readable first page and use a real form action. Enhance pagination only after direct navigation and keyboard submission work.
Implementation checkpoint
SELECT inspection_id, created_at, summary
FROM inspections
WHERE reviewer_id = :reviewer_id
AND (created_at, inspection_id) < (:cursor_time, :cursor_id)
ORDER BY created_at DESC, inspection_id DESC
LIMIT :page_limit;Cost and boundaries
An indexed page read seeks near the cursor and returns O(P) rows for page size P; an unbounded export has different cost and needs its own budget. The idempotency record adds storage and a transactional write. Test with tied timestamps and a new row inserted between page requests.
Acceptance checks
- Page through 53 seeded inspections and compare unique IDs with the authorized set.
- Race two identical create requests on separate workers and confirm one persisted inspection.
- Open the second-page URL directly, then disable scripts and submit the create form.
Common Mistakes
- The same row appears on two pages after a new insertion.
- A lost create response produces two inspections after retry.
- A cursor from another reviewer exposes records outside the caller's scope.
Related lessons
Cursor Pagination for Changing Collections; Idempotent Write Requests and Lost Responses; Relational Records and Database Constraints; Browser Routing and History State; Authorization: check permission for this record on every request.
web-tech
web-development
