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
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:
135
backend/src/features/user-preferences/README.md
Normal file
135
backend/src/features/user-preferences/README.md
Normal 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.
|
||||
Reference in New Issue
Block a user