Skip to content

Developer Tools · Best Practices

How Our Developers Actually Use AI in Production — No Hype, Just the Real Workflow

Forget the demos. Here is how our 7-person engineering team uses AI tools on real client projects every day — the prompts we write, the mistakes we catch, and the time we actually save.

Anurag Verma

Anurag Verma

12 min read

How Our Developers Actually Use AI in Production — No Hype, Just the Real Workflow

Sponsored

Share

Twitter is full of AI coding demos where someone builds a complete SaaS app in 10 minutes from a single prompt. These demos are impressive and completely misleading. They show Day 1. They never show Day 30, when the app needs to handle real users, real edge cases, real security requirements, and real bugs that happen at 2 AM.

At CODERCOPS, we use AI tools on production client projects every single day. Not demos. Not weekend projects. Real software that real people depend on. And the way we use AI in production looks nothing like the viral demos.

Here is an honest look inside our actual workflow: the tools, the prompts, the mistakes we catch, and the time we genuinely save.

Developer Workflow Production AI usage is less glamorous and more useful than the demos suggest.

The Ground Rules

Before showing the workflow, here are the rules our team follows. We wrote these after learning painful lessons during our first few months of AI-assisted production development:

  1. Never ship code you cannot explain. If you cannot describe what a function does and why it does it that way, you have not reviewed it. Do not merge it.

  2. AI writes the first draft. You own the final version. Treat AI output like a pull request from a junior developer. It might be great, it might have subtle bugs, and it is your responsibility either way.

  3. Security-critical code gets extra scrutiny. Authentication, authorization, payment processing, data encryption, input validation: these paths get manual line-by-line review regardless of who or what generated them.

  4. Specify before you generate. Write a clear specification of what you want before asking the AI to build it. Vague prompts produce vague code.

  5. Run the tests. All of them. Every time. AI-generated code that passes the existing test suite is not the same as correct code, but it is a necessary minimum.

A Typical Day

Here is what a typical development day looks like for one of our senior engineers:

8:30 AM — Morning Review

The day starts with reviewing any AI-generated pull requests from the previous evening. Some of our team members kick off long-running Claude Code tasks at the end of their day and review the results the next morning.

# Morning routine: check what Claude Code produced overnight
$ git log --oneline -5
a3f2d1e Add pagination to /api/projects endpoint
8b4c9f7 Refactor NotificationService to use queue-based delivery
f1e8a23 Add unit tests for billing webhook handler
2c7d9b4 Fix N+1 query in dashboard project listing
e5a1f6c Update error messages to match client style guide

Each of these gets a full diff review. We look for:

  • Correctness (does it do what the specification asked?)
  • Security (any new attack vectors introduced?)
  • Performance (any O(n²) patterns hiding in loops?)
  • Style (does it match our coding conventions?)
  • Tests (do the new tests actually test meaningful behavior?)

9:00 AM — Specification Writing

Before touching AI tools for new work, the developer writes a specification. This is the single highest-leverage activity in our workflow.

Here is a real specification from a recent project:

## Task: Add CSV export to the analytics dashboard

### Requirements:
- Add "Export CSV" button to the analytics dashboard header
- Export includes: project name, task count, completion rate,
  avg time to complete, date range
- Date range comes from the existing date picker component
- File name format: analytics-export-{YYYY-MM-DD}.csv
- Maximum 10,000 rows per export (show warning if more)
- Show loading spinner during export generation
- Handle errors gracefully — show toast notification on failure

### Technical Details:
- Generate CSV server-side via API route POST /api/analytics/export
- Use the existing analytics query in src/lib/data/analytics.ts
- Stream the response for large datasets (do not buffer in memory)
- Add rate limiting: max 5 exports per user per hour
- Log export events to the audit table

### Edge Cases:
- Empty dataset: show "No data to export" message instead of
  downloading an empty file
- User navigates away during export: cancel the request
- Concurrent export requests from same user: queue, do not parallelize

### NOT in scope:
- PDF export (future task)
- Custom column selection (future task)
- Scheduled/automated exports (future task)

This level of detail takes 15-20 minutes to write. But it means the AI generates correct code on the first attempt about 80% of the time, versus 30-40% with a vague specification. The 15 minutes of specification writing saves 1-2 hours of debugging and iteration.

10:00 AM — Feature Implementation with AI

With the specification written, the developer uses Cursor Composer to generate the implementation:

Implement the CSV export feature based on this specification:
[paste specification]

Follow the patterns in this project:
- API routes in src/app/api/
- Data access in src/lib/data/
- Components in src/components/
- Use the existing Button and Toast components
- Zod validation for request parameters
- Tests in src/tests/ using Vitest

Cursor generates changes across 5-6 files. The developer reviews each file:

File 1: API route. Looks good. Correct streaming pattern. But the rate limiting implementation uses an in-memory counter that would reset on server restart. Fix: switch to Redis-based rate limiting using our existing rate limit utility.

File 2: Data access function. Correct query, but missing the index hint for the date range filter. On large datasets, this would be slow. Fix: add the appropriate index and hint.

File 3: React component. Clean implementation. Loading state handled correctly. But the “Cancel export” behavior when navigating away uses useEffect cleanup that does not actually abort the fetch request. Fix: add AbortController properly.

File 4: Zod schema. Correct validation. No issues.

File 5: Tests. Good coverage of happy paths. Missing tests for rate limiting and the empty dataset edge case. Fix: add 3 additional test cases.

Total time: 45 minutes for review and fixes. The AI got us 80% of the way there. The remaining 20% required human judgment about performance, reliability, and edge cases.

12:00 PM — Debugging with AI

After lunch, a bug comes in. A client reports that their dashboard is loading slowly: 8 seconds for a page that should take under 1 second.

$ claude

> The client reports the /dashboard page is loading in 8 seconds.
> Expected load time is under 1 second.
> Investigate the performance issue, focusing on database queries
> and API response times. Check the query patterns in
> src/lib/data/dashboard.ts and look for N+1 queries or
> missing indexes.

Claude Code:

  1. Reads src/lib/data/dashboard.ts
  2. Identifies an N+1 query pattern. The dashboard fetches projects, then loops through each project to fetch its tasks individually
  3. Proposes a fix: replace the loop with a single join query
  4. Implements the fix
  5. Runs the existing tests — all pass
  6. Reports the expected improvement (from N+1 queries to 1 query)

The developer reviews the fix, verifies the query is correct, and checks that the join does not pull unnecessary data. The fix is correct. Total debugging time: 15 minutes instead of the 1-2 hours it would have taken to manually trace through the code, identify the N+1 pattern, and implement the fix.

2:00 PM — Test Generation

The team’s policy is that every PR needs test coverage. AI makes this policy sustainable:

$ claude

> Write comprehensive tests for the WebhookService class in
> src/services/webhook.ts. Include tests for:
> - Successful webhook delivery
> - Retry logic on failure (3 retries with exponential backoff)
> - Signature verification (HMAC-SHA256)
> - Payload size limits
> - Concurrent delivery to multiple endpoints
> - Timeout handling
> - Idempotency key deduplication
>
> Use Vitest. Follow the test patterns in src/tests/services/
> for structure and naming conventions.

Claude Code generates a test file with 14 test cases. The developer reviews:

  • 11 tests are correct and meaningful
  • 2 tests have incorrect assertions (testing implementation details rather than behavior). Fixed
  • 1 test is redundant with an existing test. Removed

Total time: 20 minutes for a comprehensive test suite that would have taken 1.5-2 hours to write manually.

3:30 PM — Code Review

The developer reviews PRs from teammates. Some are human-written, some are AI-generated. The review process is the same for both.

What we look for in AI-generated code specifically:

AI Code Review Checklist
├── Does it handle null/undefined inputs?
├── Are error messages helpful for debugging?
├── Does it use our project's error handling patterns?
├── Are database queries efficient (no N+1, proper indexes)?
├── Is the type safety complete (no `any` types)?
├── Are there hardcoded values that should be config/env variables?
├── Does it handle concurrent access correctly?
├── Are there race conditions in async code?
├── Does input validation cover all attack vectors?
└── Are the tests testing behavior, not implementation?

About 70% of AI-generated PRs pass review with minor comments. 25% need meaningful changes (usually security or performance related). 5% need to be substantially rewritten.

4:30 PM — Kick Off Overnight Tasks

Before wrapping up, the developer starts Claude Code tasks that can run asynchronously:

$ claude

> Refactor the email template system to use React Email instead
> of the current string-based templates. Here is the migration plan:
> [paste specification]
>
> Implement the migration for all 12 templates. Run the tests
> after each template migration. Create a single commit per
> template with a descriptive message.

Claude Code will work through this over the next 30-60 minutes. The developer will review the results first thing tomorrow morning.

The Prompts That Work vs. The Prompts That Fail

After thousands of interactions, we have learned what makes a prompt produce good output:

Bad Prompt (vague, no context)

Fix the authentication bug

Result: AI guesses what the bug might be, often fixing something that is not broken.

Good Prompt (specific, contextual, constrained)

The login endpoint POST /api/auth/login returns a 500 error when
the email contains a '+' character (e.g., test+tag@example.com).

The error is in src/lib/auth/login.ts. The email validation regex
on line 23 does not account for the '+' character which is valid
per RFC 5322.

Fix the regex to accept valid email addresses with '+' characters.
Update the test file src/tests/auth/login.test.ts to include a
test case for email addresses with '+' characters.

Do not modify any other validation logic.

Result: AI fixes exactly the right thing, in the right place, and adds the right test.

The Difference

Good prompts include:

  • What is wrong (specific symptom)
  • Where it is wrong (file and line number when possible)
  • Why it is wrong (root cause if known)
  • What the fix should do (expected behavior)
  • What it should NOT touch (scope constraints)

The Time We Actually Save

We track this quarterly. Here are our numbers from Q1 2026:

Task CategoryTime Without AITime With AISavings
Feature implementation8 hours avg4.5 hours avg44%
Bug fixing2 hours avg45 min avg63%
Test writing1.5 hours avg25 min avg72%
Code review (per PR)45 min avg35 min avg22%
Documentation2 hours avg40 min avg67%
Codebase onboarding5 days avg2 days avg60%

Net time saved per engineer per week: 6-8 hours.

But also, time lost to AI mistakes per week: 1-2 hours (debugging incorrect AI output, reverting bad changes, re-reviewing work that looked correct but was not).

Net-net time saved: 5-6 hours per engineer per week. Not the 10x improvement some vendors promise. A genuine, measurable, meaningful improvement that compounds across a team.

What AI Cannot Do In Production

To be clear about the limits:

AI cannot make product decisions. It can implement any feature you describe, but it cannot tell you which features your users actually need.

AI cannot navigate organizational politics. Your code needs to integrate with Team B’s API and they changed the contract without telling you? That requires a Slack message, not a prompt.

AI cannot understand your users. The subtle difference between “technically correct” and “what the user actually expects” is a judgment call that requires empathy and context that AI does not have.

AI cannot own the outcome. When the production system breaks at 2 AM, a human needs to understand the system well enough to fix it under pressure. You cannot prompt your way out of an outage.

The Bottom Line

AI in production is not about writing code faster. It is about spending less time on the parts of development that do not require human judgment (boilerplate, repetitive patterns, initial test scaffolding, documentation) so you can spend more time on the parts that do.

The developers on our team who get the most from AI tools are not the ones who use them the most. They are the ones who use them the most strategically: reaching for AI when it saves time without sacrificing quality, and doing the work manually when the stakes are too high to trust a machine.

That judgment, knowing when to delegate to AI and when to do it yourself, is the core skill of production development in 2026.


Want to See This Workflow in Action?

At CODERCOPS, we use these workflows to build production software for clients across industries. If you are curious about how AI-powered development could accelerate your project, let us show you.


This post describes our production workflows as of May 2026. Our processes evolve continuously as the tools improve.

Sponsored

Enjoyed it? Pass it on.

Share this article.

Sponsored

The dispatch

Working notes from
the studio.

A short letter twice a month — what we shipped, what broke, and the AI tools earning their keep.

No spam, ever. Unsubscribe anytime.

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored