diff --git a/src/main/java/kdt/web_ide/boards/controller/BoardController.java b/src/main/java/kdt/web_ide/boards/controller/BoardController.java index 7f956fe..137874b 100644 --- a/src/main/java/kdt/web_ide/boards/controller/BoardController.java +++ b/src/main/java/kdt/web_ide/boards/controller/BoardController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import kdt.web_ide.boards.dto.request.BoardSaveRequesetDto; import kdt.web_ide.boards.dto.request.BoardUpdateRequestDto; +import kdt.web_ide.boards.dto.request.BoardUserInviteRequestDto; import kdt.web_ide.boards.dto.response.BoardResponseDto; import kdt.web_ide.boards.dto.response.BoardUserResponseDto; import kdt.web_ide.boards.service.BoardService; @@ -57,17 +58,17 @@ public ResponseEntity deleteBoard( return ResponseEntity.status(HttpStatus.OK).body("게시판이 삭제되었습니다."); } - // // 게시판 인원 초대 - // @Operation(summary = "게시판 멤버 초대 API", description = "이메일로 멤버를 초대합니다. 리더만 초대 가능합니다.") - // @PostMapping("/{boardId}/invite") - // public ResponseEntity inviteMember( - // @PathVariable Long boardId, - // @RequestBody @Valid BoardUserInviteRequestDto requestDto, - // @AuthenticationPrincipal CustomUserDetails userDetails) { - // BoardUserResponseDto invitedUser = - // boardService.inviteMember(requestDto, boardId, userDetails.getMember()); - // return ResponseEntity.ok(invitedUser); - // } + @Operation(summary = "게시판 멤버 초대 API", description = "카카오 ID로 멤버를 초대합니다. 리더만 초대 가능합니다.") + @PostMapping("/{boardId}/invite") + public ResponseEntity inviteMember( + @PathVariable Long boardId, + @RequestBody @Valid BoardUserInviteRequestDto requestDto, + @AuthenticationPrincipal CustomUserDetails userDetails) { + + BoardUserResponseDto invitedUser = + boardService.inviteMember(requestDto, boardId, userDetails.getMember()); + return ResponseEntity.ok(invitedUser); + } // 게시판 인원 조회 @Operation(summary = "게시판 인원 조회 API", description = "해당 게시판의 모든 멤버를 조회합니다.") diff --git a/src/main/java/kdt/web_ide/boards/dto/request/BoardUserInviteRequestDto.java b/src/main/java/kdt/web_ide/boards/dto/request/BoardUserInviteRequestDto.java index 868b3db..8b0defa 100644 --- a/src/main/java/kdt/web_ide/boards/dto/request/BoardUserInviteRequestDto.java +++ b/src/main/java/kdt/web_ide/boards/dto/request/BoardUserInviteRequestDto.java @@ -9,7 +9,7 @@ @Getter @NoArgsConstructor public class BoardUserInviteRequestDto { - private String loginId; + private Long kakaoId; public BoardUser toEntity(Board board, Member member) { return BoardUser.builder().board(board).isLeader(false).member(member).build(); diff --git a/src/main/java/kdt/web_ide/boards/service/BoardService.java b/src/main/java/kdt/web_ide/boards/service/BoardService.java index 31e6360..edf42ed 100644 --- a/src/main/java/kdt/web_ide/boards/service/BoardService.java +++ b/src/main/java/kdt/web_ide/boards/service/BoardService.java @@ -9,6 +9,7 @@ import kdt.web_ide.boards.dto.request.BoardSaveRequesetDto; import kdt.web_ide.boards.dto.request.BoardUpdateRequestDto; +import kdt.web_ide.boards.dto.request.BoardUserInviteRequestDto; import kdt.web_ide.boards.dto.response.BoardResponseDto; import kdt.web_ide.boards.dto.response.BoardUserResponseDto; import kdt.web_ide.boards.entity.Board; @@ -72,27 +73,40 @@ public void deleteBoard(Long boardId, Member member) { boardRepository.delete(board); } - // 게시판 인원 초대 - // @Transactional - // public BoardUserResponseDto inviteMember( - // BoardUserInviteRequestDto requestDto, Long boardId, Member currentMember) { - // if (requestDto.getLoginId() == null || requestDto.getLoginId().isEmpty()) { - // throw new CustomException(ErrorCode.INVALID_LOGINID); - // } - // // 존재하는 게시판인지 확인 - // Board thisBoard = - // boardRepository - // .findById(boardId) - // .orElseThrow(() -> new CustomException(ErrorCode.BOARD_NOT_FOUND)); - // // 존재하는 멤버인지 확인 - // Member member = - // memberRepository - // .findByLoginId(requestDto.getLoginId()) - // .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); - // BoardUser newUser = requestDto.toEntity(thisBoard, member); - // boardUserRepository.save(newUser); - // return new BoardUserResponseDto(newUser); - // } + @Transactional + public BoardUserResponseDto inviteMember( + BoardUserInviteRequestDto requestDto, Long boardId, Member currentMember) { + + if (requestDto.getKakaoId() == null) { + throw new CustomException(ErrorCode.INVALID_KAKAO_ID); + } + + Board board = + boardRepository + .findById(boardId) + .orElseThrow(() -> new CustomException(ErrorCode.BOARD_NOT_FOUND)); + + boardUserRepository + .findByMemberAndBoardAndIsLeaderTrue(currentMember, board) + .orElseThrow(() -> new CustomException(ErrorCode.NO_PERMISSION)); + + Member memberToInvite = + memberRepository + .findByKakaoId(requestDto.getKakaoId()) + .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + + boardUserRepository + .findByMemberAndBoard(memberToInvite, board) + .ifPresent( + member -> { + throw new CustomException(ErrorCode.ALREADY_IN_BOARD); + }); + + BoardUser newUser = requestDto.toEntity(board, memberToInvite); + boardUserRepository.save(newUser); + + return new BoardUserResponseDto(newUser); + } // 게시판 인원 조회 @Transactional diff --git a/src/main/java/kdt/web_ide/common/exception/ErrorCode.java b/src/main/java/kdt/web_ide/common/exception/ErrorCode.java index 59974ec..32309d6 100644 --- a/src/main/java/kdt/web_ide/common/exception/ErrorCode.java +++ b/src/main/java/kdt/web_ide/common/exception/ErrorCode.java @@ -21,6 +21,7 @@ public enum ErrorCode { INVALID_IMAGE(HttpStatus.BAD_REQUEST, "ACCOUNT-010", "유효하지 않은 이미지입니다."), INVALID_NICKNAME(HttpStatus.BAD_REQUEST, "ACCOUNT-011", "유효하지 않은 이미지입니다."), KAKAO_REFRESH_TOKEN_NOT_FOUND(HttpStatus.UNAUTHORIZED, "ACCOUNT-0012", "유효하지 않은 토큰입니다."), + INVALID_KAKAO_ID(HttpStatus.BAD_REQUEST, "ACCOUNT-013", "유효하지 않은 카카오 아이디입니다."), // 채팅방 CHATROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "ACCOUNT-008", "채팅방을 찾을 수 없습니다."), @@ -31,6 +32,7 @@ public enum ErrorCode { BOARD_NOT_FOUND(HttpStatus.NOT_FOUND, "BOARD-003", "존재하지 않는 게시판입니다."), MEMBER_NOT_IN_BOARD(HttpStatus.NOT_FOUND, "BOARD-004", "게시판에 존재하지 않는 멤버입니다."), INVALID_TITLE(HttpStatus.BAD_REQUEST, "BOARD-005", "제목 입력은 필수입니다."), + ALREADY_IN_BOARD(HttpStatus.BAD_REQUEST, "BOARD-006", "이미 게시판에 존재합니다."), // S3 S3_UPLOAD_ERROR(HttpStatus.BAD_REQUEST, "S3-001", "S3 업로드 실패"), diff --git a/src/main/java/kdt/web_ide/members/controller/MemberController.java b/src/main/java/kdt/web_ide/members/controller/MemberController.java index a189af6..2022130 100644 --- a/src/main/java/kdt/web_ide/members/controller/MemberController.java +++ b/src/main/java/kdt/web_ide/members/controller/MemberController.java @@ -85,6 +85,7 @@ public ResponseEntity login(@RequestBody KakaoLoginParams params) { // 회원 정보 조회 @GetMapping("/profile") + @Operation(summary = "회원 정보 조회 API", description = "회원 정보 조회") public ResponseEntity getMember(@AuthenticationPrincipal CustomUserDetails userDetails) { MemberResponse memberResponse = memberService.getMember(userDetails.getMember()); return ResponseEntity.status(HttpStatus.OK).body(memberResponse); diff --git a/src/main/java/kdt/web_ide/members/dto/response/MemberResponse.java b/src/main/java/kdt/web_ide/members/dto/response/MemberResponse.java index b1624c4..a728620 100644 --- a/src/main/java/kdt/web_ide/members/dto/response/MemberResponse.java +++ b/src/main/java/kdt/web_ide/members/dto/response/MemberResponse.java @@ -11,6 +11,7 @@ public MemberResponse(Member member) { this.memberId = member.getMemberId(); this.nickName = member.getNickName(); this.profileImage = member.getProfileImage(); + this.kakaoId = member.getKakaoId(); } private final Long memberId; @@ -19,6 +20,8 @@ public MemberResponse(Member member) { private final String profileImage; + private final Long kakaoId; + public static MemberResponse of(Member member) { return new MemberResponse(member); }