diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberProfileResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberProfileResponse.java new file mode 100644 index 00000000..84b8a856 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberProfileResponse.java @@ -0,0 +1,17 @@ +package clap.server.adapter.inbound.web.dto.member; + +import clap.server.adapter.outbound.persistense.entity.member.constant.MemberRole; +import io.swagger.v3.oas.annotations.media.Schema; + +public record MemberProfileResponse( + @Schema(description = "회원 ID") + Long memberId, + @Schema(description = "회원 이름") + String memberName, + @Schema(description = "회원 닉네임, 로그인에 쓰입니다") + String nickname, + @Schema(description = "회원 프로필 이미지") + String imageUrl, + @Schema(description = "회원 역할") + MemberRole memberRole +) {} diff --git a/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java b/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java index 8354dd05..c3e88222 100644 --- a/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java +++ b/src/main/java/clap/server/adapter/inbound/web/member/ManagerController.java @@ -1,22 +1,25 @@ package clap.server.adapter.inbound.web.member; -import clap.server.application.port.inbound.domain.FindManagersUsecase; import clap.server.adapter.inbound.web.dto.admin.FindManagersResponse; +import clap.server.application.port.inbound.domain.FindManagersUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; import java.util.List; -@RestController -@RequestMapping("/manager") + +@Tag(name = "담당자 조회") +@WebAdapter @RequiredArgsConstructor +@RequestMapping("/api") public class ManagerController { private final FindManagersUsecase findManagersUsecase; - @GetMapping + @GetMapping("/managers") public List findManagers() { List managers = findManagersUsecase.execute(); diff --git a/src/main/java/clap/server/adapter/inbound/web/member/MemberInfoController.java b/src/main/java/clap/server/adapter/inbound/web/member/MemberInfoController.java new file mode 100644 index 00000000..96c35221 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/member/MemberInfoController.java @@ -0,0 +1,28 @@ +package clap.server.adapter.inbound.web.member; + +import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; +import clap.server.application.port.inbound.member.MemberInfoUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Tag(name = "회원 정보 조회/수정") +@WebAdapter +@RequiredArgsConstructor +@RequestMapping("/api/members") +public class MemberInfoController { + private final MemberInfoUsecase memberInfoUsecase; + + @Operation(summary = "회원 프로필을 조회합니다. 활성화된 회원만 조회 가능합니다.") + @GetMapping("/profile") + public ResponseEntity getMemberProfile(@AuthenticationPrincipal SecurityUserDetails userInfo) { + return ResponseEntity.ok(memberInfoUsecase.getMemberProfile(userInfo.getUserId())); + } + +} diff --git a/src/main/java/clap/server/adapter/inbound/web/member/ResetPasswordController.java b/src/main/java/clap/server/adapter/inbound/web/member/ResetPasswordController.java index 774b72e6..21aeaf65 100644 --- a/src/main/java/clap/server/adapter/inbound/web/member/ResetPasswordController.java +++ b/src/main/java/clap/server/adapter/inbound/web/member/ResetPasswordController.java @@ -1,7 +1,7 @@ package clap.server.adapter.inbound.web.member; import clap.server.adapter.inbound.security.SecurityUserDetails; -import clap.server.application.port.inbound.auth.ResetPasswordUsecase; +import clap.server.application.port.inbound.member.ResetPasswordUsecase; import clap.server.common.annotation.architecture.WebAdapter; import clap.server.common.annotation.validation.password.ValidPassword; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/clap/server/application/mapper/MemberMapper.java b/src/main/java/clap/server/application/mapper/MemberMapper.java index f7f14d34..6f23c923 100644 --- a/src/main/java/clap/server/application/mapper/MemberMapper.java +++ b/src/main/java/clap/server/application/mapper/MemberMapper.java @@ -1,5 +1,6 @@ package clap.server.application.mapper; +import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; import clap.server.domain.model.member.Member; import clap.server.domain.model.member.MemberInfo; @@ -13,4 +14,14 @@ public static Member toMember(MemberInfo memberInfo) { .memberInfo(memberInfo) .build(); } + + public static MemberProfileResponse toMemberProfileResponse(Member member) { + return new MemberProfileResponse( + member.getMemberId(), + member.getMemberInfo().getName(), + member.getMemberInfo().getNickname(), + member.getImageUrl(), + member.getMemberInfo().getRole() + ); + } } \ No newline at end of file diff --git a/src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java b/src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java new file mode 100644 index 00000000..feef14f0 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java @@ -0,0 +1,7 @@ +package clap.server.application.port.inbound.member; + +import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; + +public interface MemberInfoUsecase { + MemberProfileResponse getMemberProfile(Long memberId); +} diff --git a/src/main/java/clap/server/application/port/inbound/auth/ResetPasswordUsecase.java b/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java similarity index 76% rename from src/main/java/clap/server/application/port/inbound/auth/ResetPasswordUsecase.java rename to src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java index a1ef7a92..1dc3ebb2 100644 --- a/src/main/java/clap/server/application/port/inbound/auth/ResetPasswordUsecase.java +++ b/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java @@ -1,4 +1,4 @@ -package clap.server.application.port.inbound.auth; +package clap.server.application.port.inbound.member; public interface ResetPasswordUsecase { void resetPassword(Long memberId, String password); diff --git a/src/main/java/clap/server/application/service/member/MemberInfoService.java b/src/main/java/clap/server/application/service/member/MemberInfoService.java new file mode 100644 index 00000000..60ec23bd --- /dev/null +++ b/src/main/java/clap/server/application/service/member/MemberInfoService.java @@ -0,0 +1,29 @@ +package clap.server.application.service.member; + +import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; +import clap.server.application.port.inbound.domain.MemberService; +import clap.server.application.port.inbound.member.MemberInfoUsecase; +import clap.server.application.port.outbound.member.CommandMemberPort; +import clap.server.application.port.outbound.member.LoadMemberPort; +import clap.server.common.annotation.architecture.ApplicationService; +import clap.server.domain.model.member.Member; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +import static clap.server.application.mapper.MemberMapper.toMemberProfileResponse; + +@ApplicationService +@RequiredArgsConstructor +class MemberInfoService implements MemberInfoUsecase { + private final MemberService memberService; + private final LoadMemberPort loadMemberPort; + private final CommandMemberPort commandMemberPort; + + + @Override + @Transactional(readOnly = true) + public MemberProfileResponse getMemberProfile(Long memberId) { + Member member = memberService.findActiveMember(memberId); + return toMemberProfileResponse(member); + } +} diff --git a/src/main/java/clap/server/application/service/member/ResetPasswordService.java b/src/main/java/clap/server/application/service/member/ResetPasswordService.java index 99d967ec..60752411 100644 --- a/src/main/java/clap/server/application/service/member/ResetPasswordService.java +++ b/src/main/java/clap/server/application/service/member/ResetPasswordService.java @@ -1,6 +1,6 @@ package clap.server.application.service.member; -import clap.server.application.port.inbound.auth.ResetPasswordUsecase; +import clap.server.application.port.inbound.member.ResetPasswordUsecase; import clap.server.application.port.inbound.domain.MemberService; import clap.server.application.port.outbound.member.CommandMemberPort; import clap.server.common.annotation.architecture.ApplicationService; diff --git a/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java b/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java index 14a1689e..67804658 100644 --- a/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java +++ b/src/test/java/clap/server/adapter/inbound/web/admin/MemberControllerTest.java @@ -196,7 +196,7 @@ public void setupTestData() { @Test @WithMockUser(username = "admin", roles = "ADMIN") public void testFindManagers() throws Exception { - mockMvc.perform(get("/manager")) + mockMvc.perform(get("/api/managers")) .andExpect(status().isOk()) .andExpect(jsonPath("$[0].nickname").value("Manager1")) .andExpect(jsonPath("$[0].imageUrl").value("http://example.com/manager1.jpg"))