Building a Complete Project with Claude Code
Every topic in this course was preparation for this one. Building a complete project with Claude Code brings together context management, advanced prompting, code review, testing, Git workflows, security practices, and team collaboration into a single end-to-end process. This topic walks through the entire lifecycle of a real software project — from blank screen to deployed application — with Claude Code as your development partner at every stage.
The Project We Will Build
To make this concrete, the examples in this topic follow the construction of a Task Management API — a backend service where users can create accounts, log in, and manage their to-do lists. It is simple enough to understand quickly and complex enough to demonstrate every concept.
Task Management API ─────────────────────────────────────────── Features: ● User registration and login (JWT auth) ● Create, read, update, delete tasks ● Filter tasks by status (todo/done) ● Assign due dates to tasks Stack: ● Node.js + Express ● PostgreSQL + Prisma ORM ● JWT for authentication ● Vitest for testing
Phase 1 — Project Setup and Planning
Before writing a single line of code, use Claude to think through the project structure. This planning session prevents costly mistakes that require large refactors later.
Step 1 — Define the Architecture
Prompt: "I'm building a Task Management REST API with Node.js, Express, PostgreSQL, and Prisma. It has user auth and CRUD for tasks. Design the folder structure and explain what goes in each folder. I want separation of concerns: routes, services, and data access in separate layers."
Claude returns a folder structure with explanations. You review it, ask questions about decisions you disagree with, and confirm the layout before creating any files.
Folder Structure Output
/task-api
/src
/routes ← HTTP route handlers (thin layer)
/services ← Business logic
/repositories ← Database queries (Prisma calls)
/middleware ← Auth, error handling, validation
/types ← TypeScript interfaces and types
/utils ← Shared helper functions
/prisma
schema.prisma ← Database schema
/migrations ← Migration files
/tests ← Test files
CLAUDE.md ← Project standards for Claude
.env.example ← Environment variable template
Step 2 — Create the CLAUDE.md File
Prompt: "Create a CLAUDE.md file for this project. Include: tech stack, coding conventions (TypeScript strict, no any, async/await only), security rules (parameterized queries, env vars for secrets, auth on all private routes), and testing requirements (every route needs a test)."
This file now travels with the project. Every Claude Code session reads it automatically.
Phase 2 — Database Schema Design
Step 3 — Design the Schema
Prompt: "Write a Prisma schema for the Task Management API. Tables needed: - User: id, email, passwordHash, createdAt - Task: id, title, description (optional), status (todo/in_progress/done), dueDate (optional), userId (foreign key), createdAt, updatedAt Add proper indexes for query performance. Use UUIDs for all IDs."
Database Relationship Diagram
User
─────────────────────
id (UUID, PK)
email (unique)
passwordHash
createdAt
│
│ 1-to-many
▼
Task
─────────────────────
id (UUID, PK)
title
description (nullable)
status (enum)
dueDate (nullable)
userId (FK → User.id)
createdAt
updatedAt
Step 4 — Run the Migration
After Claude generates the schema, you create the migration and apply it:
npx prisma migrate dev --name init-schema npx prisma generate
If any error occurs, paste the error output into Claude and ask what went wrong.
Phase 3 — Building the Authentication Layer
Step 5 — User Registration Route
Prompt: "Write the user registration endpoint: POST /auth/register. Requirements: - Validate email format and password minimum 8 chars - Hash the password with bcrypt (salt rounds: 10) - Check for duplicate email — return 409 if exists - Return a JWT token on success (expires in 7 days) - Never return the passwordHash in the response Follow our CLAUDE.md conventions."
Step 6 — Immediately Review for Security
Prompt (right after): "Now audit what you just wrote for security vulnerabilities. Check: password storage, JWT secret handling, input validation, error messages that could leak information, and any SQL injection risk."
Fix any issues Claude identifies before moving forward. Security problems are cheapest to fix at the moment the code is written.
Step 7 — Write Tests for Auth Routes
Prompt: "Write Vitest tests for the /auth/register endpoint. Test cases needed: - Successful registration returns 201 and a JWT - Duplicate email returns 409 - Invalid email format returns 400 - Password under 8 characters returns 400 - Missing fields return 400 Mock the database calls with vi.mock."
Phase 4 — Building the Task CRUD Layer
With authentication in place, you build the task management features. Use the iterative prompting technique — build one endpoint at a time, test it, then move to the next.
Step 8 — Build Endpoints in Sequence
Sequence: ──────────────────────────────────────────────── 1. POST /tasks — Create a task 2. GET /tasks — List user's tasks (with filter) 3. GET /tasks/:id — Get one task 4. PUT /tasks/:id — Update a task 5. DELETE /tasks/:id — Delete a task ──────────────────────────────────────────────── Prompt for each step: "Write the [METHOD] /tasks[/:id] endpoint. [Specific requirements for this endpoint]. Ensure the user can only access their own tasks. Follow CLAUDE.md conventions."
Task Ownership Check Pattern
Every task endpoint must verify ownership:
WRONG — fetches task, skips ownership check:
const task = await db.task.findUnique({ where: { id } });
RIGHT — fetches task, verifies it belongs to logged-in user:
const task = await db.task.findFirst({
where: {
id: taskId,
userId: req.user.id ← Must match the logged-in user
}
});
if (!task) return res.status(404).json({ error: 'Task not found' });
Ask Claude to check every task route for this pattern before you consider the CRUD layer complete.
Phase 5 — Error Handling and Middleware
Step 9 — Global Error Handler
Prompt: "Write a global Express error handling middleware for this API. It should: - Catch all unhandled errors from route handlers - Return consistent JSON error responses (status, message, code) - In development, include stack traces - In production, hide internal error details - Handle Prisma-specific errors (unique constraint, not found) - Log all 5xx errors to the console"
Consistent Error Response Structure
Every error from the API looks the same:
────────────────────────────────────────
{
"status": "error",
"code": "DUPLICATE_EMAIL",
"message": "An account with this email already exists"
}
Clients know exactly what to expect.
Frontend developers never need to guess the error format.
Phase 6 — Full Test Suite
Step 10 — Integration Tests
Unit tests check individual functions. Integration tests check entire request flows — from HTTP request through the middleware, through the service layer, and into the database (or a test database).
Prompt: "Write integration tests for the complete task creation flow. Use a test database configured via environment variables. Test the full cycle: 1. Register a user 2. Log in, capture the JWT 3. Create a task with the JWT 4. Fetch the task list and verify the task appears 5. Update the task status to 'done' 6. Delete the task and verify it no longer appears"
Test Coverage Target
Coverage Map Before Testing: ───────────────────────────────────────── Route Coverage POST /auth/register ████████████ 100% POST /auth/login ████████████ 100% POST /tasks ████░░░░░░░░ 30% GET /tasks ░░░░░░░░░░░░ 0% PUT /tasks/:id ░░░░░░░░░░░░ 0% DELETE /tasks/:id ░░░░░░░░░░░░ 0% ───────────────────────────────────────── Ask Claude to write tests for every uncovered route.
Phase 7 — Code Review Pass
Step 11 — Final Review Before Deployment
Prompt: "Do a full code review of this project. Check: 1. All routes validate their inputs 2. Auth middleware is on every private route 3. Users can only access their own tasks 4. No secrets are hardcoded 5. All database queries are parameterized 6. Error messages do not expose internal details 7. All exported functions have tests List issues by severity: High / Medium / Low."
Fix every HIGH severity issue. Address MEDIUM issues where time permits. Schedule LOW issues for the next sprint.
Phase 8 — Preparing for Deployment
Step 12 — Environment Configuration
Prompt: "Create a .env.example file listing every environment variable this API needs. For each one, add a comment explaining what it is and where to get the value."
Step 13 — Deployment Checklist
Prompt: "Create a deployment checklist for this Node.js API. Include: environment variables to set, database migration command, build command, health check endpoint to verify, and common deployment errors for this stack."
Reflecting on the Development Process
Building this project with Claude Code follows a clear pattern you can apply to any project of any size:
PLAN → SCHEMA → AUTH → FEATURES → ERROR HANDLING
→ TESTS → REVIEW → DEPLOY
↑ ↑
└── Claude at every step ──┘
At each step:
1. Give Claude precise context (stack, conventions, task)
2. Review what Claude produces before using it
3. Ask Claude to audit security-sensitive code
4. Test before moving to the next step
5. Commit working code to Git with Claude's commit messages
What Claude Code Cannot Do for You
Even after building an entire project with Claude's help, some responsibilities always stay yours:
- Understanding your users and what they actually need
- Making architectural trade-off decisions that affect the business
- Reviewing Claude's output — you are the final check before code goes live
- Deciding when something works well enough versus when to keep improving
- Taking responsibility for security incidents caused by unreviewed code
Claude Code accelerates the implementation. The judgment, the ownership, and the final decisions belong to you.
Key Points
- Start every project with a planning session — architecture decisions made early prevent expensive refactors later
- Create
CLAUDE.mdbefore writing the first line of code — it aligns Claude with your project standards from session one - Build features in a fixed sequence: database first, auth second, business logic third, tests fourth, review fifth
- After Claude writes security-sensitive code, immediately ask it to audit that same code for vulnerabilities
- Verify task and user ownership checks on every data access route — Claude sometimes omits these in initial drafts
- The full cycle is: Plan → Schema → Auth → Features → Error Handling → Tests → Review → Deploy — Claude assists at every stage, you decide at every stage
