Skip to content

Complete Development Workflow

Put everything you’ve learned together by building a real feature with Claude Code. This guide walks through a complete development workflow, from receiving requirements to deploying tested code.

We’ll build a user profile feature that includes:

  • Profile page with editable fields
  • Avatar upload capability
  • API endpoints for profile operations
  • Database schema updates
  • Full test coverage

What You'll Build

  • Frontend: React component with form handling
  • Backend: RESTful API endpoints
  • Database: Schema migrations and queries
  • Tests: Unit, integration, and E2E tests
  • Documentation: API docs and README updates

Start Claude Code and create a Product Requirements Document:

Terminal window
> Create a PRD for a user profile feature. Users should be able to:
> - View and edit their profile (name, bio, location)
> - Upload an avatar image
> - Make their profile public or private
> - See when their profile was last updated

Claude will generate a comprehensive PRD. Review and refine:

Terminal window
> Add requirements for:
> - Avatar image size limits (max 5MB)
> - Bio character limit (500 chars)
> - Profile URL format (/users/{username})

Use extended thinking to create a technical plan:

Terminal window
> Based on this PRD, think hard about the implementation approach.
> Consider database schema, API design, security, and testing strategy.
> We're using React, Node.js/Express, and PostgreSQL.

Transform the plan into actionable tasks:

Terminal window
> Convert your plan into a detailed todo list with subtasks.
> Organize by: Database, Backend API, Frontend, Tests, Documentation

Claude generates something like:

## User Profile Feature Tasks
### Database
- [ ] Create migration for users table updates
- [ ] Add bio, location, avatar_url columns
- [ ] Add is_public boolean with default true
- [ ] Add updated_at timestamp
- [ ] Create migration for avatar_metadata table
- [ ] Store file size, mime type, upload date
### Backend API
- [ ] Create profile endpoints
- [ ] GET /api/users/:username/profile
- [ ] PUT /api/users/profile (authenticated)
- [ ] POST /api/users/avatar (file upload)
- [ ] DELETE /api/users/avatar
- [ ] Implement middleware
- [ ] Authentication check
- [ ] File upload validation
- [ ] Profile visibility check
### Frontend
- [ ] Create ProfilePage component
- [ ] Display mode for public profiles
- [ ] Edit mode for own profile
- [ ] Create ProfileForm component
- [ ] Form validation
- [ ] Avatar upload with preview
- [ ] Add routing
- [ ] Add to navigation
### Tests
- [ ] Unit tests for API endpoints
- [ ] Integration tests for profile workflows
- [ ] E2E tests for profile interactions
- [ ] Test file upload edge cases
### Documentation
- [ ] API documentation
- [ ] Update README
- [ ] Add example usage

Start with the database schema:

Terminal window
> Create the database migration for the user profile fields.
> Use our standard migration format with up/down methods.

Claude creates migrations/20250315_add_user_profile_fields.js:

exports.up = async (knex) => {
await knex.schema.alterTable('users', (table) => {
table.text('bio').nullable();
table.string('location', 100).nullable();
table.string('avatar_url', 255).nullable();
table.boolean('is_public').defaultTo(true).notNullable();
table.timestamp('profile_updated_at').defaultTo(knex.fn.now());
});
await knex.schema.createTable('avatar_metadata', (table) => {
table.increments('id').primary();
table.integer('user_id').unsigned().notNullable()
.references('id').inTable('users').onDelete('CASCADE');
table.integer('file_size').unsigned().notNullable();
table.string('mime_type', 50).notNullable();
table.timestamp('uploaded_at').defaultTo(knex.fn.now());
table.index('user_id');
});
};
exports.down = async (knex) => {
await knex.schema.dropTableIfExists('avatar_metadata');
await knex.schema.alterTable('users', (table) => {
table.dropColumn('bio');
table.dropColumn('location');
table.dropColumn('avatar_url');
table.dropColumn('is_public');
table.dropColumn('profile_updated_at');
});
};
Terminal window
> Update the User model to include the new profile fields.
> Add validation rules and any computed properties.

Implement the profile API:

Terminal window
> Implement the GET /api/users/:username/profile endpoint.
> It should:
> - Return 404 if user doesn't exist
> - Return 403 if profile is private and requester isn't the owner
> - Include avatar metadata if available

Claude's Approach

Claude will:

  1. Create the route handler
  2. Add input validation
  3. Implement business logic
  4. Add error handling
  5. Consider edge cases
Terminal window
> Implement avatar upload with:
> - Multer for file handling
> - Image validation (type and size)
> - Resize to standard dimensions
> - Store in local uploads directory
> - Save metadata to database
Terminal window
> Write comprehensive tests for the profile API endpoints.
> Include tests for:
> - Successful operations
> - Authentication failures
> - Validation errors
> - File upload edge cases

If you have Figma MCP configured:

Terminal window
> Get the user profile design from Figma and analyze the component structure
Terminal window
> Create the ProfilePage component based on the design.
> Include:
> - Conditional rendering for view/edit modes
> - Form validation with react-hook-form
> - Avatar upload with drag-and-drop
> - Loading and error states

Claude creates a well-structured component:

ProfilePage.tsx
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { useAuth } from '../hooks/useAuth';
import AvatarUpload from './AvatarUpload';
import ProfileDisplay from './ProfileDisplay';
import ProfileForm from './ProfileForm';
const ProfilePage: React.FC = () => {
const { username } = useParams<{ username: string }>();
const { user: currentUser } = useAuth();
const [profile, setProfile] = useState(null);
const [isEditing, setIsEditing] = useState(false);
const [loading, setLoading] = useState(true);
// ... implementation
};
Terminal window
> Add the profile route to our router and test the full flow:
> - Navigate to profile
> - Edit own profile
> - Upload avatar
> - View another user's profile

Using Playwright MCP:

Terminal window
> Write E2E tests for the profile feature:
> - User can view their own profile
> - User can edit and save changes
> - Avatar upload works correctly
> - Privacy settings are enforced
Terminal window
> Analyze the profile page performance:
> - Check database query efficiency
> - Verify image optimization
> - Test loading times
> Run lighthouse if available
Terminal window
> Update our API documentation with the new profile endpoints.
> Include request/response examples and error codes.
Terminal window
> Review all changes and create a pull request:
> - Generate a comprehensive PR description
> - Link to the original requirements
> - Include testing instructions
> - Add screenshots of the UI

Claude will:

  1. Run git status to see all changes
  2. Create a feature branch if not already on one
  3. Stage and commit with a detailed message
  4. Push to remote
  5. Generate PR description with all context

After PR approval:

Terminal window
> Create a deployment plan for the profile feature.
> Include:
> - Database migration steps
> - Environment variable updates
> - Feature flag configuration
> - Rollback procedure

Throughout the workflow, Claude automatically:

  • Runs tests after code changes
  • Checks linting and formatting
  • Validates against requirements
  • Suggests improvements

Keeping Claude Focused

  • Use /clear between major phases
  • Reference CLAUDE.md for standards
  • Keep PRD available for validation
  • Use subagents for parallel tasks

When things go wrong:

Terminal window
# Claude made an error
> Undo the last change
# Tests are failing
> Debug why the profile update test is failing
# Need to start over
> Revert all changes since the last commit

Here’s a condensed real-world session:

Terminal window
# Start with requirements
> Let's build a user profile feature. Think about what we need.
# Claude analyzes and plans...
> Great plan. Create the database migration first.
# Claude creates migration file...
> Run the migration and verify it worked.
# Claude runs migration...
> Now implement the GET profile endpoint with tests.
# Claude implements endpoint and tests...
> The tests are failing. Debug and fix.
# Claude investigates and fixes...
> Perfect. Now build the React component.
# Claude creates component...
> Add E2E tests for the complete flow.
# Claude writes Playwright tests...
> All tests passing! Create a PR with a good description.
# Claude creates comprehensive PR...

Feature Completion Checklist

✅ All requirements from PRD implemented

✅ Database migrations run successfully

✅ API endpoints tested and documented

✅ Frontend matches design specifications

✅ Unit test coverage > 80%

✅ E2E tests cover happy path + edge cases

✅ Documentation updated

✅ PR reviewed and approved

✅ Deployed successfully

Congratulations! You’ve built a complete feature with Claude Code. Continue learning with:

Remember: Claude Code is your pair programmer. The more context and clarity you provide, the better it can help you build robust, well-tested features efficiently.