Update progress and prioritize cart and checkout phases
This commit is contained in:
156
tasks/04-cart.md
Normal file
156
tasks/04-cart.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# Phase 4: Cart (Shopping Cart) ⚡ PRIORITY
|
||||
|
||||
**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)
|
||||
- ⚠️ **Note:** Products can be seeded manually for testing (Phase 6 can be done after 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)
|
||||
Reference in New Issue
Block a user