diff --git a/build.gradle b/build.gradle index 962217f7..f46f2163 100644 --- a/build.gradle +++ b/build.gradle @@ -101,6 +101,10 @@ dependencies { implementation 'software.amazon.awssdk:s3' implementation 'ch.qos.logback:logback-classic:1.4.12' + // Apache Tika + implementation 'org.apache.tika:tika-core:2.9.0' + implementation 'org.apache.tika:tika-parsers:2.9.0' + } tasks.named('test') { diff --git a/src/main/java/clap/server/adapter/inbound/web/admin/ManageMemberController.java b/src/main/java/clap/server/adapter/inbound/web/admin/ManageMemberController.java index 69d0e02b..fa4a068f 100644 --- a/src/main/java/clap/server/adapter/inbound/web/admin/ManageMemberController.java +++ b/src/main/java/clap/server/adapter/inbound/web/admin/ManageMemberController.java @@ -1,8 +1,8 @@ package clap.server.adapter.inbound.web.admin; import clap.server.adapter.inbound.security.SecurityUserDetails; -import clap.server.adapter.inbound.web.dto.admin.UpdateMemberInfoRequest; -import clap.server.application.port.inbound.admin.ManageMemberUsecase; +import clap.server.adapter.inbound.web.dto.admin.UpdateMemberRequest; +import clap.server.application.port.inbound.admin.UpdateMemberUsecase; import clap.server.common.annotation.architecture.WebAdapter; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -20,14 +20,14 @@ @RequiredArgsConstructor @RequestMapping("/api/managements/members") public class ManageMemberController { - private final ManageMemberUsecase manageMemberUsecase; + private final UpdateMemberUsecase updateMemberUsecase; @Operation(summary = "회원 정보 수정 API") @PostMapping("/{memberId}") @Secured("ROLE_ADMIN") public void registerMember(@AuthenticationPrincipal SecurityUserDetails userInfo, @PathVariable Long memberId, - @RequestBody @Valid UpdateMemberInfoRequest request){ - manageMemberUsecase.updateMemberInfo(memberId, request); + @RequestBody @Valid UpdateMemberRequest request){ + updateMemberUsecase.updateMemberInfo(userInfo.getUserId(), memberId, request); } } diff --git a/src/main/java/clap/server/adapter/inbound/web/auth/AuthController.java b/src/main/java/clap/server/adapter/inbound/web/auth/AuthController.java index c14f4722..79d26333 100644 --- a/src/main/java/clap/server/adapter/inbound/web/auth/AuthController.java +++ b/src/main/java/clap/server/adapter/inbound/web/auth/AuthController.java @@ -3,7 +3,8 @@ import clap.server.adapter.inbound.security.SecurityUserDetails; import clap.server.adapter.inbound.web.dto.auth.LoginRequest; import clap.server.adapter.inbound.web.dto.auth.LoginResponse; -import clap.server.application.port.inbound.auth.AuthUsecase; +import clap.server.application.port.inbound.auth.LoginUsecase; +import clap.server.application.port.inbound.auth.LogoutUsecase; import clap.server.common.annotation.architecture.WebAdapter; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -23,7 +24,8 @@ @RequiredArgsConstructor @RequestMapping("/api/auths") public class AuthController { - private final AuthUsecase authUsecase; + private final LoginUsecase loginUsecase; + private final LogoutUsecase logoutUsecase; @Operation(summary = "로그인 API") @PostMapping("/login") @@ -31,7 +33,7 @@ public ResponseEntity login(@RequestHeader(name = "sessionId") St @RequestBody LoginRequest request, HttpServletRequest httpRequest) { String clientIp = getClientIp(httpRequest); - LoginResponse response = authUsecase.login(request.nickname(), request.password(), sessionId, clientIp); + LoginResponse response = loginUsecase.login(request.nickname(), request.password(), sessionId, clientIp); return ResponseEntity.ok(response); } @@ -41,7 +43,7 @@ public void logout(@AuthenticationPrincipal SecurityUserDetails userInfo, @Parameter(hidden = true) @RequestHeader(value = "Authorization") String authHeader, @RequestHeader(value = "refreshToken") String refreshToken) { String accessToken = authHeader.split(" ")[1]; - authUsecase.logout(userInfo.getUserId(), accessToken, refreshToken); + logoutUsecase.logout(userInfo.getUserId(), accessToken, refreshToken); } } diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberInfoRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberRequest.java similarity index 96% rename from src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberInfoRequest.java rename to src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberRequest.java index 1aa4f905..8616fb4c 100644 --- a/src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberInfoRequest.java +++ b/src/main/java/clap/server/adapter/inbound/web/dto/admin/UpdateMemberRequest.java @@ -6,7 +6,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; -public record UpdateMemberInfoRequest( +public record UpdateMemberRequest( @NotBlank @Schema(description = "회원 이름", example = "서주원") String name, @NotBlank diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberDetailInfoResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberDetailInfoResponse.java new file mode 100644 index 00000000..2327bdb2 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/member/MemberDetailInfoResponse.java @@ -0,0 +1,37 @@ +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 MemberDetailInfoResponse( + String profileImageUrl, + @Schema(description = "회원 이름", example = "서주원") + String name, + @Schema(description = "회원 아이디", example = "siena.it") + String nicknanme, + @Schema(description = "회원 이메일", example = "siena.it@gmail.com") + String email, + @Schema(description = "승인 권한 여부") + Boolean isReviewer, + @Schema(description = "회원 역할") + MemberRole role, + @Schema(description = "부서") + String departmentName, + @Schema(description = "직책") + String departmentRole, + @Schema(description = "알림 수신 여부") + NotificationSettingInfoResponse notificationSettingInfo +) { + public static record NotificationSettingInfoResponse( + @Schema(description = "아지트 알림 수신 여부") + boolean agit, + @Schema(description = "이메일 알림 수신 여부") + boolean email, + @Schema(description = "카카오 워크 알림 수신 여부") + boolean kakaoWork + ) { + } +} + + + diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/member/UpdateMemberInfoRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/member/UpdateMemberInfoRequest.java new file mode 100644 index 00000000..25269a07 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/member/UpdateMemberInfoRequest.java @@ -0,0 +1,19 @@ +package clap.server.adapter.inbound.web.dto.member; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; + +public record UpdateMemberInfoRequest( + @NotBlank @Schema(description = "이름") + String name, + @Schema(description = "아지트 알림 수신 여부") + boolean agitNotification, + @Schema(description = "이메일 알림 수신 여부") + boolean emailNotification, + @Schema(description = "카카오 워크 알림 수신 여부") + boolean kakaoWorkNotification +) { +} + + + 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 index 3633bb76..46d9ce8e 100644 --- a/src/main/java/clap/server/adapter/inbound/web/member/MemberInfoController.java +++ b/src/main/java/clap/server/adapter/inbound/web/member/MemberInfoController.java @@ -1,28 +1,54 @@ package clap.server.adapter.inbound.web.member; import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.adapter.inbound.web.dto.member.MemberDetailInfoResponse; import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; -import clap.server.application.port.inbound.member.MemberInfoUsecase; +import clap.server.adapter.inbound.web.dto.member.UpdateMemberInfoRequest; +import clap.server.application.port.inbound.member.UpdateMemberInfoUsecase; +import clap.server.application.port.inbound.member.MemberDetailInfoUsecase; +import clap.server.application.port.inbound.member.MemberProfileUsecase; 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.MediaType; 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.PatchMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; @Tag(name = "01. Member", description = "회원 정보 조회 및 수정 API") @WebAdapter @RequiredArgsConstructor @RequestMapping("/api/members") public class MemberInfoController { - private final MemberInfoUsecase memberInfoUsecase; + private final MemberProfileUsecase memberProfileUsecase; + private final MemberDetailInfoUsecase memberDetailInfoUsecase; + private final UpdateMemberInfoUsecase updateMemberInfoUsecase; - @Operation(summary = "회원 프로필을 조회합니다. 활성화된 회원만 조회 가능합니다.") + @Operation(summary = "회원 프로필 조회 API") @GetMapping("/profile") public ResponseEntity getMemberProfile(@AuthenticationPrincipal SecurityUserDetails userInfo) { - return ResponseEntity.ok(memberInfoUsecase.getMemberProfile(userInfo.getUserId())); + return ResponseEntity.ok(memberProfileUsecase.getMemberProfile(userInfo.getUserId())); + } + + @Operation(summary = "회원 상세 정보 조회 API") + @GetMapping("/info") + public ResponseEntity getMemberDetailInfo(@AuthenticationPrincipal SecurityUserDetails userInfo) { + return ResponseEntity.ok(memberDetailInfoUsecase.getMemberInfo(userInfo.getUserId())); } + @Operation(summary = "회원 정보 수정 API", description = "이미지 수정이 없을 시에는 profileImage를 보내지 않습니다.") + @PatchMapping(value = "/info", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE}) + public void updateMemberDetailInfo( + @RequestPart(name = "memberInfo") UpdateMemberInfoRequest request, + @RequestPart(name = "profileImage", required = false) MultipartFile profileImage, + @AuthenticationPrincipal SecurityUserDetails userInfo) throws IOException { + updateMemberInfoUsecase.updateMemberInfo(userInfo.getUserId(), request, profileImage); + } } 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 f7d896b9..a81e2df6 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,6 +1,7 @@ package clap.server.adapter.inbound.web.member; import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.application.port.inbound.member.ResetInitialPasswordUsecase; import clap.server.application.port.inbound.member.ResetPasswordUsecase; import clap.server.common.annotation.architecture.WebAdapter; import clap.server.common.annotation.validation.password.ValidPassword; @@ -19,12 +20,13 @@ @RequestMapping("/api") public class ResetPasswordController { private final ResetPasswordUsecase resetPasswordUsecase; + private final ResetInitialPasswordUsecase resetInitialPasswordUsecase; @Operation(summary = "초기 로그인 후 비밀번호 재설정 API", description = "swagger에서 따옴표를 포함하지 않고 요청합니다.") @PatchMapping("/members/initial-password") public void resetPasswordAndActivateMember(@AuthenticationPrincipal SecurityUserDetails userInfo, @RequestBody @NotBlank @ValidPassword String password) { - resetPasswordUsecase.resetPasswordAndActivateMember(userInfo.getUserId(), password); + resetInitialPasswordUsecase.resetPasswordAndActivateMember(userInfo.getUserId(), password); } @Operation(summary = "비밀번호 재설정 API", description = "swagger에서 따옴표를 포함하지 않고 요청합니다.") diff --git a/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java b/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java index b45238b1..a8caae72 100644 --- a/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java +++ b/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java @@ -34,7 +34,7 @@ public class ManagementTaskController { @Secured({"ROLE_MANAGER", "ROLE_USER"}) public ResponseEntity createTask( @RequestPart(name = "taskInfo") @Valid CreateTaskRequest createTaskRequest, - @RequestPart(name = "attachment") @NotNull List attachments, + @RequestPart(name = "attachment", required = false) @NotNull List attachments, @AuthenticationPrincipal SecurityUserDetails userInfo ){ return ResponseEntity.ok(createTaskUsecase.createTask(userInfo.getUserId(), createTaskRequest, attachments)); @@ -46,7 +46,7 @@ public ResponseEntity createTask( public ResponseEntity updateTask( @PathVariable @NotNull Long taskId, @RequestPart(name = "taskInfo") @Valid UpdateTaskRequest updateTaskRequest, - @RequestPart(name = "attachment") @NotNull List attachments, + @RequestPart(name = "attachment", required = false) @NotNull List attachments, @AuthenticationPrincipal SecurityUserDetails userInfo){ return ResponseEntity.ok(updateTaskUsecase.updateTask(userInfo.getUserId(), taskId, updateTaskRequest, attachments)); } diff --git a/src/main/java/clap/server/adapter/outbound/infrastructure/s3/S3UploadAdapter.java b/src/main/java/clap/server/adapter/outbound/infrastructure/s3/S3UploadAdapter.java index 68798b73..6b8f33a9 100644 --- a/src/main/java/clap/server/adapter/outbound/infrastructure/s3/S3UploadAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/infrastructure/s3/S3UploadAdapter.java @@ -5,7 +5,7 @@ import clap.server.config.s3.KakaoS3Config; import clap.server.common.constants.FilePathConstants; import clap.server.exception.S3Exception; -import clap.server.exception.code.S3Errorcode; +import clap.server.exception.code.AttachmentErrorcode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.multipart.MultipartFile; @@ -34,11 +34,12 @@ public String uploadSingleFile(FilePathConstants filePrefix, MultipartFile file) try { Path filePath = getFilePath(file); String objectKey = createObjectKey(filePrefix.getPath(), file.getOriginalFilename()); + uploadToS3(objectKey, filePath); Files.delete(filePath); return getFileUrl(objectKey); } catch (IOException e) { - throw new S3Exception(S3Errorcode.FILE_UPLOAD_REQUEST_FAILED); + throw new S3Exception(AttachmentErrorcode.FILE_UPLOAD_REQUEST_FAILED); } } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java index ba9862ad..7d4e1547 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberEntity.java @@ -45,7 +45,6 @@ public class MemberEntity extends BaseTimeEntity { @Column(nullable = false) private MemberStatus status; - // TODO: spring security 적용 예정 @Column(nullable = false) private String password; @@ -53,7 +52,11 @@ public class MemberEntity extends BaseTimeEntity { private String imageUrl; @Column - private Boolean notificationEnabled; + private Boolean kakaoWorkNotificationEnabled; + @Column + private Boolean agitNotificationEnabled; + @Column + private Boolean emailNotificationEnabled; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "admin_id") diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberNotificationEntity.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberNotificationEntity.java deleted file mode 100644 index 3708775e..00000000 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/member/MemberNotificationEntity.java +++ /dev/null @@ -1,32 +0,0 @@ -package clap.server.adapter.outbound.persistense.entity.member; - -import clap.server.adapter.outbound.persistense.entity.common.BaseTimeEntity; -import clap.server.adapter.outbound.persistense.entity.notification.NotificationChannelEntity; -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Entity -@Table(name = "member_notification") -@Getter -@SuperBuilder -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class MemberNotificationEntity extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false) - private Long memberNotificationId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private MemberEntity member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "notification_channel_id") - private NotificationChannelEntity notificationChannel; - - @Column(nullable = false) - private boolean isEnabled; -} diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/NotificationChannelEntity.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/NotificationChannelEntity.java deleted file mode 100644 index 948e663d..00000000 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/NotificationChannelEntity.java +++ /dev/null @@ -1,31 +0,0 @@ -package clap.server.adapter.outbound.persistense.entity.notification; - -import clap.server.adapter.outbound.persistense.entity.common.BaseTimeEntity; -import clap.server.adapter.outbound.persistense.entity.member.MemberEntity; -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Entity -@Table(name = "notification_channel") -@Getter -@SuperBuilder -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class NotificationChannelEntity extends BaseTimeEntity { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(nullable = false) - private Long notificationChannelId; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "admin_id", nullable = false) - private MemberEntity admin; - - @Column(nullable = false) - private String code; - - @Column(nullable = false) - private String name; -} diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/constant/NotificationChannelEnum.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/constant/NotificationChannelEnum.java deleted file mode 100644 index 07f9b048..00000000 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/notification/constant/NotificationChannelEnum.java +++ /dev/null @@ -1,12 +0,0 @@ -package clap.server.adapter.outbound.persistense.entity.notification.constant; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum NotificationChannelEnum { - KAKAO_WORK, - EMAIL, - AGIT -} diff --git a/src/main/java/clap/server/adapter/outbound/persistense/repository/member/MemberNotificationRepository.java b/src/main/java/clap/server/adapter/outbound/persistense/repository/member/MemberNotificationRepository.java deleted file mode 100644 index 15223788..00000000 --- a/src/main/java/clap/server/adapter/outbound/persistense/repository/member/MemberNotificationRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package clap.server.adapter.outbound.persistense.repository.member; - -import clap.server.adapter.outbound.persistense.entity.member.MemberNotificationEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface MemberNotificationRepository extends JpaRepository { -} \ No newline at end of file diff --git a/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationChannelRepository.java b/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationChannelRepository.java deleted file mode 100644 index bf2e39bc..00000000 --- a/src/main/java/clap/server/adapter/outbound/persistense/repository/notification/NotificationChannelRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package clap.server.adapter.outbound.persistense.repository.notification; - -import clap.server.adapter.outbound.persistense.entity.notification.NotificationChannelEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface NotificationChannelRepository extends JpaRepository { -} \ No newline at end of file diff --git a/src/main/java/clap/server/application/mapper/MemberMapper.java b/src/main/java/clap/server/application/mapper/MemberMapper.java index a314b944..804a339a 100644 --- a/src/main/java/clap/server/application/mapper/MemberMapper.java +++ b/src/main/java/clap/server/application/mapper/MemberMapper.java @@ -1,6 +1,7 @@ package clap.server.application.mapper; +import clap.server.adapter.inbound.web.dto.member.MemberDetailInfoResponse; import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; import clap.server.domain.model.member.Member; @@ -18,4 +19,26 @@ public static MemberProfileResponse toMemberProfileResponse(Member member) { member.getMemberInfo().getRole() ); } + + public static MemberDetailInfoResponse toMemberDetailInfoResponse(Member member) { + return new MemberDetailInfoResponse( + member.getImageUrl(), + member.getMemberInfo().getName(), + member.getMemberInfo().getNickname(), + member.getImageUrl(), + member.isReviewer(), + member.getMemberInfo().getRole(), + member.getMemberInfo().getDepartment().getName(), + member.getMemberInfo().getDepartmentRole(), + toNotificationSettingInfoResponse(member) + ); + } + + public static MemberDetailInfoResponse.NotificationSettingInfoResponse toNotificationSettingInfoResponse(Member member) { + return new MemberDetailInfoResponse.NotificationSettingInfoResponse( + member.getAgitNotificationEnabled(), + member.getEmailNotificationEnabled(), + member.getKakaoWorkNotificationEnabled() + ); + } } \ No newline at end of file diff --git a/src/main/java/clap/server/application/port/inbound/admin/ManageMemberUsecase.java b/src/main/java/clap/server/application/port/inbound/admin/ManageMemberUsecase.java deleted file mode 100644 index 46050ae3..00000000 --- a/src/main/java/clap/server/application/port/inbound/admin/ManageMemberUsecase.java +++ /dev/null @@ -1,7 +0,0 @@ -package clap.server.application.port.inbound.admin; - -import clap.server.adapter.inbound.web.dto.admin.UpdateMemberInfoRequest; - -public interface ManageMemberUsecase { - void updateMemberInfo(Long memberId, UpdateMemberInfoRequest request); -} diff --git a/src/main/java/clap/server/application/port/inbound/admin/UpdateMemberUsecase.java b/src/main/java/clap/server/application/port/inbound/admin/UpdateMemberUsecase.java new file mode 100644 index 00000000..ea4c6c36 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/admin/UpdateMemberUsecase.java @@ -0,0 +1,7 @@ +package clap.server.application.port.inbound.admin; + +import clap.server.adapter.inbound.web.dto.admin.UpdateMemberRequest; + +public interface UpdateMemberUsecase { + void updateMemberInfo(Long adminId, Long memberId, UpdateMemberRequest request); +} diff --git a/src/main/java/clap/server/application/port/inbound/auth/AuthUsecase.java b/src/main/java/clap/server/application/port/inbound/auth/LoginUsecase.java similarity index 67% rename from src/main/java/clap/server/application/port/inbound/auth/AuthUsecase.java rename to src/main/java/clap/server/application/port/inbound/auth/LoginUsecase.java index 85307841..74fc0db0 100644 --- a/src/main/java/clap/server/application/port/inbound/auth/AuthUsecase.java +++ b/src/main/java/clap/server/application/port/inbound/auth/LoginUsecase.java @@ -2,7 +2,6 @@ import clap.server.adapter.inbound.web.dto.auth.LoginResponse; -public interface AuthUsecase { +public interface LoginUsecase { LoginResponse login(String nickname, String password, String sessionId, String clientIp); - void logout(Long memberId, String accessToken, String refreshToken); } diff --git a/src/main/java/clap/server/application/port/inbound/auth/LogoutUsecase.java b/src/main/java/clap/server/application/port/inbound/auth/LogoutUsecase.java new file mode 100644 index 00000000..f19a30c9 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/auth/LogoutUsecase.java @@ -0,0 +1,5 @@ +package clap.server.application.port.inbound.auth; + +public interface LogoutUsecase { + void logout(Long memberId, String accessToken, String refreshToken); +} diff --git a/src/main/java/clap/server/application/port/inbound/member/MemberDetailInfoUsecase.java b/src/main/java/clap/server/application/port/inbound/member/MemberDetailInfoUsecase.java new file mode 100644 index 00000000..a87a094e --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/member/MemberDetailInfoUsecase.java @@ -0,0 +1,7 @@ +package clap.server.application.port.inbound.member; + +import clap.server.adapter.inbound.web.dto.member.MemberDetailInfoResponse; + +public interface MemberDetailInfoUsecase { + MemberDetailInfoResponse getMemberInfo(Long memberId); +} diff --git a/src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java b/src/main/java/clap/server/application/port/inbound/member/MemberProfileUsecase.java similarity index 82% rename from src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java rename to src/main/java/clap/server/application/port/inbound/member/MemberProfileUsecase.java index feef14f0..e05acebd 100644 --- a/src/main/java/clap/server/application/port/inbound/member/MemberInfoUsecase.java +++ b/src/main/java/clap/server/application/port/inbound/member/MemberProfileUsecase.java @@ -2,6 +2,6 @@ import clap.server.adapter.inbound.web.dto.member.MemberProfileResponse; -public interface MemberInfoUsecase { +public interface MemberProfileUsecase { MemberProfileResponse getMemberProfile(Long memberId); } diff --git a/src/main/java/clap/server/application/port/inbound/member/ResetInitialPasswordUsecase.java b/src/main/java/clap/server/application/port/inbound/member/ResetInitialPasswordUsecase.java new file mode 100644 index 00000000..87f89652 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/member/ResetInitialPasswordUsecase.java @@ -0,0 +1,5 @@ +package clap.server.application.port.inbound.member; + +public interface ResetInitialPasswordUsecase { + void resetPasswordAndActivateMember(Long memberId, String password); +} diff --git a/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java b/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java index 1dc3ebb2..837c877d 100644 --- a/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java +++ b/src/main/java/clap/server/application/port/inbound/member/ResetPasswordUsecase.java @@ -2,5 +2,4 @@ public interface ResetPasswordUsecase { void resetPassword(Long memberId, String password); - void resetPasswordAndActivateMember(Long memberId, String password); } diff --git a/src/main/java/clap/server/application/port/inbound/member/UpdateMemberInfoUsecase.java b/src/main/java/clap/server/application/port/inbound/member/UpdateMemberInfoUsecase.java new file mode 100644 index 00000000..52aaff2a --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/member/UpdateMemberInfoUsecase.java @@ -0,0 +1,10 @@ +package clap.server.application.port.inbound.member; + +import clap.server.adapter.inbound.web.dto.member.UpdateMemberInfoRequest; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +public interface UpdateMemberInfoUsecase { + void updateMemberInfo(Long memberId, UpdateMemberInfoRequest request, MultipartFile profileImage) throws IOException; +} diff --git a/src/main/java/clap/server/application/service/admin/ManageMemberService.java b/src/main/java/clap/server/application/service/admin/UpdateMemberService.java similarity index 73% rename from src/main/java/clap/server/application/service/admin/ManageMemberService.java rename to src/main/java/clap/server/application/service/admin/UpdateMemberService.java index f30b5962..862a24d5 100644 --- a/src/main/java/clap/server/application/service/admin/ManageMemberService.java +++ b/src/main/java/clap/server/application/service/admin/UpdateMemberService.java @@ -1,7 +1,7 @@ package clap.server.application.service.admin; -import clap.server.adapter.inbound.web.dto.admin.UpdateMemberInfoRequest; -import clap.server.application.port.inbound.admin.ManageMemberUsecase; +import clap.server.adapter.inbound.web.dto.admin.UpdateMemberRequest; +import clap.server.application.port.inbound.admin.UpdateMemberUsecase; import clap.server.application.port.inbound.domain.MemberService; import clap.server.application.port.outbound.member.CommandMemberPort; import clap.server.application.port.outbound.member.LoadDepartmentPort; @@ -16,18 +16,19 @@ @ApplicationService @RequiredArgsConstructor @Transactional -class ManageMemberService implements ManageMemberUsecase { +class UpdateMemberService implements UpdateMemberUsecase { private final MemberService memberService; private final CommandMemberPort commandMemberPort; private final LoadDepartmentPort loadDepartmentPort; @Override - public void updateMemberInfo(Long memberId, UpdateMemberInfoRequest request) { + public void updateMemberInfo(Long adminId, Long memberId, UpdateMemberRequest request) { Member member = memberService.findActiveMember(memberId); - Department department = loadDepartmentPort.findById(request.departmentId()).orElseThrow(() -> new ApplicationException(DepartmentErrorCode.DEPARTMENT_NOT_FOUND)); + Department department = loadDepartmentPort.findById(request.departmentId()).orElseThrow(() -> + new ApplicationException(DepartmentErrorCode.DEPARTMENT_NOT_FOUND)); //TODO: 인프라팀만 담당자가 될 수 있도록 수정해야함 - member.getMemberInfo().updateMemberInfo( + member.getMemberInfo().updateMemberInfoByAdmin( request.name(), request.email(), request.isReviewer(), department, request.role(), request.departmentRole()); commandMemberPort.save(member); diff --git a/src/main/java/clap/server/application/service/auth/AuthService.java b/src/main/java/clap/server/application/service/auth/AuthService.java index 9fb7487f..aafac610 100644 --- a/src/main/java/clap/server/application/service/auth/AuthService.java +++ b/src/main/java/clap/server/application/service/auth/AuthService.java @@ -3,7 +3,8 @@ import clap.server.adapter.inbound.web.dto.auth.LoginResponse; import clap.server.adapter.outbound.persistense.entity.member.constant.MemberStatus; import clap.server.application.mapper.response.AuthResponseMapper; -import clap.server.application.port.inbound.auth.AuthUsecase; +import clap.server.application.port.inbound.auth.LoginUsecase; +import clap.server.application.port.inbound.auth.LogoutUsecase; import clap.server.application.port.outbound.auth.ForbiddenTokenPort; import clap.server.application.port.outbound.member.LoadMemberPort; import clap.server.common.annotation.architecture.ApplicationService; @@ -14,7 +15,6 @@ import clap.server.exception.AuthException; import clap.server.exception.code.AuthErrorCode; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; @@ -24,7 +24,7 @@ @ApplicationService @RequiredArgsConstructor @Transactional -class AuthService implements AuthUsecase { +class AuthService implements LoginUsecase, LogoutUsecase { private final LoadMemberPort loadMemberPort; private final ManageTokenService manageTokenService; private final PasswordEncoder passwordEncoder; diff --git a/src/main/java/clap/server/application/service/member/MemberInfoService.java b/src/main/java/clap/server/application/service/member/MemberInfoService.java index 60ec23bd..d4e993d8 100644 --- a/src/main/java/clap/server/application/service/member/MemberInfoService.java +++ b/src/main/java/clap/server/application/service/member/MemberInfoService.java @@ -1,24 +1,22 @@ package clap.server.application.service.member; +import clap.server.adapter.inbound.web.dto.member.MemberDetailInfoResponse; 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.application.port.inbound.member.MemberDetailInfoUsecase; +import clap.server.application.port.inbound.member.MemberProfileUsecase; 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.toMemberDetailInfoResponse; import static clap.server.application.mapper.MemberMapper.toMemberProfileResponse; @ApplicationService @RequiredArgsConstructor -class MemberInfoService implements MemberInfoUsecase { +class MemberInfoService implements MemberProfileUsecase , MemberDetailInfoUsecase { private final MemberService memberService; - private final LoadMemberPort loadMemberPort; - private final CommandMemberPort commandMemberPort; - @Override @Transactional(readOnly = true) @@ -26,4 +24,11 @@ public MemberProfileResponse getMemberProfile(Long memberId) { Member member = memberService.findActiveMember(memberId); return toMemberProfileResponse(member); } + + @Override + @Transactional(readOnly = true) + public MemberDetailInfoResponse getMemberInfo(Long memberId) { + Member member = memberService.findActiveMember(memberId); + return toMemberDetailInfoResponse(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 60752411..4baad9b5 100644 --- a/src/main/java/clap/server/application/service/member/ResetPasswordService.java +++ b/src/main/java/clap/server/application/service/member/ResetPasswordService.java @@ -1,7 +1,8 @@ package clap.server.application.service.member; -import clap.server.application.port.inbound.member.ResetPasswordUsecase; import clap.server.application.port.inbound.domain.MemberService; +import clap.server.application.port.inbound.member.ResetInitialPasswordUsecase; +import clap.server.application.port.inbound.member.ResetPasswordUsecase; import clap.server.application.port.outbound.member.CommandMemberPort; import clap.server.common.annotation.architecture.ApplicationService; import clap.server.domain.model.member.Member; @@ -14,7 +15,7 @@ @RequiredArgsConstructor @Transactional @Slf4j -class ResetPasswordService implements ResetPasswordUsecase { +class ResetPasswordService implements ResetPasswordUsecase, ResetInitialPasswordUsecase { private final MemberService memberService; private final PasswordEncoder passwordEncoder; private final CommandMemberPort commandMemberPort; diff --git a/src/main/java/clap/server/application/service/member/UpdateMemberInfoService.java b/src/main/java/clap/server/application/service/member/UpdateMemberInfoService.java new file mode 100644 index 00000000..3c6271fd --- /dev/null +++ b/src/main/java/clap/server/application/service/member/UpdateMemberInfoService.java @@ -0,0 +1,42 @@ +package clap.server.application.service.member; + +import clap.server.adapter.inbound.web.dto.member.UpdateMemberInfoRequest; +import clap.server.application.port.inbound.domain.MemberService; +import clap.server.application.port.inbound.member.UpdateMemberInfoUsecase; +import clap.server.application.port.outbound.member.CommandMemberPort; +import clap.server.application.port.outbound.s3.S3UploadPort; +import clap.server.common.annotation.architecture.ApplicationService; +import clap.server.common.constants.FilePathConstants; +import clap.server.common.utils.FileUtils; +import clap.server.domain.model.member.Member; +import clap.server.exception.ApplicationException; +import clap.server.exception.code.AttachmentErrorcode; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +@ApplicationService +@RequiredArgsConstructor +@Transactional +class UpdateMemberInfoService implements UpdateMemberInfoUsecase { + private final MemberService memberService; + private final S3UploadPort s3UploadPort; + private final CommandMemberPort commandMemberPort; + + @Override + public void updateMemberInfo(Long memberId, UpdateMemberInfoRequest request, MultipartFile profileImage) throws IOException { + Member member = memberService.findActiveMember(memberId); + String profileImageUrl = null; + if (!profileImage.isEmpty()){ + if(!FileUtils.validImageFile(profileImage.getInputStream())) { + throw new ApplicationException(AttachmentErrorcode.UNSUPPORTED_FILE_TYPE); + } + profileImageUrl = s3UploadPort.uploadSingleFile(FilePathConstants.MEMBER_IMAGE, profileImage); + } + member.updateMemberInfo(request.name(), request.agitNotification(), request.emailNotification(), + request.kakaoWorkNotification(), profileImageUrl); + commandMemberPort.save(member); + } +} diff --git a/src/main/java/clap/server/application/service/task/UpdateTaskService.java b/src/main/java/clap/server/application/service/task/UpdateTaskService.java index 3da416ff..214f9348 100644 --- a/src/main/java/clap/server/application/service/task/UpdateTaskService.java +++ b/src/main/java/clap/server/application/service/task/UpdateTaskService.java @@ -1,7 +1,6 @@ package clap.server.application.service.task; import clap.server.adapter.inbound.web.dto.task.*; -import clap.server.adapter.outbound.infrastructure.s3.S3UploadAdapter; import clap.server.adapter.outbound.persistense.entity.task.constant.TaskHistoryType; import clap.server.application.mapper.AttachmentMapper; import clap.server.application.mapper.TaskMapper; @@ -13,6 +12,7 @@ import clap.server.application.port.inbound.task.UpdateTaskProcessorUsecase; import clap.server.application.port.inbound.task.UpdateTaskStatusUsecase; import clap.server.application.port.inbound.task.UpdateTaskUsecase; +import clap.server.application.port.outbound.s3.S3UploadPort; import clap.server.application.port.outbound.task.CommandAttachmentPort; import clap.server.application.port.outbound.task.CommandTaskPort; import clap.server.application.port.outbound.task.LoadAttachmentPort; @@ -44,8 +44,8 @@ public class UpdateTaskService implements UpdateTaskUsecase, UpdateTaskStatusUse private final LoadAttachmentPort loadAttachmentPort; private final LabelService labelService; private final CommandAttachmentPort commandAttachmentPort; + private final S3UploadPort s3UploadPort; private final CommandTaskHistoryPort commandTaskHistoryPort; - private final S3UploadAdapter s3UploadAdapter; @Override @Transactional @@ -104,7 +104,7 @@ private void updateAttachments(List attachmentIdsToDelete, List attachmentsToDelete = validateAndGetAttachments(attachmentIdsToDelete, task); attachmentsToDelete.forEach(Attachment::softDelete); - List fileUrls = s3UploadAdapter.uploadFiles(FilePathConstants.TASK_IMAGE, files); + List fileUrls = s3UploadPort.uploadFiles(FilePathConstants.TASK_IMAGE, files); List attachments = AttachmentMapper.toTaskAttachments(task, files, fileUrls); commandAttachmentPort.saveAll(attachments); } diff --git a/src/main/java/clap/server/common/constants/FilePathConstants.java b/src/main/java/clap/server/common/constants/FilePathConstants.java index 92393f90..0b13ec57 100644 --- a/src/main/java/clap/server/common/constants/FilePathConstants.java +++ b/src/main/java/clap/server/common/constants/FilePathConstants.java @@ -8,7 +8,7 @@ public enum FilePathConstants { TASK_IMAGE("task/image"), TASK_DOCUMENT("task/docs"), - MEMBER_IMAGE("member/image"), + MEMBER_IMAGE("member"), ; private final String path; diff --git a/src/main/java/clap/server/common/utils/FileUtils.java b/src/main/java/clap/server/common/utils/FileUtils.java new file mode 100644 index 00000000..5a5b7d97 --- /dev/null +++ b/src/main/java/clap/server/common/utils/FileUtils.java @@ -0,0 +1,29 @@ +package clap.server.common.utils; + +import org.apache.tika.Tika; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +public class FileUtils { + private FileUtils() { + throw new IllegalStateException("Utility class"); + } + + private static final Tika tika = new Tika(); + private static final List VALID_IMAGE_TYPES = Arrays.asList( + "image/jpeg", "image/pjpeg", "image/png", "image/gif", "image/bmp", "image/x-windows-bmp" + ); + + public static boolean validImageFile(InputStream inputStream) { + try { + String mimeType = tika.detect(inputStream); + + return VALID_IMAGE_TYPES.contains(mimeType.toLowerCase()); + } catch (IOException e) { + return false; + } + } +} diff --git a/src/main/java/clap/server/domain/model/member/Member.java b/src/main/java/clap/server/domain/model/member/Member.java index 3ee1d3be..6ffcf101 100644 --- a/src/main/java/clap/server/domain/model/member/Member.java +++ b/src/main/java/clap/server/domain/model/member/Member.java @@ -13,16 +13,20 @@ public class Member extends BaseTime { private Long memberId; private MemberInfo memberInfo; private Member admin; - private Boolean notificationEnabled; + private Boolean kakaoWorkNotificationEnabled; + private Boolean agitNotificationEnabled; + private Boolean emailNotificationEnabled; private String imageUrl; private MemberStatus status; private String password; @Builder - public Member(MemberInfo memberInfo, Boolean notificationEnabled, Member admin, String imageUrl, - MemberStatus status, String password) { + public Member(MemberInfo memberInfo, Boolean agitNotificationEnabled, Boolean emailNotificationEnabled, Boolean kakaoWorkNotificationEnabled, + Member admin, String imageUrl, MemberStatus status, String password) { this.memberInfo = memberInfo; - this.notificationEnabled = notificationEnabled; + this.agitNotificationEnabled = agitNotificationEnabled; + this.emailNotificationEnabled = emailNotificationEnabled; + this.kakaoWorkNotificationEnabled = kakaoWorkNotificationEnabled; this.admin = admin; this.imageUrl = imageUrl; this.status = status; @@ -30,14 +34,16 @@ public Member(MemberInfo memberInfo, Boolean notificationEnabled, Member admin, } public static Member createMember(Member admin, MemberInfo memberInfo) { - return Member.builder() - .memberInfo(memberInfo) - .notificationEnabled(null) - .admin(admin) - .imageUrl(null) - .status(MemberStatus.PENDING) - .password(null) - .build(); + return Member.builder() + .memberInfo(memberInfo) + .agitNotificationEnabled(null) + .emailNotificationEnabled(null) + .kakaoWorkNotificationEnabled(null) + .admin(admin) + .imageUrl(null) + .status(MemberStatus.PENDING) + .password(null) + .build(); } public void resetPassword(String newEncodedPassword) { @@ -47,6 +53,9 @@ public void resetPassword(String newEncodedPassword) { public void resetPasswordAndActivateMember(String newEncodedPassword) { this.password = newEncodedPassword; this.status = MemberStatus.ACTIVE; + this.agitNotificationEnabled = true; + this.emailNotificationEnabled = true; + this.kakaoWorkNotificationEnabled = true; } public String getNickname() { @@ -57,6 +66,16 @@ public boolean isReviewer() { return this.memberInfo != null && this.memberInfo.isReviewer(); } + public void updateMemberInfo(String name, Boolean agitNotificationEnabled, Boolean emailNotificationEnabled, Boolean kakaoWorkNotificationEnabled, String imageUrl) { + this.memberInfo.updateName(name); + this.agitNotificationEnabled = agitNotificationEnabled; + this.emailNotificationEnabled = emailNotificationEnabled; + this.kakaoWorkNotificationEnabled = kakaoWorkNotificationEnabled; + if (imageUrl != null) { + this.imageUrl = imageUrl; + } + } + public void setStatusDeleted() { this.status = MemberStatus.DELETED; } diff --git a/src/main/java/clap/server/domain/model/member/MemberInfo.java b/src/main/java/clap/server/domain/model/member/MemberInfo.java index 11e3bf2f..9f4d3bd4 100644 --- a/src/main/java/clap/server/domain/model/member/MemberInfo.java +++ b/src/main/java/clap/server/domain/model/member/MemberInfo.java @@ -47,8 +47,8 @@ public static MemberInfo toMemberInfo(String name, String email, String nickname .build(); } - public void updateMemberInfo(String name, String email, boolean isReviewer, - Department department, MemberRole role, String departmentRole) { + public void updateMemberInfoByAdmin(String name, String email, boolean isReviewer, + Department department, MemberRole role, String departmentRole) { assertReviewerIsManager(isReviewer, role); this.name = name; this.email = email; @@ -58,6 +58,10 @@ public void updateMemberInfo(String name, String email, boolean isReviewer, this.departmentRole = departmentRole; } + public void updateName(String name) { + this.name = name; + } + public static void assertReviewerIsManager(boolean isReviewer, MemberRole role) { if (isReviewer) { if (role != MemberRole.ROLE_MANAGER) { diff --git a/src/main/java/clap/server/domain/model/member/MemberNotification.java b/src/main/java/clap/server/domain/model/member/MemberNotification.java deleted file mode 100644 index 2e41018c..00000000 --- a/src/main/java/clap/server/domain/model/member/MemberNotification.java +++ /dev/null @@ -1,18 +0,0 @@ -package clap.server.domain.model.member; - -import clap.server.domain.model.common.BaseTime; -import clap.server.domain.model.notification.NotificationChannel; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Getter -@SuperBuilder -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class MemberNotification extends BaseTime { - private Long memberNotificationId; - private Boolean isEnabled; - private Member member; - private NotificationChannel notificationChannel; - } diff --git a/src/main/java/clap/server/exception/code/S3Errorcode.java b/src/main/java/clap/server/exception/code/AttachmentErrorcode.java similarity index 60% rename from src/main/java/clap/server/exception/code/S3Errorcode.java rename to src/main/java/clap/server/exception/code/AttachmentErrorcode.java index 30fc1cf6..8992f41c 100644 --- a/src/main/java/clap/server/exception/code/S3Errorcode.java +++ b/src/main/java/clap/server/exception/code/AttachmentErrorcode.java @@ -6,8 +6,9 @@ @Getter @RequiredArgsConstructor -public enum S3Errorcode implements BaseErrorCode { - FILE_UPLOAD_REQUEST_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "TASK_004", "파일 업로드에 실패하였습니다."); +public enum AttachmentErrorcode implements BaseErrorCode { + FILE_UPLOAD_REQUEST_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FILE_001", "파일 업로드에 실패하였습니다."), + UNSUPPORTED_FILE_TYPE(HttpStatus.BAD_REQUEST, "FILE_002", "이미지가 아닌 파일 유형입니다."),; private final HttpStatus httpStatus; private final String customCode; diff --git a/src/main/java/clap/server/exception/code/MemberErrorCode.java b/src/main/java/clap/server/exception/code/MemberErrorCode.java index dae6b6ef..9e41bfda 100644 --- a/src/main/java/clap/server/exception/code/MemberErrorCode.java +++ b/src/main/java/clap/server/exception/code/MemberErrorCode.java @@ -10,7 +10,7 @@ public enum MemberErrorCode implements BaseErrorCode { MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER_001", "회원을 찾을 수 없습니다."), ACTIVE_MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER_002", "활성화 회원을 찾을 수 없습니다."), NOT_A_REVIEWER(HttpStatus.FORBIDDEN, "MEMBER_003", "리뷰어 권한이 없습니다."), - MEMBER_REGISTER_FAILED(HttpStatus.BAD_REQUEST, "MEMBER_004", "회원 등록에 실패하였습니다"); + MEMBER_REGISTER_FAILED(HttpStatus.BAD_REQUEST, "MEMBER_004", "회원 등록에 실패하였습니다"), ; private final HttpStatus httpStatus;