Superapp / Product requirements / todos
Task List — product requirements
Task List is a classic personal todo list. People type a title and press Enter to add a task, tick tasks off, edit them inline, delete them, switch between All, Active and Completed views and clear what is done. Each browser tab keeps its own list on the server.
Problem. A todo list is only useful if the counter, the visible items and the stored list always agree, and if keyboard-only use is as complete as mouse use.
Users
- Everyday user — Capture, tick off and tidy tasks quickly, mostly from the keyboard.
Goals
- The "items left" counter always equals the number of active todos.
- Every edit gesture (Enter, Escape, blur, empty title) has one predictable outcome.
- Bulk actions only affect the todos they promise to affect.
Out of scope
- Drag to reorder
- Multiple lists
Contents
List and counter
Seeded list, footer counter and empty state.
FR-LST-01
MustA fresh tab shows three seeded todos, with the completed one struck through, and a footer with the active counter, the All / Active / Completed filters and Clear completed.
- Buy oat milk (active), Book dentist appointment (completed), Renew library card (active)
- Footer "2 items left" with All selected
FR-LST-02
MustThe footer counter equals the number of active (not completed) todos, and is singular for one: "1 item left".
- Ticking Buy oat milk: "1 item left"; unticking: "2 items left"
- All completed: "0 items left"
FR-LST-03
CouldWith no todos the list, footer and toggle-all chevron are hidden and a hint is shown.
- "Nothing to do — add your first todo above."
Adding todos
Keyboard-only entry.
FR-ADD-01
MustTyping a title in "What needs to be done?" and pressing Enter appends an unchecked todo and empties the input; there is no add button.
- "Water the plants" is last and unchecked; "3 items left"
FR-ADD-02
ShouldTodos keep the order in which they were added.
- Three more todos added in sequence appear after the seeded three in the same order; "5 items left"
FR-ADD-03
ShouldEmpty or whitespace-only input adds nothing; surrounding spaces are trimmed from a valid title.
- Enter on empty and on " " leaves three todos
- " Feed the cat " is added as "Feed the cat"
FR-ADD-04
CouldTitles are shown as plain text and long titles wrap inside the list.
- <b>bold?</b> & "quotes" is displayed literally, not as bold
- A 100-character title wraps without horizontal scroll
Completing todos
Single and bulk completion.
FR-CMP-01
MustThe checkbox toggles a todo between active and completed (struck through) and updates the counter.
FR-CMP-02
MustThe chevron left of the input ("Mark all as complete") completes every todo; clicking it again reopens every todo and hides Clear completed.
- All three struck through, "0 items left"; again: none completed, "3 items left"
FR-CMP-03
MustClear completed removes only the completed todos and then hides itself.
- After ticking Buy oat milk: only Renew library card remains, "1 item left", button hidden
- With the seed, clearing leaves Buy oat milk and Renew library card and "2 items left"
- Mark all then Clear completed leaves the empty-list state
Editing and deleting
Inline edit and hover delete.
FR-EDT-01
MustDouble-click opens an inline editor with the current text; Enter saves the trimmed text and the change survives a reload.
- "Renew library card online " is saved as "Renew library card online"
FR-EDT-02
ShouldEscape discards the edit and keeps the original title.
- Typing "Buy almond milk" then Escape leaves "Buy oat milk"
FR-EDT-03
ShouldClicking elsewhere (blur) saves the edit.
- "Buy oat milk and bread" is kept after clicking the heading
FR-EDT-04
MustSaving an empty title deletes the todo; no blank row is ever left.
- Clearing Renew library card and pressing Enter leaves two todos and "1 item left"
FR-EDT-05
ShouldA × button is revealed only while hovering a row and deletes that todo.
- No × without hover; after hover and click, Buy oat milk is gone and "1 item left"
Filters
Hash-routed All / Active / Completed views.
FR-FLT-01
ShouldFilters show the right subset and are reflected in the URL hash; the current filter is outlined.
- Active: #/active, Buy oat milk and Renew library card
- Completed: #/completed, only Book dentist appointment
- All shows all three
FR-FLT-02
CouldA filter URL opens directly on that filter and the browser Back button returns to the previous filter.
- /todos/#/completed shows only Book dentist appointment; Active then Back shows Completed again
FR-FLT-03
ShouldCompleting a todo while the Active filter is selected removes it from the view.
- Ticking Buy oat milk: it disappears, "1 item left"
Persistence and API
Per-tab server state and REST interface.
FR-PER-01
ShouldChanges survive a reload in the same tab; a new tab starts from the seeded three todos.
- Added Water the plants, reload: four todos, "3 items left"; new tab: seeded three
FR-PER-02
ShouldThe REST API supports list, add, update, delete and reset with specific errors.
- GET lists 3 todos, active 2, completed 1
- Blank title: 422 "Title is required"
- Add returns 201 with id t4; PATCH completed true and DELETE return 200; DELETE again 404
- Reset restores the seeded three
Non-functional requirements
NFR-01
MustData integrity: the counter, the visible list and the stored list never disagree after any add, edit, delete, toggle or clear.
NFR-02
ShouldKeyboard accessibility: add, save and cancel are available from the keyboard (Enter, Escape).
Glossary and rules
| Active | A todo that is not completed. |
|---|---|
| Toggle all | The chevron left of the input that completes or reopens every todo. |