# 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)