# Phase 6: Checkout (Forms & Flow)

**Status:** ⏳ Todo
**Progress:** 0/15 tasks (0%)
**Started:** -
**Completed:** -
**Assigned to:** -

---

## Overview

Implement checkout flow: billing address form, validation, address pre-fill from user profile, save address to profile option.

**Goal:** Users can enter billing information and proceed to payment.

---

## Dependencies

- ✅ Phase 2: Database (users table with address fields)
- ✅ Phase 3: Authentication (user session needed)
- ✅ Phase 5: Cart (checkout requires items in cart)

---

## Tasks

### Schema & Validation

- [ ] Create checkout schema (Zod)
  - File: `server/utils/schemas/checkout.ts`
  - Fields: salutation, firstName, lastName, dateOfBirth, street, postCode, city, countryCode
  - Validation rules: required fields, date format, postal code format
  - Export: `checkoutSchema`, `CheckoutData` type

### API Endpoints

- [ ] Create /api/checkout/validate.post.ts endpoint
  - Validates checkout data (Zod)
  - Checks if user is logged in
  - Checks if cart has items
  - Returns: validation result or errors

### UI Components

- [ ] Create CheckoutForm component
  - File: `components/Checkout/CheckoutForm.vue`
  - Uses: VeeValidate + Zod schema
  - Fields: All billing address fields
  - Checkbox: "Adresse für zukünftige Bestellungen speichern"
  - Pre-checked if user has no saved address
  - Button: "Weiter zur Zahlung"
  - See: [CLAUDE.md: Checkout Pattern](../CLAUDE.md#checkout-with-saved-address-pattern)

- [ ] Create AddressForm component (reusable)
  - File: `components/Checkout/AddressForm.vue`
  - Props: modelValue (address object), errors
  - Emits: @update:modelValue
  - Fields: Salutation dropdown, Name fields, Address fields
  - Can be reused in profile settings later

### Core Functionality

- [ ] Implement address pre-fill from user profile
  - In CheckoutForm: fetch user data from useAuth
  - If user has saved address (user.street exists): pre-fill all fields
  - If no saved address: show empty form

- [ ] Implement save address to profile
  - After successful checkout: if checkbox checked, save address to user record
  - Update users table: salutation, dateOfBirth, street, postCode, city, countryCode
  - API endpoint: PATCH /api/user/profile (or include in order creation)

### Pages

- [ ] Create checkout page
  - File: `pages/kasse.vue` (German route)
  - Middleware: `auth` (requires login)
  - Shows: CheckoutForm component
  - Shows: Order summary (cart items + total)
  - Redirects to /warenkorb if cart is empty

### Validation & Error Handling

- [ ] Add form validation (VeeValidate)
  - Install VeeValidate + @vee-validate/zod
  - Configure VeeValidate with Zod integration
  - Show field-level errors
  - Show form-level errors (e.g., "Cart is empty")

- [ ] Add error handling
  - Handle validation errors gracefully
  - Show user-friendly error messages
  - Disable submit button while submitting
  - Show loading spinner during submission

- [ ] Add loading states
  - Loading: fetching user profile
  - Loading: validating checkout data
  - Loading: processing payment (next phase)

### Testing

- [ ] Test checkout flow
  - Login as user with saved address → verify pre-fill
  - Login as new user → verify empty form
  - Fill form and submit → verify validation
  - Submit with invalid data → verify error messages
  - Submit with valid data → proceed to payment (next phase)

- [ ] Test address save/load
  - Submit checkout with "save address" checked
  - Verify user record updated in DB
  - Start new checkout → verify address pre-filled

- [ ] Test mobile checkout
  - Test form on mobile device/emulator
  - Verify fields are easy to tap and type
  - Verify keyboard shows correct type (e.g., numeric for postal code)

- [ ] Optimize checkout UX
  - Autofocus first field
  - Tab order is logical
  - Error messages are clear and helpful
  - Button placement is accessible

- [ ] Document checkout logic
  - Document address save/load flow
  - Document validation rules
  - Document error handling strategy

---

## Acceptance Criteria

- [x] Checkout schema is defined with Zod
- [x] CheckoutForm component is functional and styled
- [x] AddressForm component is reusable
- [x] Address pre-fills from user profile if available
- [x] "Save address" checkbox works correctly
- [x] /kasse page is protected (requires auth)
- [x] Form validation works (VeeValidate + Zod)
- [x] Field-level and form-level errors display correctly
- [x] Loading states show during async operations
- [x] Mobile checkout UX is optimized
- [x] Address is saved to user profile after successful checkout
- [x] Checkout flow is documented

---

## Notes

- **Required Fields:** All address fields are required at checkout (even though optional in DB)
- **Date of Birth:** Required for annual pass registration
- **Salutation:** Dropdown with values: "Herr", "Frau", "Keine Angabe" (maps to HERR, FRAU, K_ANGABE in X-API)
- **Country Code:** Default to "DE", allow selection for international customers

---

## Blockers

- None currently

---

## Related Documentation

- [docs/PRD.md: F-006](../docs/PRD.md#f-006-checkout-prozess)
- [docs/ARCHITECTURE.md: Users Table](../docs/ARCHITECTURE.md#users)
- [CLAUDE.md: Checkout Pattern](../CLAUDE.md#checkout-with-saved-address-pattern)
