# User Preferences Feature

User preference management for unit system, currency, timezone, and dark mode settings.

## Overview

This feature provides API endpoints for retrieving and updating user preferences. Preferences are automatically created with defaults on first access.

## Architecture

- **API Layer**: Routes and controller for HTTP request/response handling
- **Core Integration**: Uses shared `core/user-preferences/` for repository and types
- **Auto-Creation**: Default preferences created on first GET if none exist

## API Endpoints

### GET /api/user/preferences (Protected)
Retrieve user preferences. Creates default preferences if none exist.

**Authentication:** Requires JWT

**Response (200 OK):**
```json
{
  "id": "uuid",
  "userId": "auth0|123456",
  "unitSystem": "imperial",
  "currencyCode": "USD",
  "timeZone": "UTC",
  "darkMode": null,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T00:00:00.000Z"
}
```

**Error Responses:**
- 401: Unauthorized (no JWT or invalid JWT)
- 500: Database error

---

### PUT /api/user/preferences (Protected)
Update user preferences. Creates preferences if none exist.

**Authentication:** Requires JWT

**Request:**
```json
{
  "unitSystem": "metric",
  "currencyCode": "EUR",
  "timeZone": "America/New_York",
  "darkMode": true
}
```

All fields are optional. Only provided fields are updated.

**Validation:**
- `unitSystem`: Must be `"imperial"` or `"metric"`
- `currencyCode`: Must be a 3-letter ISO currency code (e.g., `"USD"`, `"EUR"`)
- `timeZone`: IANA timezone string (e.g., `"America/New_York"`)
- `darkMode`: Boolean or `null` (null = system default)

**Response (200 OK):**
```json
{
  "id": "uuid",
  "userId": "auth0|123456",
  "unitSystem": "metric",
  "currencyCode": "EUR",
  "timeZone": "America/New_York",
  "darkMode": true,
  "createdAt": "2025-01-01T00:00:00.000Z",
  "updatedAt": "2025-01-01T12:00:00.000Z"
}
```

**Error Responses:**
- 400: Invalid unitSystem, currencyCode, or darkMode value
- 401: Unauthorized (no JWT or invalid JWT)
- 500: Database error

## Default Values

When preferences are auto-created:
- `unitSystem`: `"imperial"`
- `currencyCode`: `"USD"`
- `timeZone`: `"UTC"`
- `darkMode`: `null` (system default)

## Integration Points

- **Core User Preferences**: Shared repository and types in `core/user-preferences/`
- **Database**: `user_preferences` table
- **Auth**: JWT authentication via Fastify auth plugin
- **Onboarding**: Preferences set during user onboarding flow

## Testing

### Unit Tests
Location: `tests/unit/`

Tests controller logic with mocked repository:
- Get preferences with and without existing record
- Update preferences with valid and invalid inputs
- Validation error handling

Run tests:
```bash
npm test -- features/user-preferences
```

## Dependencies

- UserPreferencesRepository (`core/user-preferences/data/user-preferences.repository.ts`)
- Core logger (`core/logging/logger.ts`)
- Database pool (`core/config/database.ts`)

## Database Table

Table: `user_preferences`

| Column | Type | Description |
|--------|------|-------------|
| id | UUID | Primary key |
| user_id | VARCHAR(255) | Auth0 user ID (unique) |
| unit_system | VARCHAR(20) | `imperial` or `metric` |
| currency_code | VARCHAR(3) | ISO currency code |
| time_zone | VARCHAR(100) | IANA timezone |
| dark_mode | BOOLEAN | Dark mode preference (nullable) |
| created_at | TIMESTAMP | Creation timestamp |
| updated_at | TIMESTAMP | Last update timestamp |

See `docs/DATABASE-SCHEMA.md` for complete schema details.
