Challenge 1: Add a Projects Resource — Possible Solution ==================================================================== GET /v1/projects -> List projects (paginated, cursor-based) GET /v1/projects/{id} -> Retrieve one project POST /v1/projects -> Create a new project (should accept an Idempotency-Key header, same as task creation) PATCH /v1/projects/{id} -> Partially update a project (e.g. rename it) DELETE /v1/projects/{id} -> Delete a project Example paginated list request, following the exact same cursor convention as /v1/tasks: GET /v1/projects?after=eyJpZCI6MTJ9&limit=20 WHY THIS WORKS AS AN ANSWER ------------------------------ Every decision here is a direct copy of the pattern the capstone already established for /v1/tasks, not a new set of conventions: - Same /v1/ prefix (consistent versioning across the whole API, not just one resource). - Same GET/POST/PATCH/DELETE split, with PATCH (not PUT) for partial updates, matching Chapter 2's distinction applied consistently. - Same cursor-based pagination shape (?after=...&limit=...) for the same reason tasks needed it — if projects are also created/deleted over time by many users, offset pagination would have the same skip/duplicate risk Chapter 4's gotcha described. - Same Idempotency-Key expectation on POST, since project creation is just as vulnerable to a timeout-and-retry double-creation bug as task creation was. A well-designed API applies its conventions UNIFORMLY across resources — a client that's learned how /v1/tasks works should be able to correctly guess most of how /v1/projects works too.