Usecase: Xây App Todo Nâng Cao Từ Đầu
Một người mới bắt đầu với Superpowers có thể xây dựng một ứng dụng Todo hoàn chỉnh -- từ brainstorm đến chạy thử -- chỉ trong một phiên làm việc duy nhất. Đây là usecase nhập môn lý tưởng để trải nghiệm toàn bộ quy trình.
Bối Cảnh
Bạn muốn xây một ứng dụng Todo làm prototype/demo -- đủ ấn tượng để trình bày, nhưng xây bằng quy trình Superpowers từ đầu đến cuối.
Yêu cầu:
- CRUD: Thêm, sửa, xóa, đánh dấu hoàn thành
- Lọc/tìm kiếm theo trạng thái, priority, category
- Phân loại (Work / Personal / Study) và mức ưu tiên (High / Medium / Low)
- Drag & drop sắp xếp thứ tự
- Due date cho từng todo
- Dark mode (toggle + theo system preference)
- Dữ liệu lưu trên localStorage (không cần backend)
Tech stack:
- Vite + React 18 + TypeScript
- shadcn/ui + Tailwind CSS
- @dnd-kit (drag & drop)
- date-fns (xử lý ngày tháng)
- Vitest + React Testing Library
Bạn Sẽ Học Được Gì
Trong bài hướng dẫn này, bạn sẽ áp dụng bốn kỹ năng cốt lõi của Superpowers:
- Brainstorming & Design -- Khám phá yêu cầu qua Q&A, so sánh approach, chọn layout với visual companion
- Writing Plans -- Chia nhỏ thành 11 task có verification rõ ràng
- TDD -- Viết test trước cho hook và component
- Debugging & Verification -- Xử lý lỗi tương thích thực tế và xác minh mọi thứ hoạt động
Mục tiêu cuối cùng: một ứng dụng Todo hoạt động hoàn chỉnh với 12 test case pass, build production thành công, được xây dựng theo quy trình có kỷ luật.
Từng Bước Thực Hành
Bước 1: Brainstorm Thiết Kế Todo App
Bạn mở chat với AI và nói:
"Tôi muốn xây một ứng dụng Todo đơn giản bằng React + TypeScript. Hãy brainstorm trước khi viết code."
AI vào chế độ brainstorm, bật visual companion (hiện mockup trên trình duyệt), và bắt đầu hỏi từng câu:
Câu hỏi 1: "Mục đích chính của ứng dụng Todo này là gì?"
- A) Dự án học tập/portfolio
- B) Ứng dụng cá nhân dùng hàng ngày
- C) Prototype/demo để trình bày
Bạn chọn: C) Prototype/demo -- cần ấn tượng khi trình bày.
Câu hỏi 2: "Ứng dụng cần những tính năng nào?"
- A) Cơ bản -- Thêm, sửa, xóa, đánh dấu hoàn thành
- B) Trung bình -- Như A + lọc/tìm kiếm, categories, priority
- C) Nâng cao -- Như B + drag & drop, due date, dark mode, localStorage persist
Bạn chọn: C) Nâng cao -- đầy đủ tính năng cho demo.
Câu hỏi 3: "Dữ liệu lưu trữ ở đâu?"
- A) LocalStorage only
- B) Mock API (json-server hoặc MSW)
- C) Real backend (Firebase/Supabase)
Bạn chọn: A) LocalStorage -- đơn giản, không cần backend.
Câu hỏi 4: "UI/styling dùng approach nào?"
- A) Tailwind CSS
- B) shadcn/ui + Tailwind
- C) CSS Modules / Styled Components
- D) Ant Design / MUI
Bạn chọn: B) shadcn/ui + Tailwind -- component đẹp, chuyên nghiệp, dễ customize.
Câu hỏi 5: "Tooling/build dùng gì?"
- A) Vite
- B) Next.js
- C) Create React App
Bạn chọn: A) Vite -- nhanh, nhẹ, phổ biến nhất.
Sau khi thu thập đủ thông tin, AI trình bày 3 cách tiếp cận:
## Approach A: Single Page — All-in-One (Khuyên dùng)
Toàn bộ app nằm trong 1 trang. Sidebar chứa filter/categories, main area chứa todo list.
- Pros: Đơn giản, không cần routing, UX mượt
- Cons: Mọi thứ dồn vào 1 view
## Approach B: Multi-Page với React Router
Chia thành nhiều trang: Dashboard, Todo List, Settings.
- Pros: Cấu trúc rõ ràng, dễ mở rộng
- Cons: Overkill cho todo app, thêm dependency
## Approach C: Kanban Board Style
Todo hiển thị dạng cột (To Do / In Progress / Done), drag & drop giữa các cột.
- Pros: Visual ấn tượng khi demo
- Cons: Phức tạp hơn nhiều, khó filter/sort
Bạn ban đầu chọn Kanban (C), nhưng sau khi xem mockup trên visual companion, bạn đổi ý sang Approach A: Single Page -- cân bằng tốt nhất giữa tính năng và độ phức tạp.
AI tiếp tục hỏi về layout:
- A) Sidebar + Main Content (giống Todoist)
- B) Top Filter Bar + Centered List (minimalist)
Bạn chọn: B) Top Filter Bar + Centered List -- gọn gàng và minimalist.
AI viết design spec chi tiết gồm 3 section:
DESIGN SPEC: Todo App
=== Section 1: Architecture & Data Model ===
Data Model:
interface Todo {
id: string
title: string
completed: boolean
priority: 'high' | 'medium' | 'low'
category: 'Work' | 'Personal' | 'Study'
dueDate: string | null
order: number
createdAt: string
}
State Management:
- useReducer cho todo state (add, edit, delete, toggle, reorder)
- Custom hook useTodos() — xử lý logic + localStorage sync
- Custom hook useTheme() — dark/light mode toggle
Component Structure:
App
├── Header (title, stats, dark mode toggle)
├── FilterBar (status pills, priority pills, category pills, search)
├── TodoInput (add new todo form — expand khi click)
├── TodoList (DnD container)
│ └── TodoItem[] (checkbox, title, priority badge, category, due date, actions)
└── EditTodoDialog (shadcn dialog)
=== Section 2: UI Components & Interactions ===
FilterBar:
- Pill buttons nằm ngang: Status (All|Active|Done) | Priority | Category
- Kết hợp bằng AND (Active + High + Work → chỉ hiện todo thỏa tất cả)
- Search input bên phải
TodoItem:
- Checkbox | Title | Priority badge (màu) | Category tag | Due date | Menu (⋮)
- Hover → hiện drag handle bên trái
- Completed → mờ + gạch ngang
- Overdue → due date hiện màu đỏ
Drag & Drop:
- @dnd-kit/sortable để kéo thả sắp xếp
- Khi drag trong filtered view, chỉ cập nhật order tương đối;
các item bị ẩn bởi filter giữ nguyên order
=== Section 3: Dark Mode & Persistence ===
Dark Mode: Tailwind dark: class + system preference mặc định
localStorage: Debounce 300ms khi write, fallback mảng rỗng nếu invalid data
Testing: Vitest + RTL cho useTodos hook, TodoInput, TodoItem
AI dispatch spec reviewer để kiểm tra chất lượng spec. Reviewer approve với 3 recommendations nhỏ (đã được cập nhật vào spec).
Bạn phê duyệt. Chuyển sang giai đoạn tiếp theo.
Lưu ý Superpowers: Design spec được lưu vào
docs/superpowers/specs/, spec reviewer tự động kiểm tra trước khi chuyển sang viết plan. Xem thêm Brainstorming.
Bước 2: Superpowers Viết Plan Chi Tiết
Dựa trên design spec, AI chia công việc thành 11 task (nhiều hơn đáng kể so với app đơn giản):
## Plan: Todo App
### Task 1: Project Scaffold
- Vite + React + TS, Tailwind, shadcn/ui, @dnd-kit, date-fns
- Vitest + React Testing Library
- Verification: npm run build thành công
### Task 2: Types & Storage Utilities
- src/types/todo.ts — interface Todo, Filters, constants
- src/lib/storage.ts — localStorage helpers
- Verification: TypeScript compile OK
### Task 3: useTodos Hook (TDD)
- Test trước: src/hooks/use-todos.test.ts
- Code: src/hooks/use-todos.ts
- Verification: 6/6 tests pass
### Task 4: Filter Logic & useTheme Hook
- src/lib/filters.ts — applyFilters() function
- src/hooks/use-theme.ts — dark mode toggle
### Task 5: Header & FilterBar Components
- src/components/header.tsx
- src/components/filter-bar.tsx
### Task 6: TodoInput Component (TDD)
- Test trước: src/components/todo-input.test.tsx
- Code: src/components/todo-input.tsx
- Verification: 3/3 tests pass
### Task 7: TodoItem Component (TDD)
- Test trước: src/components/todo-item.test.tsx (với DndContext wrapper)
- Code: src/components/todo-item.tsx
- Verification: 3/3 tests pass
### Task 8: TodoList + Drag & Drop
- src/components/todo-list.tsx
### Task 9: EditTodoDialog
- src/components/edit-todo-dialog.tsx
### Task 10: Assemble App + Toast
- Kết nối tất cả components vào App.tsx
- Verification: npm run build thành công
### Task 11: Final Polish & All Tests
- Verification: 12/12 tests pass, tsc --noEmit OK, build OK
AI dispatch plan reviewer kiểm tra. Reviewer phát hiện 2 vấn đề:
- TodoItem test thiếu DndContext wrapper --
useSortablecầnDndContextprovider, test sẽ fail - Sonner chưa được cài ở Task 1 -- sẽ gây lỗi ở Task 10
AI fix cả 2 trước khi bắt đầu implement.
Lưu ý Superpowers: Plan được lưu vào
docs/superpowers/plans/và review tự động trước khi thực thi. Xem thêm Writing Plans.
Bạn xác nhận: "OK, bắt đầu implement."
Bước 3: Implement Theo Plan (TDD: RED → GREEN → REFACTOR)
AI thực thi từng task theo plan. Các task có test đều tuân theo chu kỳ TDD.
Task 1: Project Scaffold
Scaffold Vite + React + TS, cài đặt tất cả dependencies. Gặp vấn đề thực tế:
- Vite 8 chưa tương thích với
@tailwindcss/vite→ dùng--legacy-peer-deps - shadcn/ui init fail do thiếu import alias → cấu hình
@/alias trong tsconfig + vite.config - Vite 8 conflict với shadcn → downgrade về Vite 7
Bài học thực tế: Scaffold không phải lúc nào cũng suôn sẻ. Compatibility issues giữa các library là chuyện thường. Quan trọng là biết cách debug và workaround.
Task 2: Types & Storage Utilities
| File | Mô tả |
|---|---|
src/types/todo.ts | Interface Todo, Filters, type aliases, constants (PRIORITIES, CATEGORIES) |
src/lib/storage.ts | loadTodos(), saveTodos(), loadTheme(), saveTheme() với error handling |
Task 3: useTodos Hook (TDD)
| File | Mô tả | |
|---|---|---|
| Test | src/hooks/use-todos.test.ts | 6 test cases: starts empty, add todo, toggle todo, delete todo, edit todo, reorder todos |
| Code | src/hooks/use-todos.ts | useReducer + localStorage sync, expose: addTodo, toggleTodo, deleteTodo, editTodo, reorderTodos |
RED → npx vitest run → FAIL (file chưa tồn tại) → GREEN → Implement hook → 6/6 PASS
Task 4: Filter Logic & useTheme
| File | Mô tả |
|---|---|
src/lib/filters.ts | applyFilters() -- filter kết hợp AND cho status, priority, category, search |
src/hooks/use-theme.ts | Toggle dark/light, sync với localStorage + system preference |
Task 5: Header & FilterBar
| File | Mô tả |
|---|---|
src/components/header.tsx | Tên app, stats counter, dark mode toggle (Sun/Moon icon) |
src/components/filter-bar.tsx | Pill buttons cho status/priority/category + search input |
Task 6: TodoInput (TDD)
| File | Mô tả | |
|---|---|---|
| Test | src/components/todo-input.test.tsx | 3 test cases: render placeholder, call onAdd on submit, clear input after submit |
| Code | src/components/todo-input.tsx | Input expand thành form: title, priority dropdown, category dropdown, date picker |
RED → FAIL → GREEN → 3/3 PASS
Task 7: TodoItem (TDD)
| File | Mô tả | |
|---|---|---|
| Test | src/components/todo-item.test.tsx | 3 test cases: render title + priority, toggle checkbox, line-through khi completed. Lưu ý: Test cần DndContext + SortableContext wrapper |
| Code | src/components/todo-item.tsx | Sortable item với drag handle, checkbox, priority badge, category tag, due date, dropdown menu |
RED → FAIL → GREEN → 3/3 PASS
Task 8-9: TodoList + EditTodoDialog
| File | Mô tả |
|---|---|
src/components/todo-list.tsx | DnD container với @dnd-kit/core + @dnd-kit/sortable, empty state |
src/components/edit-todo-dialog.tsx | shadcn Dialog với form chỉnh sửa: title, priority, category, date picker |
Task 10: Assemble App
Kết nối tất cả vào App.tsx: useTodos + useTheme + applyFilters + Toaster. Build production thành công.
Task 11: Final Polish
Chạy tsc --noEmit pass OK, nhưng npm run build phát hiện lỗi TypeScript với asChild prop -- shadcn v2 dùng base-ui thay vì radix, cần đổi sang render prop. Fix xong → build OK, 12/12 tests pass.
Quy trình TDD ở mỗi task: AI viết test trước → chạy test xác nhận FAIL → implement code tối thiểu → chạy test xác nhận PASS → refactor nếu cần → commit. Xem thêm TDD.
Bước 4: Verification -- Xác Minh Toàn Bộ
Tất cả 11 task đã hoàn thành. Chạy verification cuối cùng.
Chạy toàn bộ test suite
npx vitest run
✓ src/hooks/use-todos.test.ts (6 tests)
✓ useTodos > starts with empty todos
✓ useTodos > adds a todo
✓ useTodos > toggles a todo
✓ useTodos > deletes a todo
✓ useTodos > edits a todo
✓ useTodos > reorders todos
✓ src/components/todo-input.test.tsx (3 tests)
✓ TodoInput > renders placeholder input
✓ TodoInput > calls onAdd with todo data on submit
✓ TodoInput > clears input after submit
✓ src/components/todo-item.test.tsx (3 tests)
✓ TodoItem > renders todo title and priority
✓ TodoItem > calls onToggle when checkbox clicked
✓ TodoItem > shows line-through when completed
Test Files 3 passed (3)
Tests 12 passed (12)
Type check & Build
npx tsc --noEmit # No errors
npm run build # Build thành công
Tuyên bố
Todo App hoàn chỉnh. 12/12 test pass. Build production OK. No TypeScript errors. 10 commits sạch sẽ theo từng feature.
Kết Quả
Sau khi hoàn thành toàn bộ quy trình, bạn có:
Tính năng hoàn chỉnh:
- CRUD todos (thêm, sửa, xóa, toggle hoàn thành)
- Filter kết hợp AND theo status, priority, category + search
- Drag & drop sắp xếp thứ tự
- Due date với cảnh báo overdue (màu đỏ)
- Dark mode (toggle + theo system preference)
- localStorage persist (debounce 300ms)
- Responsive, minimalist UI với shadcn/ui
- Hiển thị stats (tổng task, active, done)
12 test cases pass 100% bao phủ:
- Custom hook
useTodos: add, toggle, delete, edit, reorder, empty state - Component
TodoInput: render, submit, clear - Component
TodoItem: render, toggle, completed style
Cấu trúc file:
src/
App.tsx
index.css
test-setup.ts
types/
todo.ts
lib/
storage.ts
filters.ts
utils.ts
hooks/
use-todos.ts
use-todos.test.ts
use-theme.ts
components/
header.tsx
filter-bar.tsx
todo-input.tsx
todo-input.test.tsx
todo-item.tsx
todo-item.test.tsx
todo-list.tsx
edit-todo-dialog.tsx
ui/ (shadcn components)
Vấn Đề Thực Tế Gặp Phải
Không giống các tutorial lý tưởng, session thực tế gặp nhiều vấn đề cần xử lý:
1. Vite 8 chưa tương thích với Tailwind plugin
@tailwindcss/vite chưa support Vite 8 → dùng --legacy-peer-deps để cài, sau đó downgrade về Vite 7 khi shadcn cũng conflict.
2. shadcn/ui init fail do thiếu import alias
shadcn yêu cầu @/ import alias → phải cấu hình baseUrl + paths trong tsconfig và resolve.alias trong vite.config.
3. shadcn v2 dùng base-ui thay vì radix
Prop asChild không còn hoạt động → phải đổi sang render prop cho PopoverTrigger và DropdownMenuTrigger. Lỗi này chỉ xuất hiện khi chạy npm run build (vite build có type check riêng), tsc --noEmit lại pass OK, và dev mode cũng không báo.
4. TodoItem test cần DnD wrapper
useSortable hook yêu cầu DndContext + SortableContext provider. Test sẽ crash nếu không wrap. Plan reviewer đã phát hiện và fix trước khi implement.
Bài học: Đây là lý do verification quan trọng. Nhiều lỗi chỉ xuất hiện khi build production hoặc chạy type check nghiêm ngặt, không thấy trong dev mode.
Key Takeaways
1. Brainstorm giúp bạn đổi ý đúng lúc
Bạn ban đầu chọn Kanban Board, nhưng khi xem mockup trên visual companion, bạn nhận ra Single Page phù hợp hơn. Thay đổi ở giai đoạn brainstorm tốn 0 dòng code. Thay đổi sau khi implement tốn hàng giờ refactor.
2. Plan reviewer bắt bug trước khi code
Reviewer phát hiện 2 vấn đề trong plan (thiếu DndContext wrapper trong test, thiếu sonner dependency). Nếu không review, các bug này sẽ xuất hiện giữa chừng implement và làm mất thời gian debug.
3. Compatibility issues là chuyện thường
3 trong 11 task gặp vấn đề tương thích (Vite 8, shadcn alias, asChild prop). Đây không phải bug của bạn -- đây là thực tế của hệ sinh thái JavaScript. Quy trình giúp bạn phát hiện và fix nhanh thay vì lúng túng.
4. useReducer + Custom Hook + TDD là combo mạnh
useTodos hook đóng gói toàn bộ logic (CRUD, reorder, localStorage sync) và có 6 test cases bảo vệ. Khi UI phức tạp (drag & drop, filter, edit dialog), logic vẫn ổn định vì đã được test độc lập.
5. 11 task nhưng mỗi task nhỏ và rõ ràng
"Xây Todo app nâng cao" nghe đáng sợ. Nhưng khi chia thành 11 task, mỗi task chỉ tạo 1-2 file và có verification riêng. Bạn không bao giờ phải giữ toàn bộ app trong đầu -- chỉ cần tập trung vào task hiện tại.
6. Đây là bước đệm cho project thực tế
Todo app "nâng cao" này đã bao gồm: custom hooks, drag & drop, dark mode, shadcn/ui, localStorage persistence, TDD, automated review. Đây là những pattern bạn sẽ dùng lại trong mọi project React.
Thực tế không hoàn hảo như tutorial. Bạn sẽ gặp compatibility issues, library changes, và unexpected errors. Quy trình Superpowers không loại bỏ những vấn đề này -- nó giúp bạn phát hiện sớm và xử lý có hệ thống thay vì loay hoay không biết bắt đầu từ đâu.