Skip to main content
Published / updated

Building with AI

Before you start

You need: Article 03, and enough of your route to be writing real project code — around month three.

Also useful: Track 16 Git. Reviewing generated code is far easier when you can see a clean diff.

Time: about 45 minutes, at the keyboard with your own project open.

Learning objective

Use AI to write real project code, and review it so that everything you commit is something you can explain.

Topics

  • Learning with AI versus building with AI
  • Sizing a change you can actually check
  • The review checklist that matters
  • The four silent rules
  • Committing generated work
  • When to stop prompting
  • Your AI evidence log

Learning with AI versus building with AI

Article 03 was about understanding. This is about shipping.

LearningBuilding
Ask for a critique of your attemptAsk for the code, then review it
The goal is your understandingThe goal is working, defensible code
Wrong answers cost you nothingWrong answers reach your portfolio
"Don't rewrite it""Here is my context, write it, I will check it"

Both are legitimate. The mistake is using building-mode while you are still learning the topic — you get a working feature and no idea how it works, and the interview finds that.

A workable rule: generate what you have already learned to write. Use AI to go faster at things you understand, not to skip things you do not. Generating a repository method in month four, after Track 07 taught you what one is, is efficiency. Generating it in month two is avoidance.

Sizing a change you can actually check

Ask for a whole feature and you get 400 lines across six files. It compiles. It looks right. You cannot review it, so you approve it — and that is how unexplainable code reaches your project.

ChangeSizeCan you verify it?
One repository method~15 linesYes — run it against real data
One endpoint~20 linesYes — call it in Postman
One validation rule~5 linesYes — send a bad request
"The whole fee module"400 linesNo

A good change is one you can hold in your head. Build the fee feature in six steps — SQL query, repository method, service method, endpoint, frontend call, rendering — verifying each. Six verified steps beat one unverified feature, and when step three is wrong you know exactly where.

Commit after each verified step. Then a bad next change is one git restore away instead of an archaeology exercise.

Giving it enough context

Generated code matches your project only if you tell it what your project is. The model knows ASP.NET Core; it does not know your rules.

I'm working on a multi-tenant school management API in ASP.NET Core 9
using Dapper.

Entity:
public class Student
{
public int Id { get; set; }
public int SchoolId { get; set; }
public string Name { get; set; }
public string RollNumber { get; set; }
public bool IsDeleted { get; set; }
}

Here's an existing repository method, follow this style exactly:
[paste one real method]

Write GetByClassAsync(int schoolId, string className).

Rules:
- SchoolId always filtered; it comes from the auth claim, never a parameter
the caller controls
- Exclude soft-deleted rows
- Parameterised SQL, no string concatenation
- decimal for money, never double
- Full braces, explicit types, no var

Every rule in that list exists because omitting it produces a bug. Paste one real method rather than describing your style — one example teaches more than a paragraph.

Add "don't change anything else" whenever you paste an existing file. Without it you get a rewritten file and a diff you cannot review.

The review checklist

Read generated code in this order. It takes two minutes.

1. Does it do what I asked? Not something adjacent, not more.

2. Does it follow the four silent rules? The section below.

3. Does it handle the edge cases? Null, empty, zero, absent, duplicate.

4. Is anything invented? Method names, packages, configuration keys.

5. Is it more than I need? Generated code adds caching, retries and interfaces you did not ask for. Delete them — every unrequested abstraction is something you must maintain and explain.

6. Can I explain every line? If not, ask about that line before accepting it.

The four silent rules

These matter more than everything else on this page, because none of them produces an error. The code compiles, runs, and is wrong.

SchoolId from the token, never the request

// Reject — any signed-in user can read any school
public async Task<IActionResult> GetStudents([FromQuery] int schoolId)

// Accept
int schoolId = int.Parse(User.FindFirst("schoolId").Value);

This is a data breach with a 200 response. Nothing is logged. Test it by signing in as School 1 and requesting School 2 — the only way to find it.

The absent check comes first

// Reject — an absent student is reported as Fail
if (result.MarksObtained >= subject.PassingMarks) { return "Pass"; }
if (result.IsAbsent) { return "Absent"; }

// Accept
if (result.IsAbsent) { return "Absent"; }
if (result.MarksObtained >= subject.PassingMarks) { return "Pass"; }

An absent student's marks are null, and any comparison with null is false — so execution falls through to Fail. This is the rule generated code breaks most often.

Money is decimal

public double Amount { get; set; } // Reject
public decimal Amount { get; set; } // Accept

Base-2 fractions do not sum exactly. A fee report off by paise is always this.

Every command inside a transaction receives it

await connection.ExecuteAsync(sql1, p1, transaction);
await connection.ExecuteAsync(sql2, p2); // Reject — no transaction
await connection.ExecuteAsync(sql2, p2, transaction); // Accept

Miss one and a rollback leaves half the operation applied.

Check these four on every generated piece of data or business code. It takes thirty seconds and it is the difference between a portfolio you can defend and one that falls apart under a follow-up question.

Committing generated work

Commit before generating. git status clean first. Then:

git diff --stat # if you asked for one method and five files changed, stop
git diff # read it, not the AI's summary of it
git add -p # accept hunk by hunk

Read the diff, not the summary. A summary is a description; the diff is what happened. They differ more often than you would expect.

Never commit code you have not read. That single rule prevents most of the ways this goes wrong.

In the commit message, record what you verified rather than what wrote it:

Add fee defaulter query to FeeRepository

Returns accounts with a balance above zero past the due date, for one
school. Filters by SchoolId from the claim and excludes soft-deleted
students.

Written with Claude, reviewed against the four rules, tested against
seed data including a student with two fee accounts.

When to stop prompting

SituationDo it yourself
Third attempt still wrongYes — the prompt is not the problem
Business logic you understand betterYes
Anything security-relatedYes, or review it as if hostile
A change you could type fasterYes
Code you would not be able to explainYes
Boilerplate DTOs and mappersNo — generate them

Three failed attempts means the task is under-specified or genuinely hard. More prompting fixes neither, and the fourth attempt costs more than writing it.

Correcting generated code you do not understand is the worst position available. You are debugging someone else's assumptions with nobody to ask.

Your AI evidence log

Start this now. It takes a line per week and it becomes an interview answer.

Week 14 Generated FeeRepository.GetDefaultersAsync.
Took schoolId as a method parameter fed by the query string.
Fixed to read the claim. Would have leaked across schools.

Week 16 Generated grading logic. Absent check was second.
Absent students would have shown as Fail on report cards.

Week 17 Generated a payment endpoint. Amount was double.
Changed to decimal.

Week 19 Generated a React list. No key prop, and no empty state.

By week 24 you have a real record, and this is the answer to "do you use AI?" that separates you from every other candidate:

"Yes — and I review it against a checklist. On my project the generated repository method took SchoolId from the request instead of the token, which would have let one school read another's students. I keep a log; it happened four times in six months, always the same four kinds of thing."

Nobody can rehearse that. You either did the work or you did not.

Common mistakes

  • Asking for a whole feature at once
  • Accepting code without reading it
  • Treating "it compiles" as verification
  • Generating things you have not learned yet
  • Not checking the four silent rules
  • Keeping abstractions you did not ask for
  • Reading the summary instead of the diff
  • Generating on top of uncommitted work
  • Prompting a fourth time instead of writing it
  • Not keeping the evidence log

Practice

  1. Ask for a complete feature in one prompt. Count the lines. Time a proper review.
  2. Build the same feature in six verified steps. Compare the time and the bugs found.
  3. Write a full context prompt with your entity, one real method, and the four rules.
  4. Prompt without the tenant rule. Check where SchoolId comes from. Record it.
  5. Ask for grading logic five times. Count how often the absent check is first.
  6. Generate a money field. Check the type in both C# and SQL.
  7. Generate a multi-statement transaction. Check every command receives it.
  8. Commit, then generate, then read git diff --stat. Note anything unexpected.
  9. Prompt three times for something it keeps getting wrong. Then write it yourself and compare.
  10. Start your evidence log today. One line per finding.

Exercise 5 gives you your own number for how often this fails. Whatever it is, that is the rate you must catch in review.

You can now

  • Tell learning-mode from building-mode, and choose deliberately
  • Size a change so you can verify it
  • Give a model the context it cannot infer
  • Check the four rules that fail silently
  • Read a diff rather than a summary
  • Know when to stop prompting and write it
  • Keep an evidence log that becomes an interview answer

Review questions

  1. Why is a 400-line generated change worse than six 20-line ones, even if it works?
  2. Which four rules produce no error when broken, and how do you test each?
  3. Why read the diff rather than the AI's description of what it did?
  4. What makes the evidence log impossible for another candidate to fake?

Next: Add an AI feature