Weekend Build Part 1

Planning & Architecture

You're an experienced developer. You know how to build apps. But this weekend, you're going to build one the AI-first way — and the difference will be immediately obvious.


What We're Building

A task management app called Taskflow. Not a toy — a real, deployable application with authentication, a database, a REST API, and a polished frontend. The kind of project that typically takes a week or two of focused work.

We're building it in a weekend using AI-first methodology. Every decision, every component, every test — AI participates. You drive, AI accelerates.

Feature Set

Tech Stack

React 18 TypeScript Tailwind CSS Express.js SQLite

We're choosing this stack deliberately: React and TypeScript because they're the dominant frontend combination, Tailwind because it eliminates CSS bikeshedding, Express because it's minimal and fast to set up, and SQLite because it requires zero configuration — no Docker, no database server, just a file. Everything optimized for weekend speed.

Pro Tip: Why This Stack

In a weekend build, every minute of configuration is a minute not spent building features. SQLite eliminates database setup entirely. Tailwind eliminates CSS design decisions. TypeScript catches errors before runtime so you debug less. Every choice in this stack reduces friction.


The Weekend Schedule

Here's the realistic timeline. Five parts, roughly mapping to five focused sessions. You don't need to follow this exactly — adjust to your pace. The key is the sequence: planning before code, review before moving on.

Sat AM
Part 1 — Planning & Architecture
Design the system with AI. Data model, API endpoints, component tree, milestones. You're here now.
Sat PM
Part 2 — Backend: API & Database
Build the Express API, database schema, authentication, and all endpoints. Full test coverage.
Sun AM
Part 3 — Frontend: Core UI
React components, routing, state management, API integration. The app starts working.
Sun PM
Part 4 — Polish & Features
Kanban board, drag-and-drop, filtering, responsive design. The app becomes usable.
Sun Eve
Part 5 — Testing, Review & Deployment
AI-generated test suite, security review, code cleanup, and deployment.

Step 1: Design the Architecture

We're starting exactly how the AI Programming Manual teaches: design before code. Here's the actual conversation with AI that produces our architecture.

You

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.

AI

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, and we have a complete architecture. But we're not done — next comes the critique step.


Step 2: Critique the Design

You

Now critique this design. Be ruthless. What will break? What's over-engineered for a weekend build? What's missing?

AI

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' }).

Six issues found in under a minute. Issues 2, 4, 5, and 6 would have become debugging sessions later. By finding them now, we've saved at least an hour of weekend time.

This Is the Method

Design → Critique → Improve. Every time. The critique step is where the real quality comes from. If you skip it, you're just generating code with extra steps. If you do it, you're building on a solid foundation.


Step 3: The Improved Architecture

Incorporating the critique, here's our validated architecture:

Frontend — React 18 + TypeScript + Tailwind
App
AuthProvider
Router
LoginPage
DashboardLayout
Sidebar
ProjectView
FilterBar
KanbanBoard
Column
TaskCard
TaskModal
Toast
→ REST API (JSON) + JWT Auth Header
Backend — Express.js + TypeScript
authRouter
projectRouter
taskRouter
authMiddleware
validationMiddleware
errorHandler
cors
→ Parameterized SQL Queries
Data — SQLite
users
projects
tasks

Step 4: Define Milestones

Breaking the build into small, testable milestones. Each milestone produces something you can verify before moving on. This prevents the "everything is half-done" problem.

M1

Project scaffolding

Monorepo with /client and /server. Both run with hot reload. CORS configured.

20 min
M2

Database & models

SQLite setup, schema migration, TypeScript types for all entities.

30 min
M3

Authentication

Register, login, JWT middleware, protected routes. Test with curl.

45 min
M4

Project CRUD API

All project endpoints working. Archive instead of delete. Test with curl.

30 min
M5

Task CRUD API

All task endpoints including kanban move with float positioning. Full test suite.

45 min
M6

Frontend auth flow

Login/register pages, Zustand auth store, protected routes, token persistence.

45 min
M7

Dashboard & project list

Sidebar with projects, create/archive, DashboardLayout with routing.

45 min
M8

Kanban board

Columns render tasks by status. TaskCards display key info. Create task modal.

60 min
M9

Drag-and-drop & filtering

Move tasks between columns. FilterBar with status, priority, search.

60 min
M10

Polish, test & deploy

Responsive design, security review, test suite, error handling, deployment.

90 min

Total estimated time: ~8 hours of focused work. That's a weekend with breaks. Each milestone is independently verifiable — you know it works 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, every time you ask AI to generate code, paste these types first. They're compact (40 lines), they define the entire data contract, and they prevent AI from inventing its own field names or types. This single file will save you more debugging time than anything else in the project.


Before You Start Coding

Resist the urge to start implementing. You now have: a validated architecture, a critique-tested design, 10 defined milestones, and shared types. This planning session took about 30 minutes. It will save you 3+ hours of rework during the build.

If you skipped straight to code, you'd be refactoring your database schema by milestone 5 and rewriting your API by milestone 8. We've already prevented that.


Part 1 Complete — What We Have

Next Part Part 2 — Backend: API & Database