// Project brief
Todo — Agile Team
React · Next.js · REST API · Agile
Join a team maintaining a live Todo app. Pick up bugs, tasks, and stories from the backlog, ship them through PRs and code review, and earn verified story points.

Work items
8
Story points
31
Est. effort
~16h
Top difficulty
6/10
// How it works
01
Enroll
Get your own private repo, generated from the project blueprint.
02
Ship work items
Pick up bugs, tasks, and stories — one PR each, run through CI and AI code review.
03
Earn story points
Merge to bank verified points and unlock the next item on the backlog.
// The backlog
8work items, unlocked in order as you ship. Open any of them to see exactly what you'd be doing — nothing here is hidden until you sign up.
BUG-001
XS · 1SPFix incorrect empty-state message
New users open the app to an empty list. The current wording is confusing and unwelcoming.
How to do this ▾
Why it matters
New users open the app to an empty list. The current wording is confusing and unwelcoming.
What you do
The Todo app shows "No records available." when there are no todos.
Expected: "No tasks yet. Create your first task."
Find where the message comes from and correct it.
Hints
User-facing copy lives in
src/lib/labels.js.Done when
- The empty state shows exactly "No tasks yet. Create your first task."
- No other behaviour changes
- Tests pass
BUG-002
S · 2SPTodos appear in the wrong order
Users expect their most recent task at the top, like every task app they use.
How to do this ▾
Why it matters
Users expect their most recent task at the top, like every task app they use.
What you do
The list shows the oldest todo first. It should show the newest first (most recently created at the top).
Hints
See
listTodosinsrc/lib/store.js.Done when
listTodos()returns todos newest-first (by createdAt, descending)- Tests pass
TASK-003
S · 2SPValidate the create-todo endpoint
The API currently accepts empty and absurdly long titles, letting bad data into the app.
How to do this ▾
Why it matters
The API currently accepts empty and absurdly long titles, letting bad data into the app.
What you do
POST /api/todosaccepts any title. Add validation: reject an empty title and a title longer than 200 characters with HTTP 400 and an error message.Hints
Edit the POST handler in
src/app/api/todos/route.js.Done when
- Empty title -> 400, not created
- Title > 200 chars -> 400
- Valid title -> 201 with the created todo
- Tests pass
STORY-004
S · 3SPDelete a todo
Users need to remove tasks they no longer care about.
How to do this ▾
Why it matters
Users need to remove tasks they no longer care about.
What you do
Add
DELETE /api/todos/:id. Return 204 on success and 404 for an unknown id.Hints
Create
src/app/api/todos/[id]/route.js. The store already hasdeleteTodo(id).Done when
- DELETE removes the todo and returns 204
- Unknown id returns 404
- Tests pass
STORY-005
M · 5SPUpdate a todo (toggle complete / edit title)
Users complete tasks and fix typos in their titles.
How to do this ▾
Why it matters
Users complete tasks and fix typos in their titles.
What you do
Add
PATCH /api/todos/:idthat updatescompletedand/ortitle. Return the updated todo (200) or 404 for an unknown id.Hints
Add PATCH to
src/app/api/todos/[id]/route.js. The store hasupdateTodo(id, changes).Done when
- PATCH toggles completed and/or edits title, returns the updated todo
- Unknown id -> 404
- Tests pass
STORY-006
M · 5SPAdd a priority field
Users want to mark which tasks matter most (low / normal / high).
How to do this ▾
Why it matters
Users want to mark which tasks matter most (low / normal / high).
What you do
Add a
priorityfield to todos. It defaults to"normal".POST /api/todosshould accept an optionalpriorityof"low","normal", or"high", and reject any other value with 400.Hints
Touches both
src/lib/store.js(createTodo) and the POST handler.Done when
- New todos default to priority "normal"
- POST accepts a valid priority
- Invalid priority -> 400
- Tests pass
BUG-007
M · 5SPDeleting a todo corrupts later todos
A user reported that after deleting a task, completing a new task marked the wrong one done. Data integrity bug — high priority.
How to do this ▾
Why it matters
A user reported that after deleting a task, completing a new task marked the wrong one done. Data integrity bug — high priority.
What you do
Reproduce: create a few todos, delete one, create another — the new todo can reuse an existing id, so updates hit the wrong record. Find the root cause and fix it so ids are always unique.
Hints
Look closely at how
createTodoassignsidinsrc/lib/store.js.Done when
- Ids are never reused after a delete
- Updating by id affects only that todo
- Tests pass
STORY-008
L · 8SPFilter todos by status
As lists grow, users want to focus on what's left (active) or review what's done (completed).
How to do this ▾
Why it matters
As lists grow, users want to focus on what's left (active) or review what's done (completed).
What you do
Support
GET /api/todos?status=active|completed(omitted orallreturns everything). Also add acountByStatus()helper to the store returning{ all, active, completed }.Hints
Filtering goes in the GET handler;
countByStatusinsrc/lib/store.js.Done when
- ?status=active returns only active todos
- ?status=completed returns only completed
- countByStatus() returns correct { all, active, completed }
- Tests pass