Skip to content

Commit

Permalink
[FEATURE] 유저 프로필(기본정보) 수정 (#340)
Browse files Browse the repository at this point in the history
* feat(basicInfo): 사용자 기본 정보 요청 DTO 추가

- VolunteerBasicInfoRequestDto 추가
  - 공통 기본 정보(CommonBasicInfoRequestDto), 닉네임, 성별 필드 포함
- CenterBasicInfoRequestDto 추가
  - 공통 기본 정보(CommonBasicInfoRequestDto), 홈페이지 링크 필드 포함
- CommonBasicInfoRequestDto 추가
  - 이름, 연락처, 이미지 링크, 소개 글 필드 포함

* feat(domain): 공통 속성 및 엔티티별 업데이트 메서드 추가

- UserCommonAttribute: CommonBasicInfoRequestDto 기반 업데이트 메서드 추가
- NEWVolunteer: nickname, gender, volunteerStats 업데이트 메서드 추가
- NEWCenter: homepageUrl 업데이트 메서드 추가

* test(user): 기본 정보 업데이트 로직 테스트 추가

- CommonBasicInfoRequestDto 객체 생성 및 활용 추가
- UserCommonAttribute의 customize() 메서드를 update() 메서드로 수정

* refactor(controller): 메서드명 올바르게 수정, 괄호 위치 수정

* feat(user): 사용자 기본 정보 업데이트 기능 추가

- UpdateBasicInfoUseCase 인터페이스 정의
- UpdateBasicInfoService 구현
- 사용자 공통 속성 업데이트 로직 추가
- 봉사자 및 센터 속성별 업데이트 로직 포함

* refactor(basicInfo): 역할 ID 인자를 제거하여 메소드 시그니처 개선

- VolunteerBasicInfoRequestDto와 CenterBasicInfoRequestDto를 업데이트하는 메소드에서 roleId 파라미터 삭제

* feat(basicInfo): 유저 기본 정보 업데이트 API 추가

- UserCommandController 클래스 생성
- 봉사자 기본 정보 업데이트 API 추가
- 센터 기본 정보 업데이트 API 추가

* refactor(controller): 기존 PostMapping을 PutMapping으로 변경

- 봉사자 및 센터 기본 정보 업데이트 엔드포인트를 PUT 메서드로 변경
- RESTful API 규칙에 따라 정보 업데이트에 PUT 메서드 활용

* test(user): 사용자 기본 정보 업데이트 서비스 테스트 추가

- 봉사자의 기본 정보를 업데이트하는 테스트 케이스 추가
- 센터의 기본 정보를 업데이트하는 테스트 케이스 추가

* refactor(user): 불필요한 주석 삭제

* refactor: 불필요한 어노테이션, 오타 수정
  • Loading branch information
m-a-king authored Jan 28, 2025
1 parent 145498d commit b1117c7
Show file tree
Hide file tree
Showing 12 changed files with 333 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/somemore/center/domain/NEWCenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ public static NEWCenter createDefault(UUID userId) {
.homepageUrl("")
.build();
}

public void update(String homepageUrl) {
this.homepageUrl = homepageUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.somemore.user.controller;

import com.somemore.global.auth.annotation.UserId;
import com.somemore.global.common.response.ApiResponse;
import com.somemore.user.dto.basicinfo.CenterBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.VolunteerBasicInfoRequestDto;
import com.somemore.user.usecase.UpdateBasicInfoUseCase;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@Tag(name = "User Command API", description = "유저 생성 수정 삭제 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/user")
public class UserCommandController {

private final UpdateBasicInfoUseCase updateBasicInfoUseCase;

@Secured("ROLE_VOLUNTEER")
@PutMapping("/basic-info/volunteer")
@Operation(summary = "봉사자 기본 정보 업데이트", description = "봉사자의 기본 정보를 업데이트합니다.")
public ApiResponse<String> registerBasicInfo(
@UserId UUID userId,
@RequestBody VolunteerBasicInfoRequestDto volunteerBasicInfoRequestDto
) {
updateBasicInfoUseCase.update(userId, volunteerBasicInfoRequestDto);
return ApiResponse.ok("봉사자 기본 정보 업데이트 완료");
}

@Secured("ROLE_CENTER")
@PutMapping("/basic-info/center")
@Operation(summary = "센터 기본 정보 업데이트", description = "센터의 기본 정보를 업데이트합니다.")
public ApiResponse<String> registerBasicInfo(
@UserId UUID userId,
@RequestBody CenterBasicInfoRequestDto centerBasicInfoRequestDto
) {
updateBasicInfoUseCase.update(userId, centerBasicInfoRequestDto);
return ApiResponse.ok("센터 기본 정보 업데이 완료");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ public ApiResponse<Boolean> checkUserExists(
}

@GetMapping("/check/basic-info")
@Operation(summary = "유저 기본 정보 입력 상태 확인", description = "현재 유저의 필수 입력 정보가 모두 완료되었는지 확인합니다."
)
public ApiResponse<Boolean> checkUserExists(
@Operation(summary = "유저 기본 정보 입력 상태 확인", description = "현재 유저의 필수 입력 정보가 모두 완료되었는지 확인합니다.")
public ApiResponse<Boolean> checkBasicInfo(
@UserId UUID userId
) {
boolean isBasicInfoComplete = validateBasicInfoUseCase.isBasicInfoComplete(userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.somemore.global.common.entity.BaseEntity;
import com.somemore.global.imageupload.service.ImageUploadService;
import com.somemore.user.dto.basicinfo.CommonBasicInfoRequestDto;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -44,8 +45,11 @@ public class UserCommonAttribute extends BaseEntity {
@Column(name = "is_customized", nullable = false)
private boolean isCustomized;

public void customize() {
// TODO param의 정보를 필드에 업데이트
public void update(CommonBasicInfoRequestDto commonBasicInfoRequestDto) {
this.name = commonBasicInfoRequestDto.name();
this.contactNumber = commonBasicInfoRequestDto.contactNumber();
this.imgUrl = commonBasicInfoRequestDto.imgUrl();
this.introduce = commonBasicInfoRequestDto.introduce();
this.isCustomized = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.somemore.user.dto.basicinfo;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record CenterBasicInfoRequestDto(
@Schema(description = "공통 기본 정보")
@NotBlank(message = "공통 기본 정보는 필수 값입니다.")
CommonBasicInfoRequestDto commonBasicInfo,

@Schema(description = "홈페이지 링크")
@NotBlank(message = "홈페이지 링크는 필수 값입니다.")
String homepageUrl
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.somemore.user.dto.basicinfo;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record CommonBasicInfoRequestDto(
@Schema(description = "이름", example = "홍길동, 롯데리아")
@NotBlank(message = "이름은 필수 값입니다.")
String name,

@Schema(description = "연락처", example = "010-1234-5678, 02-123-4567")
@NotBlank(message = "연락처는 필수 값입니다.")
String contactNumber,

@Schema(description = "이미지 링크", example = "https://image.image")
@NotBlank(message = "이미지 링크는 필수 값입니다.")
String imgUrl,

@Schema(description = "소개 글", example = "햄부기햄북햄북어햄북스딱스함부르크햄부가우가햄비기햄부거햄부가티햄부기온앤온을 차려오거라")
@NotBlank(message = "소개 글은 필수 값입니다.")
String introduce
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.somemore.user.dto.basicinfo;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public record VolunteerBasicInfoRequestDto(
@Schema(description = "공통 기본 정보")
@NotBlank(message = "공통 기본 정보는 필수 값입니다.")
CommonBasicInfoRequestDto commonBasicInfo,

@Schema(description = "닉네임", example = "칠가이")
@NotBlank(message = "닉네임은 필수 값입니다.")
String nickname,

@Schema(description = "성별", example = "MALE", allowableValues = {"MALE", "FEMALE"})
@NotBlank(message = "성별은 필수 값입니다.")
String gender
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.somemore.user.service;

import com.somemore.center.domain.NEWCenter;
import com.somemore.center.usecase.NEWCenterQueryUseCase;
import com.somemore.domains.volunteer.domain.Gender;
import com.somemore.user.domain.UserCommonAttribute;
import com.somemore.user.dto.basicinfo.CenterBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.CommonBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.VolunteerBasicInfoRequestDto;
import com.somemore.user.usecase.UpdateBasicInfoUseCase;
import com.somemore.user.usecase.UserQueryUseCase;
import com.somemore.volunteer.domain.NEWVolunteer;
import com.somemore.volunteer.usecase.NEWVolunteerQueryUseCase;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@Transactional
@Slf4j
@RequiredArgsConstructor
public class UpdateBasicInfoService implements UpdateBasicInfoUseCase {

private final UserQueryUseCase userQueryUseCase;
private final NEWVolunteerQueryUseCase volunteerQueryUseCase;
private final NEWCenterQueryUseCase centerQueryUseCase;

@Override
public void update(UUID userId, VolunteerBasicInfoRequestDto volunteerBasicInfoRequestDto) {
updateCommonAttribute(userId, volunteerBasicInfoRequestDto.commonBasicInfo());
updateVolunteerAttribute(userId, volunteerBasicInfoRequestDto);
}

@Override
public void update(UUID userId, CenterBasicInfoRequestDto centerBasicInfoRequestDto) {
updateCommonAttribute(userId, centerBasicInfoRequestDto.commonBasicInfo());
updateCenterAttribute(userId, centerBasicInfoRequestDto);
}

private void updateCommonAttribute(UUID userId, CommonBasicInfoRequestDto commonBasicInfoRequestDto) {
UserCommonAttribute commonAttribute = userQueryUseCase.getCommonAttributeByUserId(userId);
commonAttribute.update(commonBasicInfoRequestDto);
}

private void updateVolunteerAttribute(UUID userId, VolunteerBasicInfoRequestDto volunteerBasicInfoRequestDto) {
NEWVolunteer volunteer = volunteerQueryUseCase.getByUserId(userId);
volunteer.update(volunteerBasicInfoRequestDto.nickname());
volunteer.update(Gender.from(volunteerBasicInfoRequestDto.gender()));
}

private void updateCenterAttribute(UUID userId, CenterBasicInfoRequestDto centerBasicInfoRequestDto) {
NEWCenter center = centerQueryUseCase.getByUserId(userId);
center.update(centerBasicInfoRequestDto.homepageUrl());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.somemore.user.usecase;

import com.somemore.user.dto.basicinfo.CenterBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.VolunteerBasicInfoRequestDto;

import java.util.UUID;

public interface UpdateBasicInfoUseCase {

void update(UUID userId, VolunteerBasicInfoRequestDto volunteerBasicInfoRequestDto);

void update(UUID userId, CenterBasicInfoRequestDto centerBasicInfoRequestDto);
}
8 changes: 8 additions & 0 deletions src/main/java/com/somemore/volunteer/domain/NEWVolunteer.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ public static NEWVolunteer createDefault(UUID userId) {
.build();
}

public void update(String nickname) {
this.nickname = nickname;
}

public void update(Gender gender) {
this.gender = gender;
}

public void updateVolunteerStats(int hours, int count) {
this.totalVolunteerHours += hours;
this.totalVolunteerCount += count;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.somemore.user.service;

import com.somemore.center.domain.NEWCenter;
import com.somemore.center.repository.NEWCenterRepository;
import com.somemore.support.IntegrationTestSupport;
import com.somemore.user.domain.User;
import com.somemore.user.domain.UserCommonAttribute;
import com.somemore.user.domain.UserRole;
import com.somemore.user.dto.UserAuthInfo;
import com.somemore.user.dto.basicinfo.CenterBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.CommonBasicInfoRequestDto;
import com.somemore.user.dto.basicinfo.VolunteerBasicInfoRequestDto;
import com.somemore.user.repository.user.UserRepository;
import com.somemore.user.repository.usercommonattribute.UserCommonAttributeRepository;
import com.somemore.volunteer.domain.NEWVolunteer;
import com.somemore.volunteer.repository.NEWVolunteerRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

@Transactional
class UpdateBasicInfoServiceTest extends IntegrationTestSupport {

@Autowired
private UpdateBasicInfoService updateBasicInfoService;

@Autowired
private UserRepository userRepository;
@Autowired
private UserCommonAttributeRepository userCommonAttributeRepository;
@Autowired
private NEWVolunteerRepository volunteerRepository;
@Autowired
private NEWCenterRepository centerRepository;

@Test
@DisplayName("봉사자 기본 정보를 업데이트 할 수 있다.")
void updateVolunteerBasicInfo() {
// given
UUID userId = UUID.randomUUID();
UserAuthInfo authInfo = UserAuthInfo.of("test", "test");
User user = User.of(authInfo, UserRole.VOLUNTEER);
UserCommonAttribute userCommonAttribute = UserCommonAttribute.createDefault(userId, UserRole.VOLUNTEER);

NEWVolunteer volunteer = NEWVolunteer.createDefault(userId);

userRepository.save(user);
userCommonAttributeRepository.save(userCommonAttribute);
volunteerRepository.save(volunteer);

CommonBasicInfoRequestDto commonBasicInfoRequestDto = createCommonBasicInfoRequestDto();

VolunteerBasicInfoRequestDto volunteerBasicInfoRequestDto =
new VolunteerBasicInfoRequestDto(
commonBasicInfoRequestDto,
"test",
"test");

boolean customizedBeforeUpdate = userCommonAttributeRepository.findIsCustomizedByUserId(userId)
.orElseThrow();

// when
updateBasicInfoService.update(userId, volunteerBasicInfoRequestDto);

// then
boolean customizedAfterUpdate = userCommonAttributeRepository.findIsCustomizedByUserId(userId)
.orElseThrow();

assertThat(customizedBeforeUpdate).isFalse();
assertThat(customizedAfterUpdate).isTrue();
}

@Test
@DisplayName("센터 기본 정보를 업데이트 할 수 있다.")
void updateCenterBasicInfo() {
// given
UUID userId = UUID.randomUUID();
UserAuthInfo authInfo = UserAuthInfo.of("centerTest", "centerTest");
User user = User.of(authInfo, UserRole.CENTER);
UserCommonAttribute userCommonAttribute = UserCommonAttribute.createDefault(userId, UserRole.CENTER);

NEWCenter center = NEWCenter.createDefault(userId);

userRepository.save(user);
userCommonAttributeRepository.save(userCommonAttribute);
centerRepository.save(center);

CommonBasicInfoRequestDto commonBasicInfoRequestDto = createCommonBasicInfoRequestDto();

CenterBasicInfoRequestDto centerBasicInfoRequestDto =
new CenterBasicInfoRequestDto(
commonBasicInfoRequestDto,
"Main Center"
);

boolean customizedBeforeUpdate = userCommonAttributeRepository.findIsCustomizedByUserId(userId)
.orElseThrow();

// when
updateBasicInfoService.update(userId, centerBasicInfoRequestDto);

// then
boolean customizedAfterUpdate = userCommonAttributeRepository.findIsCustomizedByUserId(userId)
.orElseThrow();

assertThat(customizedBeforeUpdate).isFalse();
assertThat(customizedAfterUpdate).isTrue();
}

private static CommonBasicInfoRequestDto createCommonBasicInfoRequestDto() {
return new CommonBasicInfoRequestDto(
"test",
"test",
"test",
"test"
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.somemore.user.domain.UserCommonAttribute;
import com.somemore.user.domain.UserRole;
import com.somemore.user.dto.UserAuthInfo;
import com.somemore.user.dto.basicinfo.CommonBasicInfoRequestDto;
import com.somemore.user.repository.user.UserRepository;
import com.somemore.user.repository.usercommonattribute.UserCommonAttributeRepository;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -39,8 +40,10 @@ void setup() {
@Test
void isBasicInfoComplete_ReturnsTrue() {
// given
CommonBasicInfoRequestDto commonBasicInfoRequestDto =
new CommonBasicInfoRequestDto("test", "test", "test", "test");
UserCommonAttribute userCommonAttribute = UserCommonAttribute.createDefault(user.getId(), UserRole.VOLUNTEER);
userCommonAttribute.customize();
userCommonAttribute.update(commonBasicInfoRequestDto);
userCommonAttributeRepository.save(userCommonAttribute);

// when
Expand Down

0 comments on commit b1117c7

Please sign in to comment.