This commit is contained in:
Bastian Masanek
2025-10-30 08:24:44 +01:00
commit 6e50ec7034
73 changed files with 27355 additions and 0 deletions

156
tasks/05-cart.md Normal file
View File

@@ -0,0 +1,156 @@
# Phase 5: Cart (Shopping Cart)
**Status:** ⏳ Todo
**Progress:** 0/12 tasks (0%)
**Started:** -
**Completed:** -
**Assigned to:** -
---
## Overview
Implement shopping cart functionality: API endpoints for cart operations, cart composable, and UI components for cart display and management.
**Goal:** Users can add products to cart, update quantities, and remove items.
---
## Dependencies
- ✅ Phase 2: Database must be completed (carts, cart_items tables needed)
- ✅ Phase 3: Authentication should be completed (for user-specific carts)
- ✅ Phase 4: Products must be completed (products needed in cart)
---
## Tasks
### API Endpoints
- [ ] Create /api/cart/index.get.ts endpoint
- Get current user's cart (or session cart for guests)
- Include cart items with product details (join)
- Calculate total price
- Return: { cart, items: [{product, quantity, subtotal}], total }
- [ ] Create /api/cart/items.post.ts endpoint
- Add item to cart (body: {productId, quantity})
- Validate product exists and has stock
- Create cart if doesn't exist
- Upsert cart_item (update quantity if already exists)
- Return: Updated cart
- [ ] Create /api/cart/items/[id].patch.ts endpoint
- Update cart item quantity (body: {quantity})
- Validate quantity > 0
- Validate stock availability
- Return: Updated cart item
- [ ] Create /api/cart/items/[id].delete.ts endpoint
- Remove item from cart
- Delete cart_item record
- Return: 204 No Content
### Composables
- [ ] Create useCart composable
- File: `composables/useCart.ts`
- State: cart (ref), items (computed), total (computed), itemCount (computed)
- Functions:
- `fetchCart()` - Load cart from API
- `addItem(productId, quantity)` - Add to cart
- `updateItem(itemId, quantity)` - Update quantity
- `removeItem(itemId)` - Remove from cart
- `clearCart()` - Empty cart
- Auto-fetch on mount
- See similar pattern: [CLAUDE.md: useAuth](../CLAUDE.md#oauth2-login-flow-pattern)
### UI Components
- [ ] Create CartItem component
- File: `components/Cart/CartItem.vue`
- Props: item (object with product, quantity, subtotal)
- Display: Product image, name, price, quantity input, subtotal
- Actions: Update quantity, Remove button
- Emits: @update, @remove
- [ ] Create CartSummary component
- File: `components/Cart/CartSummary.vue`
- Props: items (array), total (number)
- Display: Items count, subtotal, VAT, total
- Button: "Zur Kasse" (to checkout)
- Styling: shadcn-nuxt Card
### Pages
- [ ] Create cart page
- File: `pages/warenkorb.vue` (German route)
- Uses: useCart composable
- Shows: List of CartItem components + CartSummary
- Empty state: "Ihr Warenkorb ist leer" with link to /produkte
- Loading state while fetching
### Testing
- [ ] Test cart operations
- Add product to cart from product page
- Verify cart count updates (header badge)
- Visit /warenkorb page
- Update quantity via input
- Remove item via button
- Verify total updates correctly
- [ ] Add cart persistence
- For logged-in users: cart stored in DB (user_id)
- For guests: cart stored in DB (session_id)
- Test cart persists across page reloads
- Test cart merges when guest logs in (optional, can defer)
- [ ] Optimize cart queries
- Ensure product details are fetched efficiently (join, not N+1)
- Test with 10+ items in cart
- Add indexes if needed
- [ ] Document cart logic
- Document cart/session relationship
- Document cart item uniqueness (cart_id + product_id)
- Document cart cleanup strategy (old carts)
---
## Acceptance Criteria
- [x] All 4 cart API endpoints work correctly
- [x] useCart composable manages cart state
- [x] CartItem component displays and allows editing
- [x] CartSummary component shows total correctly
- [x] /warenkorb page shows cart with all items
- [x] Can add products to cart from product pages
- [x] Can update item quantities in cart
- [x] Can remove items from cart
- [x] Cart total calculates correctly
- [x] Cart persists across page reloads
- [x] Empty cart shows helpful message
---
## Notes
- **Guest Carts:** Use session_id for guest carts (cookie-based)
- **Cart Merge:** When guest logs in, merge guest cart with user cart (optional for MVP)
- **Stock Validation:** Ensure quantity doesn't exceed stock when adding/updating
- **VAT:** 7% VAT for annual passes (hardcoded for MVP)
---
## Blockers
- None currently
---
## Related Documentation
- [docs/PRD.md: F-005](../docs/PRD.md#f-005-warenkorb)
- [docs/ARCHITECTURE.md: Carts Tables](../docs/ARCHITECTURE.md#carts)