feat: Add backend support for measurement unit preferences
Some checks failed
CI/CD Pipeline / Build Application (push) Has been cancelled
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled

Updated backend to support measurement unit preferences (Metric/Imperial)
in user profiles. The preferences are stored in the existing JSONB
preferences column, which already exists in the database.

**Backend Changes:**
- Updated User entity to include measurementUnit in preferences type
- Created UpdateProfileDto with proper validation for preferences
- Updated auth controller to use UpdateProfileDto for PATCH /api/v1/auth/profile
- Added IsIn validator for measurementUnit ('metric' | 'imperial')

**Documentation:**
- Updated LOCALIZATION_IMPLEMENTATION_PLAN.md with completion status
- Marked Phases 1, 2, 3, 7, 8 as completed
- Marked Phase 4 (backend preferences) as in progress
- Added detailed completion markers for each subsection

**Technical Details:**
- No migration needed - using existing preferences JSONB column
- Preferences object now includes: notifications, emailUpdates, darkMode, measurementUnit
- Endpoint: PATCH /api/v1/auth/profile accepts optional preferences object
- Validation ensures measurementUnit is either 'metric' or 'imperial'

**Next Steps:**
- Frontend integration to persist language/measurement preferences to backend
- Apply localization throughout remaining pages and components
- Create onboarding flow with language/measurement selection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-03 11:01:19 +00:00
parent c1e37d30b0
commit de691525fb
4 changed files with 135 additions and 87 deletions

View File

@@ -91,6 +91,7 @@ export class User {
notifications?: boolean;
emailUpdates?: boolean;
darkMode?: boolean;
measurementUnit?: 'metric' | 'imperial';
};
@CreateDateColumn({ name: 'created_at' })

View File

@@ -24,6 +24,7 @@ import { RegisterDto } from './dto/register.dto';
import { LoginDto } from './dto/login.dto';
import { RefreshTokenDto } from './dto/refresh-token.dto';
import { LogoutDto } from './dto/logout.dto';
import { UpdateProfileDto } from './dto/update-profile.dto';
import {
RequestPasswordResetDto,
ResetPasswordDto,
@@ -88,7 +89,7 @@ export class AuthController {
@HttpCode(HttpStatus.OK)
async updateProfile(
@CurrentUser() user: any,
@Body() updateData: { name?: string },
@Body() updateData: UpdateProfileDto,
) {
return await this.authService.updateProfile(user.userId, updateData);
}

View File

@@ -0,0 +1,33 @@
import { IsString, IsOptional, IsObject, ValidateNested, IsIn } from 'class-validator';
import { Type } from 'class-transformer';
export class UserPreferencesDto {
@IsOptional()
notifications?: boolean;
@IsOptional()
emailUpdates?: boolean;
@IsOptional()
darkMode?: boolean;
@IsOptional()
@IsIn(['metric', 'imperial'])
measurementUnit?: 'metric' | 'imperial';
}
export class UpdateProfileDto {
@IsOptional()
@IsString()
name?: string;
@IsOptional()
@IsString()
locale?: string;
@IsOptional()
@IsObject()
@ValidateNested()
@Type(() => UserPreferencesDto)
preferences?: UserPreferencesDto;
}