Acceptance Checklist — Product Wishlist
Use this checklist to verify your implementation is complete before archiving.
API
- [ ]
POST /api/wishlistwith valid{ productId }and authenticated session returns201 Createdwith the saved wishlist item - [ ]
POST /api/wishlistwith a duplicate(productId, userId)returns409 Conflict - [ ]
GET /api/wishlistreturns a JSON array of the authenticated user's wishlist items with product details - [ ]
DELETE /api/wishlist/{id}returns204 No Contentand removes the item (only if owned by authenticated user) - [ ]
DELETE /api/wishlist/{id}for another user's item returns403 Forbiddenor404 Not Found - [ ]
GET /api/wishlist/check?productId={id}returns{ "exists": true }or{ "exists": false } - [ ] All wishlist endpoints return
401 Unauthorizedwhen called without authentication
Frontend
- [ ] Product detail page shows a wishlist toggle button for logged-in users
- [ ] Logged-out users see a "Log in to save" prompt instead of the wishlist button
- [ ] Clicking "Save to Wishlist" adds the product and toggles the button to "Saved"
- [ ] Clicking "Saved" removes the product from the wishlist and toggles back
- [ ]
/wishlistroute renders all saved products as cards (name, price, image, remove action) - [ ]
/wishlistroute is guarded — redirects to login if unauthenticated - [ ] Removing an item from the wishlist page removes it from the displayed list
- [ ] An empty state ("Your wishlist is empty. Browse products to add some!") is shown when no items exist
- [ ] Navigation includes a wishlist link (visible only when logged in)
Test suite
- [ ] All new Spring controller/service tests pass (
mvn testin the backend) - [ ] All pre-existing backend tests continue to pass
- [ ] No new Angular compile errors or test failures
OpenSpec artefacts
- [ ]
openspec/changes/contains an archived entry for this feature (timestamped folder underarchive/) - [ ]
tasks.mdhas all items checked off before archiving - [ ]
proposal.mdreflects the final agreed scope (not the original draft)