Courses Learn Blog Contact
Get Started →
Lesson 16

Day 16: AI-Assisted Development

Prompting with real context, reviewing generated code as a hostile reader, catching hallucinated methods, and the one rule: never submit code you cannot explain.

Webbo3 Level 2: JavaScript Development 18 min read Free

Webbo3 Level 2 · JavaScript Development · Day 16 of 20

AI-Assisted Development

Using AI the way an engineer does: as a fast assistant you supervise, never as an authority you obey.

By the end of today you can

  • Prompt for code with enough context to get something useful
  • Review AI output the way you would review a stranger's pull request
  • Spot a hallucinated method, a subtle logic error and an insecure pattern
  • Use AI for the things it is genuinely good at, and stop using it for the rest
  • Live by one rule: never submit code you cannot explain

Nobody is going to tell you not to use AI. You will use it, your colleagues use it, and pretending otherwise would make this course useless the day you leave it. What separates a developer from somebody typing prompts is not whether they use it. It is whether they can tell when it is wrong.

1. What it is actually good at

Genuinely good atQuietly bad at
Explaining an error message in plain EnglishKnowing whether your code is actually broken: it cannot see your screen
Generating practice material and test dataJudging what matters in your product: it does not know your users
Boilerplate you have written a hundred timesAnything depending on your codebase that you did not paste in
Reviewing your code as a hostile readerWriting code for a library version it half-remembers
Expanding a list of edge cases you startedProducing the first list, which is where your judgement lives
Turning a rough README into a clear oneDeciding your architecture, which it will do confidently and badly

The pattern across that whole table

AI is strong where the work is transformation, and weak where the work is judgement. Rewriting, explaining, expanding, translating: good. Deciding what matters, whether this is right, what to build: yours.

2. Prompting that gets something usable

TEXTa prompt that wastes your time
write me a function to filter students

You will get a plausible function for a made-up data shape that does not match yours. Compare:

TEXTa prompt that earns its keep
I am writing vanilla JavaScript, no frameworks, ES modules, for a browser.

Here is my actual data shape:
  { id: 12, name: "Chidinma Okafor", score: 88, city: "Lagos", paid: true }

I have an array of about 200 of these in `state.students`.

Write a function `visibleStudents(state)` that returns the students matching
BOTH `state.search` (case-insensitive, matches any part of the name) and
`state.filter` (one of "all", "paid", "unpaid").

Constraints:
- Do not mutate `state.students`
- Return an empty array when nothing matches, never null
- No libraries

Then list three edge cases your function does NOT handle.
  • The real data shape. Most bad output is AI guessing at a shape you never gave it.
  • The constraints. Vanilla, no libraries, do not mutate. Otherwise it will reach for lodash and React.
  • What "done" means. Empty array not null. Say it or you will get null and a crash three files away.
  • Ask what it did not handle. This last line is the highest-value sentence in the prompt: it forces the model to argue against its own output, and it is where you find out that empty search was never considered.

3. Reviewing what comes back

Read AI output the way you read a pull request from somebody you do not know. Here is a piece of generated code of exactly the kind you will be handed. Four things are wrong with it. Find them before you open the answer.

JSapp.js
// "Renders the student list with a search filter"
function renderStudents(students, search) {
  var html = '';
  for (var i = 0; i < students.length; i++) {
    if (students[i].name.includes(search)) {
      html += '<li onclick="selectStudent(' + students[i].id + ')">'
            + students[i].name + ' - ' + students[i].score + '</li>';
    }
  }
  document.getElementById('list').innerHTML = html;

  var avg = students.reduce((a, b) => a + b.score) / students.length;
  document.getElementById('avg').innerHTML = 'Average: ' + avg;
}
Show me the four problems

1. The average is wrong in two ways. reduce with no starting value uses the first object as the accumulator, so it computes {...} + 88, producing a string like [object Object]88. And it averages all students rather than the filtered ones, which is almost certainly not what the label claims.

2. User text goes into innerHTML. A student named <img src=x onerror=...> executes. Day 4 and Day 17.

3. onclick written into a string. It depends on a global function, breaks under modules, and would be a delegated listener in anything written this month.

4. The search is case-sensitive, so typing "chidinma" finds nothing. And var in 2026 is a smell on its own.

None of those stop the page loading. Three of them produce output that looks fine until the wrong moment, which is exactly why "it ran" is not a review.

JSapp.js
// proving problem 1, because it is the one people do not believe
const students = [{ name: 'Chidinma', score: 88 }, { name: 'Musa', score: 54 }];

console.log('no starting value:', students.reduce((a, b) => a + b.score));
console.log('with a starting value:', students.reduce((a, b) => a + b.score, 0) / students.length);
Console

4. Hallucinated APIs

The most dangerous output is not code that fails. It is code that looks completely reasonable and calls a method that does not exist.

JSapp.js
const items = [3, 1, 2];

console.log(typeof items.sortBy);        // sounds real, is not
console.log(typeof items.remove);        // sounds real, is not
console.log(typeof items.toSorted);      // real, and genuinely useful
console.log(typeof items.includes);      // real

console.log(items.toSorted((a, b) => a - b), 'original untouched:', items);
Console

The ten-second check that saves an hour

When AI hands you a method you have not used before, search MDN for it by name before you build on it. If MDN does not have it, it either does not exist or is not something you should be relying on. This habit costs ten seconds and it is the single highest-return thing in this lesson.

5. The security failures AI hands you most often

What it writesWhy it is wrongDay
el.innerHTML = userInputXSS. The user can inject markup4, 17
An API key inline in the JavaScriptPublic the moment you deploy8, 17
eval() on anythingRuns arbitrary code. Almost never justified17
Validation only in the browserTrivially bypassed. The server must check13
Storing a token in localStorageReadable by any injected script11, 17

These recur because the model learned from a decade of tutorials that did the same things. It is not being careless: it is reproducing the average of what people have published, and the average is not secure.

6. Use it as a reviewer, which is where it shines

The highest-value use of AI in this whole course is not generation. It is asking it to attack work you already did.

TEXTthe review prompt
You are a senior JavaScript engineer reviewing a junior's code. Be strict and
specific. Do not compliment me.

Here is my code:
[paste it]

Answer:
1. Any bug that produces a wrong result rather than an error. Show me the input
   that breaks it.
2. Anywhere user input reaches the DOM or a URL unsafely.
3. Anything that will break with 5,000 records instead of 50.
4. Three names that do not say what they hold.
5. The single change that would most improve this file, and why.

If you find nothing in a category, say so rather than inventing something.

That last line matters more than it looks. Without it you get five findings whether or not there are five, because the shape of your question implied there should be.

7. The rule

Never submit code you cannot explain

Not "did not write". Cannot explain. Copying from Stack Overflow was always fine if you understood what you copied, and pasting from an AI is fine on exactly the same terms. If you cannot say what a line does and why it is there, it does not go in your project, because the moment it breaks you cannot fix it and the moment you are asked about it you cannot answer.

The three-question test, before any generated code goes in

  1. What does this line do? If you cannot say, ask for an explanation rather than pasting it.
  2. What happens with empty, zero, or 5,000 items? Try it. Do not reason about it.
  3. Could a user put something hostile through this? If user text reaches innerHTML or a URL, the answer is yes.

Do this now

  1. Take the broken code from section 3, fix all four problems, and write one sentence per fix explaining what would have gone wrong.
  2. Ask an AI to generate a small feature for your Day 15 project with your real data shape pasted in. Before you run it, write down what you think is wrong with it. Then run it and see if you were right.
  3. Run the reviewer prompt on a file you wrote yourself this month. Fix what it finds that is genuinely a problem, and write down anything it flagged that was actually fine. That second list is the point of the exercise.
  4. Find one hallucination. Ask for "five lesser-known array methods with examples" and check every one on MDN. Note which were real.

Checkpoint

Q1. What is AI genuinely good at, in one word?

Transformation. Explaining, rewriting, expanding, translating, generating practice material. It is weak wherever the task is judgement: what matters, what to build, whether this is right.

Q2. Why include "list three edge cases you did NOT handle" in a prompt?

It forces the model to argue against its own output, which surfaces the assumptions it quietly made. It is the cheapest quality improvement you can make to any code prompt.

Q3. You are given `array.sortBy()`. What do you do?

Search MDN for it before building on it. It does not exist. Ten seconds now against an hour of debugging a method that was never real.

Q4. What does "never submit code you cannot explain" actually forbid?

Not using AI, and not copying. It forbids shipping lines you could not defend if asked, whoever or whatever produced them.

Tick before you move on

  • I found all four problems in the generated code before opening the answer
  • I proved the reduce bug myself rather than taking it on trust
  • I ran the reviewer prompt and noted where it was wrong as well as right
  • I caught at least one hallucinated method against MDN
  • Every line in my Day 15 project is one I can explain

Quick recap

AI is strong at transformation and weak at judgement · Paste your real data shape and your constraints, or you get plausible fiction · Review generated code as a hostile reviewer: innerHTML, keys, eval, reduce · Check unfamiliar methods on MDN before building on them · Never submit code you cannot explain

Tomorrow, Day 17: the security mistakes a junior developer is actually expected not to make.

Learn this with a real instructor

Free lessons take you a long way on your own. The full programmes add live classes, assignments, Skill Points and a certificate — built for African students.