In this chapter
We'll make the seat-hold logic bulletproof: decisions and repeated checks, the idea of state (explained with a traffic light), Input → Process → Output, edge cases (the "what ifs"), and validating input like a bouncer at the door.
The Problem in Real Life
Anna shows John her flowchart. He reads it, nods, and then starts asking questions, counting them on his fingers.
"What if the fan pays at minute nine, but the payment takes two minutes to finish? What if they click the seat twice? What if they open the seat map in two browser tabs? What if two different fans click the same seat in the same second? What if the payment fails? What if they press the Back button? What if the seat number doesn't exist?"
He stops at ten. Anna's flowchart handles two of them.
Your plan works when everything goes right. Most bugs live in the moments when something goes slightly wrong.
John
The Happy Path vs. Every "What If"
The happy path is easy
Pick a seat, pay, done. Real users and real networks rarely behave that neatly.
Things change over time
A seat isn't just "a seat" — it's free, then held, then sold. Its current situation is called its state.
Edges hide the bugs
Minute nine, two tabs, same second, a failed payment — that's where real bugs live.
Decisions, Repetition, State and Edge Cases
Let's build up the ideas one at a time, each with a picture you already know.
Input → Process → Output: you met this in Act 02. Every piece of logic takes something in, works on it, and gives something back. For the seat hold: the input is which seat, which fan, and what time it is. The process is the checks and changes. The output is what the fan sees ("seat held — pay within 10 minutes" or "sorry, taken") and the seat's new situation. Writing down the input and output first makes the process much easier to design.
Decisions — forks in the road: every IF is a fork where the logic goes one way or the other. Each fork doubles the number of possible paths, which is why careful thinking matters. A good habit: for every IF, ask "and what happens in the ELSE?" — Anna's missing arrow was a forgotten else.
Repetition — checking again and again: some things must happen repeatedly. For example, every minute the system can look through all held seats and release any whose time is up — a loop. Repetition is how you handle "many" and "over time."
- State — the traffic light analogy: a traffic light is always in exactly one situation: red, yellow or green. That's its state. And it can only change in certain ways — green goes to yellow, never straight to red. A seat works the same way. Its state is always exactly one of FREE, HELD or SOLD.
- Allowed moves (transitions): FREE → HELD when a fan picks it. HELD → SOLD when they pay in time. HELD → FREE when time runs out or payment fails. And some moves are never allowed: SOLD → HELD, or FREE → SOLD without a hold. Writing down the allowed moves is one of the most powerful ways to prevent bugs, because any request for a move that isn't on the list is simply refused.
- Edge cases — the "what ifs": an edge case is a situation at the boundary of normal use: the first or last item, zero or the maximum, exactly at the time limit, the same action twice, two things at once. Most of John's ten questions were edge cases. They're not rare in real life — with 50,000 fans on Sale Day, a "one in a thousand" edge case happens fifty times.
- Validation — the bouncer at the door: a bouncer checks every guest before they get in: are you on the list, are you old enough. Validation does the same for input: check it's sensible before your logic uses it. Does this seat exist? Is the fan logged in? Is the quantity between 1 and 10? Bad input stopped at the door can't cause damage inside.
| From | To | When | Allowed? |
|---|---|---|---|
| FREE | HELD | A fan picks the seat | Yes |
| HELD | SOLD | The same fan pays before heldUntil | Yes |
| HELD | FREE | Time runs out, or payment fails | Yes |
| HELD | HELD (new fan) | Another fan picks it | No — show "seat taken" |
| FREE | SOLD | Payment without a hold | No |
| SOLD | anything | Any request | No — sold is final |
| What if... | What should happen |
|---|---|
| The fan pays at minute 9, payment finishes at minute 11 | Count the time when payment started; finish the sale |
| The fan clicks the same seat twice | Second click changes nothing — they already hold it |
| The fan opens two tabs | Both tabs show the same hold; only one payment can succeed |
| Two fans click in the same second | Only one gets HELD — needs a database transaction (Act 13) |
| The payment fails | Seat goes back to FREE; fan sees a clear message |
| The fan presses Back | Hold stays until it expires; they can return and pay |
| The fan's 10 minutes run out | Seat goes back to FREE automatically |
| The seat number doesn't exist | Validation refuses it at the door |
| The fan isn't logged in | Validation asks them to log in first |
| The fan tries to hold 40 seats | Validation: maximum 10 per order |
| Part | For the seat hold |
|---|---|
| Input | Seat number, fan, current time |
| Process | Validate → check state → if FREE, mark HELD with heldBy and heldUntil |
| Output | "Seat held — pay within 10 minutes" or "Sorry, this seat is taken" |
A seat's states and the only allowed moves
FREE
anyone can pick it
HELD
one fan, for 10 minutes
SOLD
paid in time — final
FREE again
time ran out or payment failed
WHEN a fan picks a seat:IF the fan is not logged in THEN refuse: "Please log in" # validationIF the seat does not exist THEN refuse: "Unknown seat" # validationIF seat.state is HELD AND seat.heldBy is this fan THENshow the payment page again # clicked twice / second tabELSE IF seat.state is FREE THENset seat.state to HELD, heldBy to this fan, heldUntil to now + 10 minutesshow the payment pageELSErefuse: "Sorry, this seat is taken"WHEN the fan starts paying:IF seat.state is HELD AND seat.heldBy is this fan AND now is before heldUntil THENtake the paymentIF payment succeeded THEN set seat.state to SOLDELSE set seat.state to FREE and say "Payment failed"ELSErefuse: "Your hold has expired — please pick the seat again"EVERY minute:FOR EACH seat that is HELD:IF now is after seat.heldUntil THEN set seat.state to FREE
Lines marked # validation are the bouncer. Every move checks the current state first, so only allowed moves can happen.
Answering the ten "what ifs": Anna goes through John's questions one by one, and for each one she decides what should happen. Then she updates the algorithm. The key change: before every move, check the seat's current state and the clock. "Pay" only works if the seat is still HELD by this fan and the time hasn't run out. "Pick" only works if the seat is FREE. If anything doesn't match, refuse politely and explain why.
One question is special: two fans clicking the same seat in the same second. On paper, both could see FREE before either marks it HELD. John tells her to write it down as a known risk: the real fix needs the database to make "check and hold" happen as one unbreakable step — a transaction, which she'll learn in Act 13. Writing down a risk you can't solve yet is also good engineering.
Key Takeaway
Design logic with Input → Process → Output in mind, ask "what about the else?" at every decision, and use repetition for "many" and "over time". Track state like a traffic light — one state at a time, only allowed moves — test every edge case, and validate input at the door before it can cause damage.
Why This Matters
State and edge cases are where most real bugs come from — not in the main path everyone tests, but in the moments around it. Sale Day will produce every one of John's ten situations thousands of times in an hour. Thinking in states and "what ifs" now is what lets BlueTicket survive that hour later.
Version 2 handles every "what if" on the list. But Anna isn't sure it's actually right — she's been staring at it so long that it all looks correct. John has a way to check logic without running any code at all.
