πŸš€ New: The .NET Senior PlaybookSave 20% with launch discountΒ 

newsletter

How to Build Production-Ready Projects With Claude Code

10 min read

Newsletter Sponsors

Your cloud setup shouldn't take longer than your actual build. Instant VMs, built-in HTTPS, persistent disks - zero config drama. Spin up, SSH in, ship it. That's exe.dev.

πŸ‘‰ Get started today

Every CI debug session ends the same way: 10 commits called fix: ci, fix: ci again, fix: asdf. You push a guess, wait 10 minutes for a 15-step pipeline to fail at step 14, look at logs, push another guess. It's such a waste of time. Stop guessing!

Depot CI lets you run real CI against your local uncommitted changes. Edit a workflow, run it, get an answer. No commit, no push, no polluted git history. If logs aren't enough, stop the run after the expensive setup step and SSH straight into the runner. You can pw, ls, and check what's actually on the machine instead of inventing it in your head.

The loop is three commands:

bash
depot ci run --workflow .depot/workflows/ci.yml depot ci run --workflow .depot/workflows/ci.yml --ssh-after-step 3 depot ci ssh <run-id>

Migration is one command: depot ci migrate picks up your existing GitHub Actions workflows and copies them over. Your .github/ folder stays intact, so you can run both in parallel until you're ready to cut over.

πŸ‘‰ Try Depot CI for free

In modern software development, there are two common paths:

  1. You don't use AI, and you spend weeks on architecture decisions and months writing boilerplate code.
  2. You use AI heavily, shortcut every possible architecture decision, vibe-code 98% of your project, and ship quickly with low quality.

Neither of these paths is great.

I want to tell you something about AI-assisted development in 2026.

If you don't understand your programming language deeply, your main web framework, HTTP, databases, concurrency fundamentals, Architecture Patterns, tradeoffs... You can't tell when the code generated by Claude or Copilot is subtly wrong - and it will be, often enough to matter in production.

AI amplifies what you already know.

The stronger your fundamentals, the better your judgment on what Architecture Decisions to make, what to keep, what to fix, and what to throw away entirely. And going forward, developers with deep knowledge who operate AI, will be the most valued.

Over the past year, I built a 10-step workflow that I use to ship quality software much quicker with AI. This workflow is designed to create well-architected, production-ready software with solid architecture, proper validation, error handling, security, and clean code.

You should treat AI as your personal assistant who helps you in each phase of design and development. You guide it through a structured process where each step builds on the output of the previous one.

In this post, I will share the complete workflow with detailed prompts you can adapt for your own projects.

In this post, we will explore:

  • Why most AI-generated code fails in production
  • The 10-step workflow I use to ship production-quality software with AI
  • Prompt engineering principles for production code

Let's dive in.

Copied

Why Most AI-Generated Code Fails in Production

The most common way developers use AI for coding is what I call "vibe coding." You open a chat, type "build me a REST API for managing orders," and get back something that compiles.

The generated code typically has:

  • Poor code quality
  • Poor input validation (or just inline if-else statements)
  • No error handling strategy (or try-catch in API endpoints)
  • No consistent project structure
  • No separation of concerns
  • Hard-coded configuration
  • No logging or observability
  • No security considerations
  • No tests

This happens because the AI has no context about your project. It does not know your architecture decisions, your team's coding conventions, your error handling patterns, or your deployment constraints. It gives you a generic answer to a generic question.

And even with the best AI models, like Claude Opus, with such generic prompts, you cannot guarantee that the output will be production-ready.

Production-ready code means something specific:

  • It follows a consistent architecture across the entire codebase
  • It has high-quality code
  • It handles errors gracefully with a unified error response format
  • It validates all user inputs
  • It uses proper logging and has observability
  • It follows your team's naming conventions and file organization
  • It is structured for testing and maintenance
  • It has a comprehensive test suite

To achieve this, we need a better process. When you give AI structured requirements, architecture decisions, and code examples to follow, the output quality increases dramatically.

The workflow I share in this post mirrors how experienced developers already think:

  1. Requirements
  2. Architecture
  3. Specification
  4. Writing code
  5. Reviewing code
  6. Testing code and deploying

AI accelerates each step, but the human remains the architect and decision-maker. I always said that the creative and decision-making part should always be on us, humans.

Copied

The 10-Step Workflow to Ship Production-Quality Software with AI

I have created and refined this workflow over time to ship production-quality software with AI.

The workflow has 5 phases and 10 steps:

Phase 1: Requirements and Planning

  • Step 1: Define Business Requirements
  • Step 2: Define Non-Functional Requirements

Phase 2: Architecture and Specification

  • Step 3: Design the Architecture
  • Step 4: Generate the Backend Specification

Phase 3: Backend Implementation

  • Step 5: Code the Backend
  • Step 6: Review and Refine

Phase 4: Frontend Implementation

  • Step 7: Generate the Frontend Specification
  • Step 8: Code the Frontend

Phase 5: Deployment

  • Step 9: Automate Deployment with CI/CD
  • Step 10: Human Review, Test, and Deploy

Each phase produces artifacts that feed into the next phase.

Let's walk through each step in detail.

Copied

Step 1: Define Business Requirements

Every project starts with requirements (regardless of whether you use AI). Skip this step, and you will spend more time fixing misunderstandings than writing code.

A Business Requirements Document (BRD) describes what the system should do from the user's perspective. It covers user roles, core features, workflows, business rules, and edge cases.

If you already have a BRD, upload it to Claude Code, switch to Opus 4.7 model and use Plan Mode. Opus can handle 1M tokens in a single prompt, which is enough for documents with 500 pages (I haven't tested it with larger documents).

Plan Mode tells Claude to analyze and reason through the problem before generating anything. This is critical. Without it, Claude will jump straight to code.

Here is the prompt I use for analyzing business requirements:

markdown
You are a Senior Business Analyst reviewing a Business Requirements Document. Read the attached BRD and analyze it thoroughly. For each feature, identify and document: 1. All user roles and their permissions 2. Core entities and their relationships 3. Complete user workflows (step by step) 4. Business rules and validation constraints 5. Edge cases and error scenarios 6. Any ambiguities or missing requirements Present your analysis as a structured document. Flag every ambiguity with a [CLARIFICATION NEEDED] tag so we can resolve it before moving to architecture.

If you do not have a BRD, you can create one interactively. Describe your project idea, and ask Claude to generate a BRD by asking you clarifying questions:

markdown
I want to build [describe your project in 2-3 sentences]. Help me create a Business Requirements Document by asking me clarifying questions about: - User roles and permissions - Core features and workflows - Business rules and constraints - Integration requirements Ask questions one section at a time. After I answer, I summarize my answers and move to the next section.

The goal of this step is to eliminate ambiguity. Every unclear requirement will become a bug or a rework cycle later.

P.S. To speed up the process, I use the Wispr Flow app to dictate rather than type. It costs me $12/month, and it's absolutely worth it, as it saves so much time for typing. If you want to try it, you can use my referral link to get 1 month for free.

Copied

Step 2: Define Non-Functional Requirements

Most developers skip non-functional requirements and pay for them later during production incidents.

Non-functional requirements (NFRs) define the quality attributes of your system:

  • Availability β€” will it be up when users need it?
  • Scalability β€” can it handle 10x more users without a rewrite?
  • Performance β€” how fast does it respond under load?
  • Cost β€” how much will it cost to run at scale?
  • Security β€” who can access what, and how is data protected?
  • Maintainability β€” how easy is it to change or extend later?
  • Reliability β€” does it recover gracefully when things go wrong?
  • Testability β€” can you verify the code is easily testable?

These constraints directly affect architecture decisions in the next step.

Here is the prompt I use:

markdown
Based on the business requirements we defined, help me define non-functional requirements for this project. For each category below, extract from the document, and if missing, suggest specific, measurable targets: 1. Availability: Uptime SLA, acceptable downtime per month 2. Performance: API response time targets (p50, p95, p99), page load time targets 3. Scalability: Expected concurrent users, data growth rate, peak load scenarios 4. Security: Authentication method, authorization model, data encryption requirements, compliance needs 5. Cost: Infrastructure budget constraints, hosting preferences (cloud provider, self-hosted) Present each requirement with a measurable target and the reasoning behind it.

This is just an example; your task as an Architect is to define the NFRs for your project. There are way more than I have mentioned. See the full list here.

After Claude suggests targets, challenge them. Are they realistic for your project size? Do you really need 99.95% uptime for your project?

Overengineering starts with inflated non-functional requirements. The output of this step is a short document (usually one page) that will guide every architecture decision that follows.

Copied

Step 3: Design the Architecture

This is where many developers make their biggest mistake with AI: they accept the first architecture suggestion without questioning it.

I use Claude as an Architecture Consultant, not as an authority. I present the requirements and NFRs, ask for options with trade-offs, and then I make the decision myself.

Here is the prompt:

markdown
You are a Solution Architect. I need help designing the architecture for the project described in the attached requirements. Based on the business requirements and non-functional requirements, propose 2-3 architecture options. For each option, provide: 1. Architecture style (Modular Monolith, Microservices, Serverless) 2. Project structure and module/service boundaries 3. Database choice and schema approach 4. API design approach (REST, GraphQL, gRPC, Events) 5. Authentication and authorization strategy 6. Deployment model For each option, clearly state: - Pros and cons - Which NFRs does it satisfy, and which ones does it trade off - Team size and expertise requirements - Estimated complexity Recommend one option and explain your reasoning.

For most projects, I use a Modular Monolith with Vertical Slice Architecture right from the start. This gives you clean module boundaries without the operational complexity of microservices. You can always extract modules into separate services later if needed. Read more about architecture trade-offs in my other post.

After choosing the architecture, I use an interactive conversation to define the details:

  • Module boundaries
  • Shared abstractions
  • Database schema
  • API contracts
  • Communication patterns: sync or async

The key is to challenge every proposal. Ask "Why this approach over X?" and "What happens when Y fails?"

The output of this step is an architecture document that describes the system structure, technology choices, and the reasoning behind them.

Copied

Step 4: Generate the Backend Specification

A backend specification is a detailed Markdown file that describes every aspect of the implementation. It is so detailed that a developer could implement the entire backend without asking many questions.

When you feed Claude a specification file, the generated code is consistent, follows your patterns, and requires minimal rework.

Before generating any specification or code, set up a CLAUDE.md file in the root of your project. This is the single most impactful thing you can do.

CLAUDE.md is a Markdown file that Claude Code automatically loads into context when you open a project. It tells Claude your tech stack, architecture, coding conventions, and patterns, so every generated file is consistent from the start.

What to include in CLAUDE.md:

  • Tech stack with specific versions
  • Architecture style and project structure
  • File naming conventions
  • Patterns you use AND patterns you explicitly do not use
  • Common commands (build, test, run, migrations)
  • Testing frameworks and conventions
  • Domain terminology mapped to code entities

What NOT to include:

  • Secrets, API keys, or connection strings
  • Code formatting rules (use .editorconfig for that)
  • Obvious framework knowledge that Claude already knows
  • Large code samples (reference files with @ instead)

Here is the CLAUDE.md template I use for my .NET backend projects:

markdown
undefined

CLAUDE.md

Copied

Overview

[Project name] - Modular Monolith Web API

Copied

Tech Stack

  • .NET 10, ASP.NET Core Minimal APIs
  • EF Core 10 with PostgreSQL (snake_case naming convention)
  • FluentValidation for request validation
  • Result<T> pattern for error handling (no exceptions for business logic)
  • JWT Authentication with Refresh Tokens
  • OpenTelemetry for tracing and metrics
  • Serilog for structured logging
  • Swagger/OpenAPI for API documentation
  • Docker for containerization
Copied

Architecture

  • Modular Monolith with Vertical Slice Architecture
  • Clean Architecture: domain is isolated from infrastructure
  • Each module: Domain, Core, Infrastructure, PublicApi projects
  • CQRS with manual handlers (no MediatR, no interfaces)
  • Manual mapping with extension methods
Copied

Project Structure

  • src/Modules.[Name].Domain/ - Entities, value objects, enums
  • src/Modules.[Name].Core/ - Endpoints, handlers, validators
  • src/Modules.[Name].Infrastructure/ - DbContext, EF config, migrations
  • src/Modules.[Name].PublicApi/ - Cross-module contracts
  • src/Modules.Common.API/ - Shared endpoint abstractions, error handling
  • src/Modules.Common.Domain/ - Result<T>, IHandler, IEvent interfaces
  • src/ModularMonolith.Host/ - Program.cs, DI composition
Copied

File Naming

  • Features/[UseCaseName]/[UseCaseName].Endpoint.cs
  • Features/[UseCaseName]/[UseCaseName].Handler.cs
  • Features/[UseCaseName]/[UseCaseName].Validator.cs
  • Features/[UseCaseName]/[UseCaseName].Mapping.cs (if 2+ mappings)
  • Features/Shared/Routes/RouteConsts.cs
  • Features/Shared/Errors/[Module]Errors.cs
Copied

Code Conventions

  • Positional records for request/response DTOs
  • File-scoped namespaces
  • Primary constructors for dependency injection
  • Sealed classes for implementations
  • Internal by default, public only for contracts
Copied

Patterns We Use

  • Result<T> pattern for all handler return types
  • IHandler marker interface for auto-registration
  • IApiEndpoint for endpoint registration
  • RouteConsts for centralized route definitions
  • FluentValidation validators per use case
  • Bogus for test data seeding
  • EF Core DbContext directly in handlers
Copied

Patterns We Do NOT Use

  • Repository pattern
  • AutoMapper or any mapping library
  • MediatR or any mediator library
  • Exceptions for business logic flow
  • [FromServices] attribute
Copied

Testing

  • xUnit for test framework
  • Moq for mocking
  • Testcontainers for integration tests (PostgreSQL)
  • Respawn for database cleanup between tests
  • NetArchTest.Rules for architecture tests
  • Test naming: [Method][Scenario][ExpectedResult]
Copied

DI Registration

  • Each module: Add[Module]Module(services, configuration)
  • Auto-scan handlers: RegisterHandlersFromAssemblyContaining
  • Auto-scan validators: AddValidatorsFromAssembly
  • Auto-scan endpoints: RegisterApiEndpointsFromAssemblyContaining
**How to reference other files from CLAUDE.md.** For large projects, keep CLAUDE.md under 100 lines and split detailed rules into separate files using the `@` import syntax: ```markdown @.claude/rules/architecture.md @.claude/rules/testing.md @.claude/rules/api-conventions.md

You can also create module-specific rules that only apply to certain paths. Place them in .claude/rules/ with a YAML frontmatter:

markdown
--- paths: - src/Modules.Users/** ---

Users Module Rules

  • Uses ASP.NET Core Identity for user management
  • JWT tokens with refresh token rotation
  • Policy-based authorization with UserPolicyConsts
With CLAUDE.md in place, your specification prompt becomes much shorter. Claude already knows your project structure, file naming, patterns, and conventions. The prompt only needs to describe the business-specific content: entities, endpoints, and business rules. Here is the prompt I use: ```markdown Based on the architecture we designed, create a detailed Backend Implementation Specification as a Markdown file. The specification must include: 1. Entity Definitions - All entities as C# classes with property types - Value objects and enums - Entity relationships 2. Database - EF Core mapping configuration for each entity - EF Core Migrations - Seeding strategy with sample data using Bogus 3. API Endpoints - For each endpoint: HTTP method, route, request body, response body with C# record definitions - Business rules and validation rules per endpoint - Error scenarios and expected error responses 4. Authentication and Authorization - Which endpoints require authentication - Which endpoints require specific policies or roles

There is no need to describe file naming, handler patterns, DI registration, or project structure. Claude already knows all of that from CLAUDE.md.

I iterate on this specification until it covers every feature. Every hour spent on the specification saves 3-5x as many hours of rework, rewriting and debugging generated code.

Copied

Step 5: Code the Backend

This is the core implementation step. With CLAUDE.md and the specification already in place, the implementation prompt is short. Claude already knows your architecture, patterns, file naming, and conventions.

It has the specification with all entities, endpoints, and business rules. The prompt just needs to connect the two.

Here is the prompt I use:

markdown
You are a Principal Developer producing code of exceptional quality, following Clean Code principles. Your code is a pleasure to read, maintain and work with. Read the Backend Specification file and implement all features. Follow existing code patterns - see @file:CreateShipment.Endpoint.cs, @file:CreateShipment.Handler.cs, and @file:CreateShipment.Validator.cs as reference examples.

That is it. Three sentences plus a few @file references.

This works because Claude combines context from multiple sources:

  • CLAUDE.md provides architecture, patterns, file naming, and conventions
  • The specification provides entities, endpoints, business rules, and validation
  • @file references provide concrete code examples to follow

The @file references are the most powerful technique in the entire workflow. Instead of describing your patterns in words, you point to actual code files.

Claude reads them and follows the same style. If you want AI to generate high-quality code, you must provide high-quality code examples for it to follow.

Copied

Step 6: Review and Refine

After generating the backend code and all the tests pass, review it.

I want a fresh look at the code while reviewing. That's why I opened a new session in Claude to reset the context. I use a three-pass review approach. Each pass focuses on a different aspect:

markdown
Review the generated code with three passes: Pass 1 - Code Quality: - Are naming conventions consistent across all files? - Are all handlers following the same pattern? - Are there any unused imports or dead code? - Is the code DRY without being over-abstracted? Pass 2 - Performance: - Are there any N+1 query issues in EF Core calls? - Are there any unnecessary database round-trips? - Are all async methods properly awaited? - Are CancellationTokens passed through the entire call chain? Pass 3 - Security: - Are all endpoints properly authorized? - Are all user inputs validated before processing? - Are there any SQL injection or XSS vulnerabilities? - Are sensitive data fields excluded from responses? - Are sensitive data fields excluded from logging? For each issue found, show the file, the problem, and the fix.

Claude can find its own mistakes when you ask specific questions. The key is being specific. "Review this code" produces generic feedback. "Check for N+1 queries in EF Core" produces actionable findings.

After fixing issues, I also run architecture tests to verify that the generated code follows the intended architecture. I have a set of architecture test examples, and I use them as a reference to quickly write them with AI for my project.

I also ask AI to create HTTP request files in my IDE (supported by Visual Studio, Visual Studio Code and JetBrains Rider) for each endpoint.

You should never fully trust any AI-generated code. Run the application, test the endpoints manually, and verify the database queries.

AI catches patterns, but humans catch business logic errors.

Copied

Step 7: Generate the Frontend Specification

The frontend needs its own specification, separate from the backend.

I call this a Product Document Requirement (PDR). The PDR references the backend API and includes everything a frontend developer needs to build the UI.

Here is the prompt I use to generate the PDR:

markdown
Based on the implemented backend, create a Frontend Product Document Requirement (PDR) as a Markdown file. The PDR must include: 1. Authentication Flow - Login page: POST /api/users/login request/response - Store JWT token, call GetMe after login - Refresh token flow: intercept 401 responses, call POST /api/users/refresh, retry original request - Logout: clear tokens and redirect to login 2. For Each Page - API endpoints it calls with an exact JSON request and response examples - UI layout: which fields to display, form inputs, table columns - Actions: create, update, delete buttons with their API calls - Validation rules matching backend validators - Error handling: how to display API errors to the user 3. Conditional Rendering - Read authorization policies from @file:UserPolicyConstants.cs - Show/hide action buttons based on HATEOAS links in API responses - Show/hide pages in navigation based on user claims 4. Paging - How to call paginated endpoints - Request parameters (page, pageSize) - Response shape (items, totalCount, totalPages) - UI: page controls, page size selector Include complete JSON examples for every request and response so the frontend implementation requires zero guessing about the API contract.

Notice the @file:UserPolicyConstants.cs reference. This tells Claude to read the actual backend policy constants and use the exact claim names in the PDR.

The generated PDR should be so good that a real front-end developer can implement UI without any additional questions. And the same goes with Claude code.

The PDR bridges backend and frontend by including the exact JSON shapes for every endpoint.

Create a separate CLAUDE.md for the frontend.

Here is a concise frontend CLAUDE.md example:

markdown
undefined

CLAUDE.md - Frontend

Copied

Tech Stack

  • React 19 with TypeScript
  • Axios for HTTP communication
  • TailwindCSS 4.x for styling
  • @heroicons/react for icons
  • Zustand for state management
Copied

Architecture

  • Vertical Slice Architecture: organize by feature, not by type
  • Each feature: page component, API service, types, child components
Copied

Project Structure

  • src/features/[feature-name]/ - Page, components, service, types
  • src/shared/components/ - Reusable UI components
  • src/shared/hooks/ - Custom hooks (useAuth, useApi)
  • src/shared/lib/api.ts - Axios instance with interceptors
  • src/shared/types/ - Shared TypeScript types
Copied

Conventions

  • Server URL in .env file (VITE_API_URL)
  • Typed API service per feature (never raw Axios calls in components)
  • Axios interceptor for 401 -> refresh token flow
  • Conditional rendering based on HATEOAS links in API response
Copied

Patterns We Do NOT Use

  • Redux or React context + hooks
  • CSS modules (use TailwindCSS)
  • Default exports (use named exports)
This is enough for Claude to generate a consistent frontend structure. The PDR provides the implementation details; the CLAUDE.md provides the conventions.
Copied

Step 8: Code the Frontend

Just like the backend, the frontend prompt is short when CLAUDE.md and the PDR are already in place.

Claude knows your tech stack and conventions from CLAUDE.md. It knows every page, endpoint, and JSON shape from the PDR. The prompt just connects them.

Here is the prompt:

markdown
You are a Principal Developer producing code of exceptional quality, following Clean Code principles. Your code is a pleasure to read, maintain and work with. Read the PDR file and implement a professional, production-ready UI. Follow the frontend CLAUDE.md for tech stack and conventions. UI requirements: - Clean, professional design with ###### as accent color - Rounded borders on all interactive elements - Responsive layout for desktop, tablet, mobile - Loading states for all API calls - Error messages displayed inline near the relevant fields - Follow the attached screenshots for UI mockups

The prompt focuses only on what CLAUDE.md and the PDR do not cover: visual design preferences. Everything else - pages to build, API calls to make, conditional rendering rules, paging behavior - is already in the PDR.

For an existing project with established UI components, make the prompt even shorter and add @file references to existing pages:

markdown
Read the PDR file and implement the remaining features. Follow the patterns in @file:UsersPage.tsx and @file:LoginPage.tsx.

This is the power of the specification-first approach: each step builds on the previous one. By the time you reach the frontend implementation, most decisions are already made and documented.

P.S. If you use Claude, you can connect a Figma MCP and let your AI talk to Figma and generate the UI code with better quality.

Copied

Step 9: Automate Deployment with CI/CD

With the backend and frontend working, the next step is to automate deployment.

Here is the prompt I use for generating CI/CD pipelines:

markdown
Create a GitHub Actions CI/CD pipeline for this project. The pipeline should: 1. Trigger on push to main and pull requests 2. Backend (.NET): - Restore, build, and run all the tests - Build Docker image - Push to private GitHub container registry 3. Frontend (React): - Install dependencies - Run linter and tests - Build production bundle 4. Deploy to [your target environment] Use separate jobs for backend and frontend so they run in parallel. Cache NuGet packages and npm modules for faster builds. Use environment variables for secrets (never hard-code them).

Adjust the deployment target to match your infrastructure. Whether it is Azure App Service, AWS ECS, a Kubernetes cluster, or a simple VPS with Docker Compose, the prompt should specify the exact target.

Copied

Step 10: Human Review, Test, and Deploy

This final step is entirely human.

Run the application end to end. Test every user flow manually. Click through the UI. Call every API endpoint. Verify that error messages make sense. Check that authorization works correctly for different user roles.

Review the generated code yourself. Read through the handlers, validators, and endpoints. Look for business logic errors that the AI might have missed. AI is excellent at following patterns, but it does not understand your business domain as well as you do.

Test edge cases. What happens when you submit an empty form? What happens when two users edit the same record simultaneously? What happens when the database is down?

When you find issues, go back to Claude with specific feedback. Reference the actual file and line:

markdown
In CreateOrder.Handler.cs, the handler does not check if the customer exists before creating the order. Add a check that returns Error.NotFound if the customer ID is invalid.

Specific feedback produces specific fixes. "The order creation is broken" produces confusion.

P.S.: You can also use AI to help you create test cases for automated and manual testing. Often, AI creates a more detailed set of tests than a human. But it can't reason the same way as a human, and doesn't know all the nuances and details. Always review the AI-generated tests, add and refine them as needed.

Copied

Prompt Engineering Principles for Production Code

After using this workflow on multiple projects, I distilled the following principles:

1. Specificity beats cleverness. A 30-line prompt with explicit instructions produces better code than a 3-line prompt with a clever framing. Tell Claude exactly what files to create, what patterns to follow, and what conventions to use.

2. Reference existing code with @file. This is the single most impactful technique. Instead of describing your patterns in words, point to actual code files. Claude reads them and follows the same style.

3. Separate planning from coding. Never ask Claude to design the architecture and write the code in the same prompt. The planning steps (1-4) produce specification documents. The coding steps (5, 8) consume those documents. This separation keeps each step focused.

4. Use specifications as contracts. The Markdown specification file is a contract between you and Claude. If the generated code does not match the spec, that is a specific, fixable problem. Without a spec, you have no way to evaluate whether the output is correct.

5. Review in phases. When reviewing generated code, focus on one aspect at a time: first code quality, then performance, then security. Each phase reveals issues the others miss.

6. The human is the architect. Claude proposes, you decide. Never accept an architecture recommendation without understanding why it was suggested and whether it fits your constraints. Challenge every proposal.

7. Iterate, do not rewrite. When Claude generates code with issues, fix the issues. Do not throw everything away and start over. The generated code usually has the right structure. The problems are in the details.

The biggest mistake I made when I started this workflow was asking Claude to plan and code in a single prompt. The output was mediocre because Claude was trying to make too many decisions at once. Splitting into separate steps, each building on the previous one, was the change that made everything click.

Copied

Bottom Line

This workflow is, in principle, tool-agnostic, but I use Claude Code with Opus 4.7 for a reason.

Code quality. Opus produces clean, well-structured code that follows conventions consistently. It understands the relationships between the backend and the frontend, so complex refactorings do not break dependencies across layers.

Deep reasoning. Through Extended Thinking and Plan Mode, Opus reasons through trade-offs and edge cases before writing code. This matters most during architecture design (Step 3) and specification generation (Step 4), where bad decisions are expensive to fix later.

Large context window. With 1M tokens of context, Opus can hold your entire CLAUDE.MD, specification file, and hundreds of file references at once. It sees the full picture instead of working with fragments.

I use Claude Opus for planning, main implementation, code reviews, creating test cases, and generating specifications. I use Claude Sonnet for smaller iterations, writing tests, and quick fixes where deep reasoning is not required.

Claude Code plans (April, 2026):

  • Pro plan ($20/month) - Opus with limited usage. Good for smaller and medium-sized projects.
  • Max plan ($100/month) - Opus with extended usage. This is what I use for complex projects.

Alternative: Codex Agent. OpenAI's Coding Agent that works with OpenAI models. It follows a similar pattern of reading your codebase and generating code. If you are already invested in the OpenAI ecosystem, Codex CLI is worth exploring.

Based on my experience, Claude produces code with much higher quality than Codex. Claude is a bit faster, with better reasoning and a bigger context window.

The workflow I described in this post applies regardless of which tool you choose. The principles - specifications before code, @file references, structured prompts - work with any AI coding assistant.

This workflow works because it mirrors how experienced developers already think. AI does not change the process. It accelerates every step within it.

P.S.: Before starting a new project, read this article on how to start a new .NET project with a proper base from day one.

Did you like this article on using AI? Would you like me to write more or less content on AI topics? Respond to this email with your thoughts. I read every response.

Hope you find this newsletter useful. See you next time.

Whenever you're ready, here's how I can help you:

The .NET Senior Playbook β€” 800+ real-world interview questions with expert answers across 50 chapters. You try to answer each question first, then reveal the full solution β€” and a test after every chapter proves it actually stuck. Finish, and you earn a verifiable certificate for your LinkedIn.

Chapter-test results with a per-answer explanation
View the Playbook

Enjoyed this article? Share it with your network

Improve Your .NET and Architecture Skills

Join my community of 25,000+ developers and architects.

Each week you will get 1 practical tip with best practices and real-world examples.

Learn how to craft better software with source code available for my newsletter.

Join 25,000+ developers already reading
No spam. Unsubscribe any time.