본문 바로가기
Storify

STORIFY (0202) - 유저 프로필 추가

by Peter.JH 2024. 2. 2.
728x90

유저 프로필 추가

- 나는 로그인해서 내 프로필을 볼 수 있다. 

- 나는 내 프로필을 수정할 수 있다.

- 다른 사람이 내 프로필을 볼 수 있다. 

 

profile 관련은 user 모듈에 추가했다. user.schema에 정보를 추가해서 담아 저장할것이기 때문이다. 

 

 

users.controller 중

  @ApiBearerAuth()
  @UseGuards(AccessTokenGuard)
  @Patch('profile')
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    description: 'User Profile and Avatar Data',
    type: FileUploadDto,
  })
  @UseInterceptors(
    FileInterceptor('avatar', {
      limits: { fileSize: 4000000 }, // 4MB
      fileFilter: (req, file, callback) => {
        if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
          return callback(new Error('Only image files are allowed!'), false);
        }
        callback(null, true);
      },
    }),
  )
  async updateProfile(@Req() req, @UploadedFile() avatar): Promise<User> {
    const userId = req.user.sub;
    const updateUserInfo: UpdateUserProfileDto = req.body;
    return this.usersService.updateUserProfile(userId, updateUserInfo, avatar);
  }

 

 

users.service 중

  async updateUserProfile(
    userId: string,
    updateUserInfo: UpdateUserProfileDto,
    avatar?: Express.Multer.File,
  ): Promise<User> {
    if (avatar) {
      const imageUrl = await this.uploadProfileImage(userId, avatar);
      updateUserInfo.avatar = imageUrl;
    }
    return this.userRepository.updateUserProfile(userId, updateUserInfo);
  }

  async uploadProfileImage(
    userId: string,
    avatar: Express.Multer.File,
  ): Promise<string> {
    const fileNameParts = avatar.originalname.split('.');
    if (fileNameParts.length < 2) {
      throw new Error('Invalid file format.');
    }
    const ext = fileNameParts.pop();
    const fileName = `${userId}.${ext}`;
    return this.storagesService.imageUploadToS3(fileName, avatar, ext);
  }

  async deleteUser(userId: string): Promise<any> {
    return this.userRepository.deleteUser(userId);
  }

 

 

users.repository 중

  async updateUserProfile(
    userId: string,
    updateUserInfo: UpdateUserProfileDto,
  ): Promise<User> {
    try {
      if (updateUserInfo.nickname) {
        const existingNickname = await this.userModel
          .findOne({ nickname: updateUserInfo.nickname })
          .exec();
        if (existingNickname && existingNickname._id.toString() !== userId) {
          throw new Error('이미 사용중인 닉네임입니다.');
        }
      }

      const user = await this.userModel
        .findByIdAndUpdate(userId, updateUserInfo, { new: true })
        .select('avatar nickname introduction')
        .exec();

      if (!user) {
        throw new Error('User not found');
      }

      return user;
    } catch (error) {
      Logger.error(`updateUserProfile 실패: ${error.message}`);
      throw new Error('유저 프로필 업데이트 실패했습니다. 다시 시도해주세요.');
    }
  }

 

 

작업정리

 

1. 사용자 프로필 업데이트 API 개선:

- 사용자의 프로필과 아바타 데이터를 업데이트하는 API를 개선하였습니다. 이를 위해 multipart/form-data를 사용하여 데이터를 수신하도록 설정하였습니다.

 

2. 파일 업로드 인터셉터 적용:

- 사용자의 아바타 파일 업로드를 처리하기 위해 FileInterceptor를 사용하였습니다. 이를 통해 파일 크기 제한과 파일 형식 필터링을 적용하였습니다.

 

3. 유저 프로필 업데이트 로직 개선:

- 사용자 프로필 업데이트 로직을 개선하여, 사용자가 프로필 정보와 아바타 이미지를 함께 업데이트할 수 있도록 하였습니다. 

728x90