The request
Add the review screen.
Goal:
A page at /review shows the cards that are due, one at a time.
How it works:
- Show the question only, with a "Show answer" button.
- After the answer is shown, display three buttons: Forgot, Hard, Easy.
- Clicking one uses nextGap to work out the new gap, updates the card's
gap_days and next_review, and moves to the next due card.
- next_review is today's date plus the new gap, in YYYY-MM-DD.
Which cards are due:
- A card is due if its next_review is today or any earlier date.
- Show the ones with the oldest next_review first.
- If nothing is due, show the text "Nothing to review, well done".
Limits:
- Use the existing nextGap function. Do not rewrite the rules.
- Plain HTML and CSS. No UI framework.
- Must be usable on a phone screen.
Done when:
- Reviewing a card changes its next_review to the correct date.
- A card due tomorrow does not appear.
- An overdue card does appear.
- With nothing due, the message above is shown.
The second quiet mistake
Test it the obvious way and everything looks right. Add a card, review it, it disappears,
the next one comes up.
Now test the case your plan named on purpose. Make a card overdue:
# set one card's next_review to a date in the past, by hand
Open /review.
There is a good chance that card does not appear.
Why this happens
The requirement was “due if next_review is today or any earlier date“. The natural thing
to write is:
WHERE next_review = today
when the correct thing is:
WHERE next_review <= today
One character. No error message. Nothing crashes.

Why this one is genuinely dangerous
Think about what it does to a real student.
You study for a week, then you miss two days. Every card that came due in those two days now
has a next_review date in the past. With = instead of <=, those cards are gone. Not
deleted, just never shown again.
The app keeps working. It shows you today’s cards cheerfully. You are quietly no longer
studying the things you had already started to forget, which are the exact cards that
mattered most.
You would not notice for weeks. You might never notice.
The dangerous mistakes are not the ones that crash. They are the ones that keep working
and are wrong.
That is why “an overdue card must still appear” was written into your plan back in Lesson
2.5, before a single line of code existed. Deciding what to check is easiest before there
is anything to look at.
Fix it, then protect it
Fixing the character is not enough. Ask for a test:
Add a test that creates a card with next_review three days in the past
and checks that it appears in the due list.
Now the mistake cannot come back quietly.
Commit
npm test
git add -A
git commit -m "Step 7-9: review screen, due cards including overdue, empty state"
Try this before the next lesson
- Set a card to a date far in the past. Does it appear? Is it first in the list?
- Set one to tomorrow. Confirm it does not appear.
- Review every card, then reload
/review. Do you see the empty message?