Before You Start: Prerequisites
- Time budget: 2-4 focused hours for this part.
- Environment: Node.js 20+ and npm installed.
- Skill level: Comfortable with JavaScript/TypeScript basics and terminal commands.
- AI tooling: Access to your preferred coding assistant (chat or editor-integrated).
- Scope mindset: Build for weekend delivery, not long-term scale.
Assumptions for This Tutorial
- You can run local dev servers and install dependencies without step-by-step onboarding.
- You are okay with pragmatic choices that optimize speed (for example SQLite and minimal infra).
- You will review AI output critically instead of copy-pasting blindly.
What We're Building
A task management app called Taskflow: an example full-stack scope with authentication, a database, a REST API, and a frontend. The tutorial shows a path toward a demo deployment; actual build time and readiness depend on your implementation and verification.
The walkthrough is organized as weekend-sized sessions using AI-assisted methodology. AI can draft decisions, components, and tests; you review the output and own each result.
Feature Set
- Projects — Create, rename, archive projects to group related tasks
- Tasks — Full CRUD with title, description, status, priority, due date, assignment
- Kanban board — Drag-and-drop columns: To Do, In Progress, Review, Done
- Filtering & search — By status, priority, assignee, and text search
- Authentication — JWT-based login/register with secure password hashing
- Responsive — Works on desktop and mobile
Tech Stack
We're choosing this stack deliberately: React and TypeScript for a typed component workflow, Tailwind to keep styling close to components, Express for a small API surface, and SQLite to avoid operating a separate database server for the tutorial. The choices prioritize a compact example build.
Pro Tip: Why This Stack
In a weekend build, setup time competes with feature work. SQLite avoids provisioning a separate database server, Tailwind provides ready utility classes, and TypeScript can flag some mistakes before runtime. These choices can reduce setup and iteration friction, but do not replace testing.
The Weekend Schedule
Here's a suggested sequence. Five parts roughly map to five focused sessions, but the times are planning estimates rather than measured outcomes. Adjust to your pace; the key is planning before code and verification before moving on.
Step 1: Design the Architecture
We're starting exactly how the AI Programming Manual teaches: design before code. The following illustrative exchange produces an architecture draft to critique and refine.
I'm building a task management app called Taskflow this weekend. React 18 + TypeScript frontend, Express + SQLite backend, Tailwind for styling.
Features: projects, tasks with full CRUD, kanban board with drag-and-drop, filtering, JWT authentication.
Design the architecture. Show me: data model, API endpoints, component tree, and state management approach.
Constraint: must be buildable by one developer in a weekend. Optimize for speed, not scale.
Data Model
Three tables: users (id, email, password_hash, name, created_at), projects (id, name, owner_id, archived, created_at), tasks (id, project_id, title, description, status, priority, assignee, due_date, position, created_at, updated_at).
Status enum: todo | in_progress | review | done
Priority enum: low | medium | high | urgent
API Endpoints
Auth: POST /auth/register, POST /auth/login
Projects: GET /projects, POST /projects, PATCH /projects/:id, DELETE /projects/:id
Tasks: GET /projects/:id/tasks, POST /projects/:id/tasks, PATCH /tasks/:id, DELETE /tasks/:id, PATCH /tasks/:id/move (for kanban reorder)
Component Tree
App → AuthProvider → Router → { LoginPage, RegisterPage, DashboardLayout → { Sidebar (project list), ProjectView → { FilterBar, KanbanBoard → { Column → TaskCard* } }, TaskModal } }
State Management
For weekend speed, I recommend Zustand over Redux. Two stores: useAuthStore (user, token, login/logout) and useProjectStore (projects, tasks, CRUD actions). API calls inside Zustand actions, no separate service layer — minimize indirection for speed.
One prompt produces an architecture draft. It is not accepted yet — next comes the critique step.
Step 2: Critique the Design
Now critique this design. Be ruthless. What will break? What's over-engineered for a weekend build? What's missing?
Issues found:
1. Assignee field is a string — This works for solo use but breaks if you want multi-user assignment later. For weekend scope this is fine, but note the limitation.
2. Position field for kanban ordering — Reordering with integer positions leads to frequent renumbering. Use float positions instead (e.g., insert between 1.0 and 2.0 → 1.5). Cheaper operations.
3. Missing: task moved_at timestamp — If you track when a task was moved to "done," you get basic velocity metrics for free. Add completed_at.
4. DELETE /projects/:id is dangerous — Should this cascade-delete all tasks? Add a soft-delete (archive) instead. You already have an archived field — use it.
5. No error handling strategy defined — Define upfront: API returns { error: string, code: string } on failure. Frontend shows toast notifications.
6. CORS not mentioned — Will bite you immediately. Add to the architecture: cors({ origin: 'http://localhost:5173' }).
In this illustrative critique, six potential issues are identified before implementation. Addressing issues such as ordering, deletion behavior, error handling, and CORS early can reduce later debugging, but any time saved depends on your build.
Design → Critique → Improve. The critique step surfaces assumptions before they become code. It improves the starting point, while implementation review and testing are still required.
Step 3: The Improved Architecture
Incorporating the illustrative critique, here's the revised architecture draft to validate:
Step 4: Define Milestones
Break the build into small, testable milestones. Each milestone defines something to verify before moving on, which helps avoid carrying too many unfinished flows at once.
Project scaffolding
Monorepo with /client and /server. Both run with hot reload. CORS configured.
Database & models
SQLite setup, schema migration, TypeScript types for all entities.
Authentication
Register, login, JWT middleware, protected routes. Test with curl.
Project CRUD API
Implement project endpoints. Archive instead of delete. Test with curl.
Task CRUD API
Implement task endpoints including kanban move with float positioning. Add focused endpoint tests.
Frontend auth flow
Login/register pages, Zustand auth store, protected routes, token persistence.
Dashboard & project list
Sidebar with projects, create/archive, DashboardLayout with routing.
Kanban board
Columns render tasks by status. TaskCards display key info. Create task modal.
Drag-and-drop & filtering
Move tasks between columns. FilterBar with status, priority, search.
Polish, test & deploy
Responsive design, security review, test suite, error handling, deployment.
Planning estimate: ~8 hours of focused work. Treat it as a scope budget, not a promised completion time. Each milestone defines a check to run before moving on.
Step 5: Define the Types
Before writing any implementation code, we define the TypeScript types. These types become the contract that both frontend and backend must respect — and they're the single most important context to share with AI throughout the build.
// === Entities ===
export interface User {
id: string;
email: string;
name: string;
created_at: string;
}
export interface Project {
id: string;
name: string;
owner_id: string;
archived: boolean;
created_at: string;
}
export type TaskStatus = 'todo' | 'in_progress' | 'review' | 'done';
export type TaskPriority = 'low' | 'medium' | 'high' | 'urgent';
export interface Task {
id: string;
project_id: string;
title: string;
description: string;
status: TaskStatus;
priority: TaskPriority;
assignee: string | null;
due_date: string | null;
position: number;
completed_at: string | null;
created_at: string;
updated_at: string;
}
// === API Request/Response ===
export interface CreateTaskInput {
title: string;
description?: string;
status?: TaskStatus;
priority?: TaskPriority;
assignee?: string;
due_date?: string;
}
export interface UpdateTaskInput {
title?: string;
description?: string;
status?: TaskStatus;
priority?: TaskPriority;
assignee?: string | null;
due_date?: string | null;
}
export interface MoveTaskInput {
status: TaskStatus;
position: number;
}
export interface ApiError {
error: string;
code: string;
}
Pro Tip: Types Are Your Best Context
Throughout this build, when you ask AI to generate code, paste these types first. They're compact (40 lines), they define the intended data contract, and they reduce the chance of invented field names or inconsistent types. You still need compiler and behavior checks.
Resist the urge to start implementing without review. At this tutorial checkpoint you have: an architecture draft, a reviewed list of design risks, 10 defined milestones, and shared types. Taking time to plan can reduce rework during your build.
If you skip straight to code, schema and API changes may arrive later and be more expensive. Validate these decisions against your requirements before implementing.
Part 1 Target Checkpoint — What to Have
- Reviewed architecture draft: three-layer system (React → Express → SQLite) with components defined
- Critique pass: six potential issues identified for resolution before implementation
- Data model: three tables with all fields, enums, and relationships defined
- API design: 11 endpoints with methods, paths, and behaviors specified
- Component tree: 13 components with clear hierarchy and responsibilities
- 10 milestones: each independently testable, with time estimates totaling ~8 hours
- Shared TypeScript types: the contract both frontend and backend will respect