Commit Graph

3 Commits

Author SHA1 Message Date
7ecb337263 Finishing a lesson or island needs recorded answers and an unlocked island; auto DB backup before migrate; throttles on 15 more routes
- content: POST nodes/{id}/quiz/complete and lessons/{id}/complete refuse a locked island
  (403 node_locked, same rule as /api/home) and a user who has not answered every question
  (409 answers_missing). Before, only a user with zero hearts and no answers was refused, so
  anyone else finished any island, locked or not, and finishing a locked island's lessons
  unlocked it. A node or lesson with no questions still passes when unlocked, with no XP.
  The client can no longer understate totalQuestions to buy stars.
- throttle_scope on 15 routes that had none (question bank without login, intro, hearts,
  notifications, tickets, plans, subscription status, orders, offers, affiliate, assistant
  history and feedback, logout).
- admin: OTPCode and Session can only be added/changed by a superuser.
- deploy.sh: integrity-checked DB backup before migrate (keeps the last 2); no migrate without it.
- docs and CLAUDE.md updated to say what is verified and what is not.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 13:30:24 +03:30
663252a260 Remove the guest system entirely: no is_guest/device_id, no guest throttles, phone login is the only way in
accounts.0008 drops the columns and refuses to run while guest rows exist.
Docs describe the current state; tests that only proved guest behaviour are gone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 18:20:10 +03:30
4700ccbf91 hearts: zero hearts really stops play
- The zero-hearts check moved inside the answer transaction: two wrong
  answers sent at once with one heart left were both accepted (reproduced
  with two threads).
- Finishing a lesson or an island without hearts and without having
  answered its questions is now 403 no_hearts; before, quiz/complete let
  a student move on island after island with zero hearts. Losing the last
  heart on the last question still finishes the island.
- A heart that came back while waiting is now saved before answering, so
  the reply no longer says 0 hearts left (the app then showed the
  no-hearts page to someone who had a heart).
- The 403 also carries fullRefillAt for the waiting screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:31:44 +03:30