Ship It: The Finishing Checklist
intermediate20 min readLesson 129 of 204
Testable requirements, designed errors, boring happy paths, durable state, and explainable lines.
You have built programs all course; the final module is about finishing one. "Finishing" has a checklist:
- Requirements are testable. Each capability has a concrete scenario: "adding a duplicate ISBN updates the quantity" — not "handles input".
- Errors are designed, not accidental. Every failure the user can
cause has a chosen channel: return
nullopt, throwValidationError, or print a message. Pick per case; document with the signature. - The happy path is boring. Read the main loop: if it is more than parse → dispatch → print, responsibilities leaked upward.
- State survives restart. Serialize on change, deserialize on start; corrupt input degrades to "start empty" with a warning — never a crash.
- You can explain every file. The final review is verbal: point at a line and say which decision it implements. If you cannot, that line is either unnecessary or undesigned.
The graded challenges below are the three seams learners most often get wrong: the borrow/return state machine, the persistence round-trip, and the validation boundary. Each is small; each is where "almost working" programs actually break.