👋Hi, I'm Waqas — a Software Architect and Technical Consultant specializing in .NET, Azure, microservices, and API-first system design..
I help companies build reliable, maintainable, and high-performance backend platforms that scale.
How Developers Are Integrating AI Into Daily Workflows
Integrating AI into dev workflows: completion, chat, refactors, tests, and review.
November 27, 2024 · Waqas Ahmad
Read the article
Introduction
Integrating AI into daily workflows is no longer a one-off experiment—teams need to decide where and how to use completion, chat, refactors, tests, and review without sacrificing quality or hitting a productivity plateau. This article describes concrete patterns: how developers weave AI into coding, review, documentation, and debugging, when to use it (repetition and scaffolding) vs when to keep humans in the loop, and what works vs what backfires. For developers and tech leads, getting the balance right—treating AI as a draft source and reviewing everything—sustains gains and avoids debt; we link to Current State of AI Coding Tools, Cursor vs Copilot vs Claude Code, and Why AI Productivity Gains Plateau.
When this applies: Developers or teams integrating AI into daily workflows (completion, chat, refactors, tests, review) who want practical patterns and norms.
When it doesn’t: Readers who only want a tool comparison or who don’t use AI yet. This article is about where and how to use AI in the loop and how to review.
Scale: Any team size; the workflows (completion, chat, etc.) and the need for review and norms hold regardless.
Constraints: Success depends on review and norms; without them, integration can increase debt or plateau.
Non-goals: This article doesn’t recommend a single tool; it describes workflows and conditions for sustainable use.
What “integrating AI” means in practice
Integrating AI means routinely using AI tools as part of writing, reading, changing, and reviewing code—not as a one-off. That includes inline completion (accept or edit suggestions as you type), chat (ask how something works or how to implement X), multi-step refactors (e.g. rename, extract, add tests), and review assistance (AI-suggested PR comments). Success depends on when you use it and how you review output—see Trade-Offs of Relying on AI for Code Generation and Impact on Code Quality.
What “routinely” looks like:Completion dozens of times a day for boilerplate and obvious next lines; chat a few times a day for explanations, design questions, or debugging; refactors (single or multi-file) when you have a clear scope; test and doc generation for scaffolding; review tools as a first pass on PRs. The key is consistency—same review bar for AI output as for human-written code, and ownership for every change that ships.
AI in daily workflows at a glance
Workflow
How AI is used
Risk if unchecked
Completion
Tab-complete, accept or edit
Over-accepting wrong or brittle code
Chat
Explain, design, debug
Trusting design or security advice
Refactors
Single/multi-file edit
Breaking callers or contracts
Tests
Generate unit/integration tests
Shallow tests, missed edge cases
Docs
Comments, README, API docs
Stale or wrong docs
Review
AI-suggested PR comments
Missing design/security issues
Loading diagram…
How to read the table: Each workflow (completion, chat, refactors, tests, docs, review) has a typical AI use and a risk if you do not check output. Completion is highest volume; chat is second; refactors, tests, docs, and review are more selective. The common thread: use AI for speed and scaffolding, but review and own the result so quality stays high—see Impact on code quality.
Completion: when and how to use
Completion (tab-complete) is the most common integration: you type, AI suggests the next line or block. Use it for boilerplate (DTOs, mappers, getters/setters), repetitive patterns (repository impl, dependency injection wiring), tests for simple cases (arrange/act/assert scaffold), and obvious next steps (closing braces, return statements). Do not accept blindly: read and edit; reject when it guesses APIs (wrong method or version), business rules, or edge cases (e.g. null, empty list) wrong. Fits well with Clean Architecture when you complete within one layer so suggestions stay bounded. See What AI IDEs Get Right — and What They Get Wrong.
Concrete examples:Good: Accept completion for a property list that matches your entity; tweak naming if needed. Good: Accept test scaffold (mocks, assert) and addedge-case tests yourself. Bad: Accept completion that calls an API you do not have (e.g. .NET 7+ in a .NET 6 project — see Example 2) or that violates your layering (e.g. controller calling repository directly — see Example 1). Mitigation:Scan every suggestion; run tests and linters before commit. For full code-level examples of what bad and good look like (exact prompts, full bad output, and full corrected code), see the next section.
Code-level examples: prompts, bad output, and fixes
The following examples show exact prompts you might type, fullbad AI output (what the model returns in theory), what goes wrong at build or runtime, and fullcorrect code. Each scenario is concrete at code level so you can see the issues, not just read about them. Use these as checklists when reviewing AI-generated code and when writing prompts so you ask for bounded behaviour.
Example 1: “Add a new order API” — layer violation
Exact prompt (chat or composer):
“Add a new API endpoint to create an order. Accept order details in the request body and save to the database.”
What you get in theory (bad AI output): The model often returns a single controller that talks to the database directly. Full example of the bad code you might receive:
// BAD: Full controller as often suggested by AI — controller does too much, no service layer, direct DBusing Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespaceMyApp.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
publicclassOrderController : ControllerBase
{
privatereadonly AppDbContext _db;
publicOrderController(AppDbContext db)
{
_db = db;
}
[HttpPost]
publicasync Task<IActionResult> Create(OrderRequest request)
{
var order = new Order
{
CustomerId = request.CustomerId,
Total = request.Total,
CreatedAt = DateTime.UtcNow
};
_db.Orders.Add(order);
await _db.SaveChangesAsync();
return Ok(new { order.Id });
}
}
}
What goes wrong at code level: The controller depends on AppDbContext (infrastructure). There is no application layer (use case); validation and business rules are missing or inline. You cannot unit-test the create logic without a real DB; changing persistence (e.g. to a message queue) forces controller changes. This violatesClean Architecture and makes the codebase harder to maintain. See Where AI Still Fails.
Correct approach (full good code): Controller only delegates to an application-layer use case; infrastructure stays in the repository implementation.
// GOOD: Controller delegates to application layer; no direct DB or infrastructure in API layernamespaceMyApp.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
publicclassOrderController : ControllerBase
{
privatereadonly ICreateOrderUseCase _createOrderUseCase;
publicOrderController(ICreateOrderUseCase createOrderUseCase)
{
_createOrderUseCase = createOrderUseCase;
}
[HttpPost]
publicasync Task<IActionResult> Create(OrderRequest request)
{
var result = await _createOrderUseCase.Execute(request);
return result.Match<IActionResult>(
id => Ok(new { Id = id }),
err => BadRequest(new { Error = err })
);
}
}
}
// Application layer — use case uses repository interface onlynamespaceMyApp.Application.Orders
{
publicinterfaceICreateOrderUseCase
{
Task<Result<Guid>> Execute(OrderRequest request);
}
publicclassCreateOrderUseCase : ICreateOrderUseCase
{
privatereadonly IOrderRepository _orderRepository;
publicCreateOrderUseCase(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
publicasync Task<Result<Guid>> Execute(OrderRequest request)
{
if (request.CustomerId == Guid.Empty || request.Total < 0)
return Result<Guid>.Failure("Invalid request");
var order = new Order(request.CustomerId, request.Total);
await _orderRepository.AddAsync(order);
return Result<Guid>.Success(order.Id);
}
}
}
// Infrastructure: IOrderRepository implemented with DbContext in a separate project/layer
Takeaway: Either narrow the prompt (e.g. “Add a use case for CreateOrder that uses our existing IOrderRepository and a controller that calls it”) or review and reject any controller that touches DbContext or infrastructure directly.
Example 2: Completion — wrong API or framework version
Context: You are in a .NET 6 project. You type something like if (string.IsNullOrEmpty(customerName)) and the IDE suggests the next line, or you ask completion to “add a guard for null or empty name.”
What you get in theory (bad AI output): Completion may suggest .NET 7+ APIs that do not exist in .NET 6. Full method as suggested:
// BAD (in a .NET 6 project): ThrowIfNullOrEmpty is available only in .NET 7+publicvoidProcessCustomer(string customerName)
{
ArgumentException.ThrowIfNullOrEmpty(customerName);
// ... rest of method
}
What goes wrong at code level:Build fails with an error such as: 'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'. If the API existed but behaved differently across versions, you could get runtime issues in production. So the result in theory is a compile error and broken CI until you fix it.
Correct approach (full good code for .NET 6):
// GOOD for .NET 6: explicit check, no dependency on .NET 7+ APIspublicvoidProcessCustomer(string customerName)
{
if (string.IsNullOrEmpty(customerName))
thrownew ArgumentException("Customer name is required.", nameof(customerName));
// ... rest of method
}
Takeaway: Always review imports and API usage; pin target framework in the project file; run build in CI so version mismatches are caught. See Where AI Still Fails.
Example 3: Chat “fix this query” — SQL injection
Exact prompt:
“Here’s my code that builds a SQL query from user input. Fix it so it works with our database.”
(Then you paste something like: var sql = "SELECT * FROM Users WHERE Name = '" + userInput + "'";)
What you get in theory (bad AI output): The model may “fix” formatting or small issues but leave user input concatenated into the SQL string. Full bad example:
// BAD: User input concatenated into SQL — SQL injectionpublicasync Task<List<User>> FindUsersByName(string userInput)
{
var sql = "SELECT * FROM Users WHERE Name = '" + userInput.Replace("'", "''") + "'";
var users = await _db.Users.FromSqlRaw(sql).ToListAsync();
return users;
}
What goes wrong at code level: An attacker sends userInput = "'; DROP TABLE Users; --". The resulting SQL becomes:
SELECT*FROM Users WHERE Name =''; DROPTABLE Users; --'
The database executes both the SELECT and the DROP. So the result in theory is data loss and security breach. Escaping quotes is not sufficient; parameterisation is required. See OWASP and Securing APIs.
Correct approach (full good code):
// GOOD: Parameterised query; user input never concatenated into SQLpublicasync Task<List<User>> FindUsersByName(string userInput)
{
returnawait _db.Users
.FromSqlRaw("SELECT * FROM Users WHERE Name = {0}", userInput)
.ToListAsync();
}
// Or use LINQ: _db.Users.Where(u => u.Name == userInput).ToListAsync();
Takeaway:Never trust AI for auth, secrets, or injection-prone code. Human security review is required for any code that touches user input and SQL or shell commands. See Where AI Still Fails.
Example 4: Generated unit test — shallow, no edge cases
Exact prompt (chat):
“Generate unit tests for this method: public decimal GetTotal(Order order) that sums line items.”
What you get in theory (bad AI output): Often one test, happy path only, with weak or incomplete assertions. Full bad example:
// BAD: Happy path only; no null/empty; weak assertionpublicclassGetTotalTests
{
privatereadonly OrderCalculator _sut = new OrderCalculator();
[Fact]
publicvoidGetTotal_ReturnsSum()
{
var order = new Order
{
LineItems = new List<LineItem>
{
new LineItem { Amount = 10 },
new LineItem { Amount = 20 }
}
};
var result = _sut.GetTotal(order);
Assert.NotNull(result);
Assert.Equal(30, result);
}
}
What goes wrong at code level:Production may pass order == null or order.LineItems == null or empty list. The implementation might throw NullReferenceException or return 0; the tests do not cover these, so you get false confidence and bugs in production. The result in theory is a production incident when a null or empty order is passed. See How AI Is Changing Code Review and Testing and Impact on Code Quality.
Correct approach (full good tests): Add edge cases and explicit behaviour assertions.
// GOOD: Edge cases and behaviour assertedpublicclassGetTotalTests
{
privatereadonly OrderCalculator _sut = new OrderCalculator();
[Fact]
publicvoidGetTotal_WhenOrderNull_ThrowsArgumentNullException()
{
Assert.Throws<ArgumentNullException>(() => _sut.GetTotal(null));
}
[Fact]
publicvoidGetTotal_WhenLineItemsNull_ThrowsOrReturnsZero_AccordingToSpec()
{
var order = new Order { LineItems = null };
// If spec says throw: Assert.Throws<...>(() => _sut.GetTotal(order));// If spec says return 0:var result = _sut.GetTotal(order);
Assert.Equal(0, result);
}
[Fact]
publicvoidGetTotal_WhenLineItemsEmpty_ReturnsZero()
{
var order = new Order { LineItems = new List<LineItem>() };
var result = _sut.GetTotal(order);
Assert.Equal(0, result);
}
[Fact]
publicvoidGetTotal_WhenLineItemsPresent_ReturnsSum()
{
var order = new Order
{
LineItems = new List<LineItem>
{
new LineItem { Amount = 10 },
new LineItem { Amount = 20 }
}
};
var result = _sut.GetTotal(order);
Assert.Equal(30, result);
}
}
Takeaway: Use AI for scaffold only; add null, empty, boundary, and business-rule tests yourself; review assertion quality. See Testing strategies.
Example 5: Multi-file refactor — broken caller (missing await)
Exact prompt (composer/codebase):
“Rename GetOrderById to GetOrderAsync and make it async; update all callers.”
What you get in theory (bad AI output): The repository is updated correctly, but one caller is missed or not updated. Repository change:
// New signature in IOrderRepository / OrderRepositorypublicasync Task<Order?> GetOrderAsync(Guid id, CancellationToken ct = default);
One caller still looks like this (bad):
// BAD: Caller not updated — GetOrderAsync returns Task<Order?>, but caller doesn't awaitpublicasync Task<OrderSummary> GetOrderSummary(Guid id)
{
var order = _orderRepo.GetOrderAsync(id); // order is Task<Order?>, not Order?if (order == null) returnnull; // comparison wrong: Task is never nullreturnnew OrderSummary(order.Total); // order.Total fails: order is Task, not Order
}
What goes wrong at code level:Compiler may error on order.Total (operator not defined for Task<Order?>). If you force it (e.g. by ignoring the warning), runtime will use a Task object where an Order is expected and fail. So the result in theory is compile or runtime failure in that caller.
Correct approach (full good code for caller):
// GOOD: Caller updated to awaitpublicasync Task<OrderSummary?> GetOrderSummary(Guid id)
{
var order = await _orderRepo.GetOrderAsync(id);
if (order == null) returnnull;
returnnew OrderSummary(order.Total);
}
Takeaway: For multi-file refactors, review every call site; run tests after applying changes; use small commits so you can revert. See Refactors: single-file and multi-file.
Example 6: Dependency injection — wrong lifetime (captured dependency)
Exact prompt (chat):
“Register our services in DI. We have OrderService, PaymentService, and EmailSender.”
What you get in theory (bad AI output): All services registered as Singleton or Scoped in a way that captures a scoped dependency in a singleton. Full bad example:
// BAD: OrderService is Singleton but depends on DbContext (Scoped) — captured dependency
services.AddDbContext<AppDbContext>(options => ..., ServiceLifetime.Scoped);
services.AddSingleton<OrderService>(); // OrderService takes AppDbContext in ctor
services.AddScoped<PaymentService>();
What goes wrong at code level: At runtime, the first request creates the singleton OrderService with one AppDbContext. Every later request reuses that same DbContext, leading to stale data, concurrency bugs, or disposed context exceptions. The result in theory is incorrect behaviour or runtime errors under load.
Correct approach (full good code):
// GOOD: Services that use DbContext must be Scoped (or Transient), not Singleton
services.AddDbContext<AppDbContext>(options => ..., ServiceLifetime.Scoped);
services.AddScoped<OrderService>();
services.AddScoped<PaymentService>();
services.AddSingleton<IEmailSender, EmailSender>(); // Only if EmailSender is stateless/thread-safe
Takeaway:Review DI registrations for lifetime mismatches; do not accept “register everything as Singleton” from AI. See Dependency injection and Where AI Still Fails.
Example 7: Nullable and edge case — compiles but fails at runtime
Exact prompt (completion or chat):
“Add a method that returns the first line item’s product name from an order.”
What you get in theory (bad AI output): Code that compiles but does not handle null or empty collections. Full bad example:
// BAD: No null/empty checks — NullReferenceException or InvalidOperationException at runtimepublicstringGetFirstLineItemProductName(Order order)
{
return order.LineItems.First().ProductName;
}
What goes wrong at code level: If order is null, order.LineItems throws NullReferenceException. If LineItems is empty, .First() throws InvalidOperationException. So the result in theory is runtime crashes in production when orders are empty or partially loaded.
Correct approach (full good code):
// GOOD: Explicit null and empty handlingpublicstring? GetFirstLineItemProductName(Order? order)
{
if (order?.LineItems == null || !order.LineItems.Any())
returnnull;
return order.LineItems.First().ProductName;
}
Takeaway:Always consider null and empty in prompts or review; add tests for these cases. See Where AI Still Fails (Edge cases).
Summary: use these examples in review
When reviewing AI-generated code, check: (1) Layers — no controller → DB or infrastructure in the wrong place. (2) API version — methods and types exist in your target framework. (3) Security — no concatenated user input in SQL or commands; use parameterised or safe APIs. (4) Tests — edge cases and assertions that verify behaviour, not just “it runs.” (5) Refactors — all callers updated and tests pass. (6) DI — correct lifetimes, no captured scoped dependencies in singletons. (7) Null/empty — explicit handling or documented contracts. Use the exact prompts and full bad/good pairs above as templates for what to look for. See Impact on Code Quality and Where AI Still Fails.
Chat: explanations, design, debugging
Chat is used for “how does this work?”, “how do I implement X?”, and “why is this failing?”. Use it for learning, exploration, and first drafts of design. Do not treat chat as authoritative for architecture, security, or performance—always verify. Where AI Still Fails applies here. What Developers Actually Want From AI Assistants emphasises context and control; give the model enough context (file, error, constraints) and keep control of final decisions.
Refactors: single-file and multi-file
Refactors range from rename and extract method to multi-file changes (e.g. change signature everywhere). Single-file refactors are safer—the model sees one file and you review one diff. Multi-file (e.g. Cursor composer, or chat with codebase context) can be powerful but review every call site and run tests; wrong assumptions about callers or contracts can break integration. Use version control and small commits so you can revert; run tests after each logical step. See How AI Is Changing Code Review and Testing—review still catches refactor bugs.
Patterns that work:Rename or extract in one file first; commit; then propagate to callers in small steps. For multi-file “change this pattern everywhere,” use a codebase-aware tool (e.g. Cursor) and apply in chunks (e.g. one module at a time) with tests after each chunk. Avoid: One giant multi-file change without intermediate runs of the test suite.
Tests and documentation
AI can generate unit tests, integration tests, and docs (comments, README, API docs). Use it for scaffolding (arrange/act/assert, mocks) and obvious cases; expand and tune tests for edge cases (null, empty, boundaries) and business rules. Testing strategies still apply: unit, integration, e2e where needed. Docs generated by AI can go stale—own them like any other artifact and update when code changes. Trade-offs of AI code generation include debt if generated tests are shallow (happy path only) and never extended.
What to add after AI-generated tests:Edge cases (null input, empty list, invalid state); business logic (e.g. “when order is cancelled, expect X”); integration points (e.g. DB, HTTP) if you use integration tests. Docs: Use AI for first draft of README or comments; verify accuracy and keep in sync with code.
Code review and PRs
AI-assisted review (e.g. Copilot for PRs, or chat “review this diff”) can suggest style, bugs, and tests. Integrate it as a first pass; humans must still check design, security, and consistency. See How AI Is Changing Code Review and Testing. Technical leadership can set norms: e.g. “AI suggestions are optional; human review is required.”
Completion and chat in depth
Completion:Volume—many developers accept or editdozens of completions per day (boilerplate, repository, DI, tests). Risk rises when acceptwithoutreading (wrong API, wrong layer, missing edge case). Mitigation:Scan every suggestion; runlinters and tests; reject or heavilyedit for security, business rules, architecture. When it backfires: Wrong API/version (build fails)—review imports, pin versions. Layer violation (controller calling repo directly)—review for Clean Architecture. Missing edge case (null, empty)—add tests and review. See What AI IDEs Get Right and Wrong and Where AI Still Fails. Chat:Trust with verification: explanations, first drafts, single-file refactors—run tests and review. Verify, do not trust blindly:architecture, security, performance, concurrency, business rules—use OWASP, domain experts, tests. Give context:specific prompts and enough code/error so the model sees your problem. See Trade-Offs and What Developers Want From AI. Day-in-the-life:Completion and chat are routine; review and ownership (human) are non-negotiable. Same bar for AI and human code; metrics (defect rate, time to change) apply; norms set when to use AI and when to review. See Impact on Code Quality and How AI Is Changing Code Review and Testing. Related:Current State of AI Coding Tools, Cursor vs Copilot, Why AI Productivity Gains Plateau.
By role: solo, pair, lead
Solo developer.Completion and chat are primary; self-review (read every suggestion, run tests and linters) is critical—no second pair of eyes. Documentpatterns and norms so consistency holds; measuredefect rate and time to change so quality is visible. Pair or mob.Driver uses completion/chat; navigatorreviewssuggestions and catcheslayer or security issues. Ownership is shared but explicit. Tech lead or architect.Setnorms (when to use AI, when to review, what “done” means); review for architecture and consistency; measureoutcomes so plateau or debt is caught early. See Technical Leadership in Remote Teams and Impact on Code Quality.
Tools that support each workflow
Completion:GitHub Copilot, Cursor, Claude Code—inline tab-complete; strong for boilerplate and obvious next lines. Chat:Cursor, Claude Code, Copilot Chat—explanations, first drafts, refactor suggestions; codebase context (e.g. Cursor @codebase) improvesrelevance for multi-file work. Refactors (multi-file):Cursorcomposer or codebase-aware chat—review every file and run tests. Tests:Completion or chat for scaffolds; expand for edge cases and business rules—see How AI Is Changing Code Review and Testing. Review:Copilot for PRs or chat “review this diff”—first pass only; human approval required. See Current State of AI Coding Tools and Cursor vs Claude Code vs Copilot.
Summary table: workflow by task and risk
Task
Use AI for
You still do
Risk if unchecked
Boilerplate
Completion
Read, edit, review
Wrong API, wrong layer
Explain code
Chat
Verify, extend
Wrong or incomplete explanation
Debug
Chat (error + code)
Verify fix, test
Wrong assumption, security
Refactor one file
Chat or completion
Review, run tests
Broken behaviour
Refactor many files
Codebase-aware tool
Review every call site, tests
Broken callers, drift
Unit tests
Generate scaffold
Add edge cases, business rules
Shallow tests, false confidence
Docs
First draft
Own, keep in sync
Stale or wrong
PR review
First-pass suggestions
Design, security, consistency
Missing design/security
Key terms
Completion (inline):Tab-complete or suggestion as you type; mostcommon daily use; review every suggestion.
Chat:Conversation with the model (explain, draft, refactor); givecontext (file, error) and verifydesign/security advice.
Scaffolding:First-draft structure (e.g. test arrange/act/assert, DTOs); expand and tune for edge cases and ownership.
Real-world scenarios
Each scenario below maps to code-level issues you can see in the Code-level examples section (layer violation, wrong API, injection, shallow tests, broken refactor, DI lifetime, null/empty). Use them to recognise when the same failure mode appears in your codebase.
Scenario 1: Developer leans on completion for a feature. They accept many completions for DTOs, mappers, and controller wiring. In review, one wrong property type (e.g. wrong API version as in Example 2) and a missing null check (as in Example 7) are found. Takeaway: Scan every suggestion; run tests and linter before pushing. Completion speeds typing but does not replace review. The exact failure mode is visible in the bad/good code pairs in Example 2 and Example 7.
Scenario 2: Team uses chat for a refactor. They ask “extract this into a service and update callers.” The model suggests a split; they apply it across several files. One caller passes a different shape or forgets to await (as in Example 5) and breaks at runtime. Takeaway: Multi-file refactors need review of every call site and tests after apply. Use small steps when possible. See the full broken caller and corrected caller in Example 5.
Scenario 3: AI-generated tests pass but miss edge cases. The team generates unit tests for a service; happy path is covered (as in the bad test in Example 4). A production bug appears for null input. Takeaway: Use AI for scaffold; add edge-case and business-rule tests manually. The full bad vs good test suite in Example 4 shows what to add (null, empty, behaviour assertions). See Testing strategies and Trade-offs.
Scenario 4: PR review tool suggests many comments. The team uses Copilot for PRs; it suggests style and obvious fixes. Reviewers adopt some and reject others; design and security are still human-checked. Takeaway: AI first pass is useful; humans own final approval and design/security. Security-sensitive changes (e.g. any SQL or auth) should be checked against Example 3-style injection and layer issues from Example 1.
Scenario 5: New service is slow or throws under load. After adding a “cache” or “background job” suggested by chat, the team registers it in DI. They accepted the default registration and now a scoped DbContext is captured by a singleton (Example 6). Takeaway: Review DI lifetimes for every new service; see the full bad vs good registration in Example 6.
Common issues and challenges
Over-accepting completion: Accepting every suggestion without reading leads to wrong APIs and brittle code. Always scan and edit before commit—see Impact on code quality.
Using chat for architecture: AI can suggest plausible but wrong design. Use chat for exploration and drafts; own architecture and verify—see Where AI still fails.
Multi-file refactors without review: Large edits can break call sites or drift in style. Review every file; use small commits and tests—see How AI Is Changing Code Review and Testing.
Shallow generated tests: AI often generates happy path tests; edge cases and business rules need human input. Fix: Expand and tune; add null, empty, boundary, and domain tests—see Testing strategies and Trade-offs.
Stale or wrong docs: AI-generated comments or README can drift from code. Fix: Treat docs as owned artifacts; update when code changes; review AI-generated docs like any other content.
Best practices and pitfalls
Do:
Use AI for repetition and scaffolding (boilerplate, tests, docs); review all output.
Trust AI for security or architecture without verification.
Accept completion without reading; let generated tests replace thinking about edge cases.
Skip human review for PRs or critical paths.
Norms and team integration
Set norms so AI use is consistent and review is non-negotiable. Examples: “All code (human or AI) requires review before merge”; “Use AI for boilerplate and scaffolding; design and security stay human-led”; “Do not paste secrets or PII into chat”. Technical leadership can pilot with one squad, gather feedback (what developers want), and roll out with clear expectations. Measure outcomes (defect rate, cycle time) so you can tune norms and tool use—see Why AI Productivity Gains Plateau.
Quick reference: workflow by task
Task
Use AI for
You still do
Boilerplate (DTOs, mappers)
Completion
Read, edit, review
Explain code
Chat (paste block)
Verify, extend
Debug
Chat (paste error + code)
Verify fix, test
Refactor one file
Chat or completion
Review, run tests
Refactor many files
Codebase-aware tool
Review every call site, tests
Unit tests
Generate scaffold
Add edge cases, business rules
Docs
First draft
Own, keep in sync
PR review
First-pass suggestions
Design, security, consistency
Summary
Developers integrate AI into completion, chat, refactors, tests, docs, and review; success depends on when you use it (repetition and scaffolding) and how you review (always, with ownership). Skipping review or over-accepting AI output leads to debt and quality drift; setting norms and measuring outcomes keeps integration sustainable and addresses plateau. Next, choose tools using Current State of AI Coding Tools and Cursor vs Copilot vs Claude Code, then set team norms and keep Impact on Code Quality and Trade-Offs in mind.
Position & Rationale
The article describes where developers use AI in the daily loop (completion, chat, refactors, tests, docs, review) and states that success depends on when you use it and how you review. The stance is factual: use AI for repetition and scaffolding; review everything; set norms and measure outcomes. It doesn’t claim that integrating AI always increases productivity—it ties outcome to review and norms.
Trade-Offs & Failure Modes
Using AI in more places (e.g. refactors, tests) can speed first drafts but adds the risk of brittle or wrong output if review is skipped. Tightening norms (review required, ownership) reduces that risk but doesn’t remove it. Failure modes: over-accepting completion without reading; using chat for design or security decisions without verification; skipping review because “we’re going fast.”
What Most Guides Miss
Many guides list workflows (completion, chat) but don’t tie them to risk (when to use vs when not) or to norms (who approves, what must be human-only). Another gap: diversifying use—tests, review, explanations, not just completion—can sustain gains; that’s underplayed compared to “use completion everywhere.” The bit they skip: integration is a team decision. One developer using AI in a corner is fine until their code hits review and nobody knows the assumptions; once you scale, you need agreed boundaries (e.g. “we use AI for boilerplate and tests, not for auth or billing logic”) and someone who owns the rollout. Most posts don’t say who decides or what happens when two people disagree on “is this AI-appropriate.”
Decision Framework
If you’re starting → Use completion for boilerplate; review every suggestion; then add chat for explanations and single-file refactors.
If you’re adding refactors or tests → Keep scope clear; review output; expand tests for edge cases.
For any workflow → Set norms (when review is required, who owns what); measure outcomes (defect rate, time to change).
If quality or plateau is a concern → Tighten review and standards; diversify use rather than adding more completion.
Key Takeaways
AI in daily workflows: completion, chat, refactors, tests, docs, review; success depends on when you use it and how you review.
Use for repetition and scaffolding; review and own everything; set norms and measure outcomes.
Diversifying use (not just completion) and keeping review mandatory sustain gains.
When I Would Use This Again — and When I Wouldn’t
Use this framing when a team is integrating AI into daily work and needs practical patterns and norms. Don’t use it to claim that “more AI” always helps; the article states that review and norms determine outcome.
Frequently Asked Questions
Frequently Asked Questions
Where do developers use AI most in daily workflow?
Completion (tab-complete) is the most common; chat for explanations and design is second. Refactors, tests, and review are used more selectively.
Start with completion (tab-complete): use it for boilerplate and obvious next lines; read and edit every suggestion. Then add chat for explanations (“what does this do?”) and refactors in one file. See Current State of AI Coding Tools.
Yes for first pass: paste error and context and ask “why might this fail?” or “suggest a fix.” Verify the answer (wrong assumptions, security); do not run suggested code blindly. See Where AI still fails.
How do I integrate AI into our team workflow?
Set norms (technical leadership): when to use AI, when review is required, what “done” means. Pilot with one squad; gather feedback; align with what developers want.
Which tools fit which workflow best?
Completion: Copilot, Cursor, Claude Code (inline). Chat and codebase-wide: Cursor (@codebase, composer), Claude Code, Copilot Chat. Multi-file refactors: Cursor composer or codebase-aware chat. PR review: Copilot for PRs or chat “review this diff.” See Tools that support each workflow and Cursor vs Claude Code vs Copilot.
How do solo developers maintain quality with AI?
Self-review every suggestion (layer, API, security); runlinters and tests before commit; documentpatterns so consistency holds; measuredefect rate and time to change so quality is visible. Do not skip review because you’re solo—see Impact on Code Quality and By role: solo, pair, lead.
Related Guides & Resources
Explore the matching guide, related services, and more articles.