Files
picpeak/frontend
Paul NothaftandPaul Nothaft 6a048d08bd feat(feedback): let guests remove their star rating (#884) (#893)
* feat(feedback): let guests remove their star rating (#884)

Clicking your current rating again clears it. rating: 0 is the wire
contract: the validator now accepts 0, and the service deletes the
guest's rating row (instead of storing a 0 that would drag the photo
average down) and recalculates photo stats. The lightbox stars send 0
on a same-star click; PhotoRating already did, but the backend rejected
it with a 400 until now.

* fix(feedback): harden the rating-clear path (#884 review round)

External review follow-ups: numerically normalize the clear sentinel so
a numeric-string "0" can't slip into the update/insert paths (validator
now also toInt()s), delete the full guest-scoped rating set on clear so
racy duplicate rows can't survive in the average (same defense as the
reaction path), and refresh the visible average/count after the
identity-modal submit path like the direct paths do.

* fix(feedback): round-2 review fixes for rating clear (#884)

- Clear sentinel matches only an explicit 0 / "0" — malformed input
  (undefined, NaN, garbage strings) can no longer delete a rating.
- Lightbox survives the photo list shrinking while open (clearing your
  rating under the Rated filter drops the photo on refetch): index is
  re-anchored and the lightbox closes when the list empties, instead of
  crashing on an out-of-range index.
- Story layout gets the same same-star-to-clear behavior, keyed off the
  session-local my-rating map, and an explicit 0 no longer falls back to
  displaying the photo average.

* fix(feedback): refresh guest-scoped caches after rating changes (#884 review round 3)

- GalleryView's onFeedbackChange now also invalidates ['my-feedback',
  slug]: in guest identity mode the Rated/Liked filter membership and
  chip counts come from that query (#538), so a cleared rating never
  left the Rated filter until the 30s staleTime lapsed.
- PhotoRating invalidates gallery-photos + my-feedback on success: the
  parent refetch fires optimistically in onMutate and could capture
  pre-mutation state, with nothing refreshing after the server accepted.

---------

Co-authored-by: Paul Nothaft <[email protected]>
2026-07-29 11:34:23 +02:00
..