chore: Update Documentation
All checks were successful
Deploy to Staging / Build Images (push) Successful in 2m19s
Deploy to Staging / Deploy to Staging (push) Successful in 27s
Deploy to Staging / Verify Staging (push) Successful in 5s
Deploy to Staging / Notify Staging Ready (push) Successful in 5s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Mirror Base Images / Mirror Base Images (push) Successful in 29s

This commit is contained in:
Eric Gullickson
2026-01-03 15:10:19 -06:00
parent 485bfd3dfc
commit 3053b62fa5
8 changed files with 1149 additions and 273 deletions

View File

@@ -0,0 +1,135 @@
# 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.