Section 2: One Invariant and a Deadline - Requirements (Functional & Non-Functional)
Executive Summary: This section converts Section 1's assumptions into a contract a test could check. We write seven functional requirements as sentences you could demo, draw the auction's five-state lifecycle, and state the two conditions that make a bidding service correct: the winner is the bidder with the highest maximum among bids accepted strictly before end_time, ties going to the earliest accepted, and the cut-off is decided by the server's accepted_at inside the accept transaction, never by a client clock or a scheduler. We test both against auction #7731's Sunday tie and Theo's late bid. The non-functional table then puts a number and a reason on every promise: 500 milliseconds for a bid verdict, 60 seconds for a close, 99.99% for the bid path but 99.9% for the streams, and zero loss of anything acknowledged.
The interviewer looks at the assumptions you just wrote down. "Good. Now tell me what it has to do, and what 'correct' means."
Two different questions, and most candidates answer only the first. A feature list says what the system does; a requirements pass also says what must never be false and what must be measurable. For an auction the first half is short. The second half is where the design comes from.
The Functional List, as Sentences You Could Demo
| # | Capability | Demoable sentence |
|---|---|---|
| 1 | Create auction | Priya lists the booster box at $1.00, no reserve, ending Sunday 19:00:00 PT |
| 2 | Place proxy bid | Marcus submits a maximum of $12,000 and gets a verdict and the new price in one round trip |
| 3 | Read auction state | Anyone opens #7731 and sees price, bid count, high-bidder alias and end time |
| 4 | Bid history | Every accepted bid as a resulting price and a masked alias, never a maximum |
| 5 | Watch / unwatch | Dana watches #7731 and receives price changes without refreshing |
| 6 | Close and record the winner | At 19:00:31 the closer records Marcus as winner at $12,000 and emits auction.closed |
| 7 | Notify | Elena is told she is outbid; Marcus that he won; Priya that it sold |
"Row four. Why not show the maximums? Bidders would love the transparency."
Because the maximum is the mechanism: publish Marcus's $12,000 and a shill account bids $11,850 to lift the price to $11,900, one $100 step under his ceiling, at no risk to the seller, as Section 4's pushback argues. So no read endpoint, cache payload or history row ever carries the high bidder's maximum. Returning it "for transparency" has no flip trigger; it ends the product.
Key Insight: The core requirement is not "accept bids" but "return a definitive verdict, HIGH_BIDDER or OUTBID or REJECTED, in the response to the bid itself", so Elena's Thursday OUTBID at $9,550 arrives on the response, not later from a stream. An "accepted, check back later" design makes ordering queue-order rather than arrival-order, and nobody can tell a bidder in the final second whether they are winning.
Quick check before moving on:
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson