← THE WORKSHOP / RETURN
EXAMPLE LIBRARY / THREE COMPLETE CASES

MAKE IT.
BREAK IT ON PURPOSE.

Three modest projects with real code and deliberately missing rules. The errors are pedagogical, not claims that a particular AI model wrote them.

CASE STUDY 01 / NUMERICAL INPUTS

Number Desk: zero is not blank.

Scenario: a visitor needs to add two numbers from a phone. The initial app accepts two number fields and announces the result.

The invisible problem

JavaScript has the unintuitive rule Number('') === 0. If your code converts a blank input directly, a missing number becomes a real quantity. The interface reports success even though the user has not completed the task.

// Before: the empty string is silently coerced.
const total = Number(first.value) + Number(second.value);

// After: blank and zero receive different treatment.
if (first.value.trim() === '' || second.value.trim() === '') {
  status.textContent = 'Enter both numbers.';
  return;
}
const total = Number(first.value) + Number(second.value);

Three necessary checks

  1. Enter 2 and 3: expect 5.
  2. Leave one input empty: expect an error, not a plausible answer.
  3. Operate the form using only a keyboard and confirm the result is announced.

Transfer lesson: never let a coercion rule silently define the business meaning of missing data.

PRACTISE IN THE WORKSHOP ↗
CASE STUDY 02 / INFORMATION FEEDBACK

Show & Tell: absence needs a label.

Scenario: three local portfolio items are filterable by text. The first version removes unmatched cards but has no recovery message. A visitor searches for “banana”; the empty panel looks broken.

What changed

The repaired version uses an explicitly labelled search and a visible, live-announced message explaining that no projects matched. The message recommends editing or clearing the query. A “zero results” interface can still be a complete interaction.

// After filtering:
list.replaceChildren(...matchingCards);
emptyMessage.hidden = matchingCards.length !== 0;
// HTML: <p id="emptyMessage" role="status" hidden>
// No matches. Clear the filter and try again.
// </p>

Three necessary checks

  1. Search “design”: see the design project.
  2. Search an impossible term: see a helpful empty state.
  3. Clear the search: the full collection returns and focus stays where expected.

Transfer lesson: every empty state is a piece of product writing and an accessibility decision, not just an absence of content.

CASE STUDY 03 / SMALL-BUSINESS RULES

Kirana Counter: invalid lines still add up to trouble.

Scenario: a tiny neighbourhood shop records item, quantity and unit price. The first version accepts zero units; a line appears in the record although it represents no sale.

The rule belongs in the model

The repaired version requires a nonempty item name, a positive whole-number quantity and a finite nonnegative unit price. This is a worked example of domain logic: code can be syntactically valid while violating the world's actual rules.

// A few examples of an explicit domain rule:
const validQty = Number.isInteger(qty) && qty > 0;
const validPrice = Number.isFinite(unit) && unit >= 0;
if (!item.trim() || !validQty || !validPrice) {
  message.textContent = 'Check item, quantity and price.';
  return;
}

Three necessary checks

  1. Add 2 units priced at ₹15: total rises by ₹30.
  2. Try quantity zero: receive an error and no new line.
  3. Reload the page: confirm the demo has no persistent customer or sales data.

Transfer lesson: input types and HTML hints do not replace the application rules. Real shop systems need additional safeguards, persistence decisions and data backup.

YOUR TURN TO SHIP A SMALL THING.

Every case has a real, inspectable and exportable starter. Learn what was changed before trusting the result.

TRY ALL THREE CASES ↗