Skip to content

Commit

Permalink
[Feat]: 공유 수락 API 구현 (#43)
Browse files Browse the repository at this point in the history
* [Feat]: 공유 수락 API 구현

공유 수락 API 구현

Related to: #40

* [Update]: 공유 요청 및 수락 예외처리 추가

5명 초과 시 예외처리 추가

Related to: #40

* [Update]: UserServiceUtil 적용

UserServiceUtil 적용

Related to: #40

* [Update]: RequestBody로 변경

RequestParam에서 RequestBody로 변경

Related to: #40
  • Loading branch information
onpyeong authored Jan 13, 2024
1 parent 4837079 commit e1a92c3
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 56 deletions.
2 changes: 2 additions & 0 deletions src/main/java/io/sobok/SobokSobok/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public enum ErrorCode {
INVALID_REQUEST_BODY(HttpStatus.BAD_REQUEST, "잘못된 Request body입니다."),
BAD_REQUEST_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 형식의 요청입니다."),
FILE_SAVE_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, "파일 생성에 실패했습니다."),
FORBIDDEN_EXCEPTION(HttpStatus.FORBIDDEN, "접근 권한이 없습니다."),

// auth
UNREGISTERED_USER(HttpStatus.NOT_FOUND, "등록되지 않은 사용자입니다."),
Expand All @@ -35,6 +36,7 @@ public enum ErrorCode {
// friend
INVALID_SELF_ADD_FRIEND(HttpStatus.BAD_REQUEST, "자신에게 캘린더 공유 요청을 할 수 없습니다."),
ALREADY_FRIEND(HttpStatus.CONFLICT, "이미 캘린더 공유 요청이 되었습니다."),
EXCEEDED_FRIEND_COUNT(HttpStatus.CONFLICT, "친구 수가 초과됐습니다."),
NOT_FRIEND(HttpStatus.FORBIDDEN, "친구 관계가 아닙니다."),

// notice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum SuccessCode {

// friend
ADD_FRIEND_SUCCESS(HttpStatus.OK, "공유 요청에 성공했습니다."),
HANDLE_FRIEND_REQUEST_SUCCESS(HttpStatus.OK, "공유 응답에 성공했습니다."),

// notice
GET_NOTICE_LIST_SUCCESS(HttpStatus.OK, "알림 리스트 조회에 성공했습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package io.sobok.SobokSobok.friend.application;

import io.sobok.SobokSobok.auth.application.util.UserServiceUtil;
import io.sobok.SobokSobok.auth.domain.User;
import io.sobok.SobokSobok.auth.infrastructure.UserRepository;
import io.sobok.SobokSobok.exception.ErrorCode;
import io.sobok.SobokSobok.exception.model.BadRequestException;
import io.sobok.SobokSobok.exception.model.ConflictException;
import io.sobok.SobokSobok.exception.model.NotFoundException;
import io.sobok.SobokSobok.exception.model.ForbiddenException;
import io.sobok.SobokSobok.friend.domain.Friend;
import io.sobok.SobokSobok.friend.domain.SendFriend;
import io.sobok.SobokSobok.friend.infrastructure.FriendQueryRepository;
import io.sobok.SobokSobok.friend.infrastructure.FriendRepository;
import io.sobok.SobokSobok.friend.infrastructure.SendFriendRepository;
import io.sobok.SobokSobok.friend.ui.dto.AddFriendRequest;
import io.sobok.SobokSobok.friend.ui.dto.AddFriendResponse;
import io.sobok.SobokSobok.friend.ui.dto.HandleFriendRequest;
import io.sobok.SobokSobok.friend.ui.dto.HandleFriendRequestResponse;
import io.sobok.SobokSobok.notice.domain.Notice;
import io.sobok.SobokSobok.notice.domain.NoticeStatus;
import io.sobok.SobokSobok.notice.domain.NoticeType;
import io.sobok.SobokSobok.notice.infrastructure.NoticeQueryRepository;
import io.sobok.SobokSobok.notice.infrastructure.NoticeRepository;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -24,21 +30,29 @@
public class FriendService {

private final UserRepository userRepository;
private final FriendQueryRepository friendQueryRepository;
private final NoticeRepository noticeRepository;
private final SendFriendRepository sendFriendRepository;
private final FriendRepository friendRepository;
private final NoticeQueryRepository noticeQueryRepository;

@Transactional
public AddFriendResponse addFriend(Long userId, Long memberId, String friendName) {
User sender = validateUser(userId);
public AddFriendResponse addFriend(Long userId, AddFriendRequest request) {
User sender = UserServiceUtil.findUserById(userRepository, userId);

if (sender.getId().equals(memberId)) {
if (sender.getId().equals(request.memberId())) {
throw new BadRequestException(ErrorCode.INVALID_SELF_ADD_FRIEND);
}

User receiver = validateUser(memberId);
User receiver = UserServiceUtil.findUserById(userRepository, request.memberId());

if (friendQueryRepository.isAlreadyFriend(sender.getId(), receiver.getId())) {
if (friendRepository.countBySenderId(sender.getId()) >= 5 ||
friendRepository.countBySenderId(receiver.getId()) >= 5) {
throw new ConflictException(ErrorCode.EXCEEDED_FRIEND_COUNT);
}

if (noticeQueryRepository.isAlreadyFriendRequestFromSender(sender.getId(), receiver.getId())
|| noticeQueryRepository.isAlreadyFriendRequestFromSender(receiver.getId(),
sender.getId())) {
throw new ConflictException(ErrorCode.ALREADY_FRIEND);
}

Expand All @@ -54,7 +68,7 @@ public AddFriendResponse addFriend(Long userId, Long memberId, String friendName
sendFriendRepository.save(
SendFriend.newInstance(
notice.getId(),
friendName
request.friendName()
)
);

Expand All @@ -66,8 +80,48 @@ public AddFriendResponse addFriend(Long userId, Long memberId, String friendName
.build();
}

private User validateUser(Long userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new NotFoundException(ErrorCode.UNREGISTERED_USER));
@Transactional(noRollbackFor = {ConflictException.class})
public HandleFriendRequestResponse updateNoticeStatus(Long userId, Long noticeId,
HandleFriendRequest request) {
UserServiceUtil.existsUserById(userRepository, userId);

Notice notice = noticeRepository.findById(noticeId)
.orElseThrow(() -> new BadRequestException(ErrorCode.BAD_REQUEST_EXCEPTION));

if (!userId.equals(notice.getReceiverId())) {
throw new ForbiddenException(ErrorCode.FORBIDDEN_EXCEPTION);
}

User sender = UserServiceUtil.findUserById(userRepository, notice.getSenderId());

if (friendRepository.countBySenderId(userId) >= 5 ||
friendRepository.countBySenderId(sender.getId()) >= 5) {
notice.setIsOkay(NoticeStatus.REFUSE);
throw new ConflictException(ErrorCode.EXCEEDED_FRIEND_COUNT);
}

notice.setIsOkay(request.isOkay());

if (request.isOkay() == NoticeStatus.ACCEPT) {
SendFriend sendFriend = sendFriendRepository.findByNoticeId(noticeId);
friendRepository.save(Friend.newInstance(
sender.getId(),
userId,
sendFriend.getFriendName()
));

friendRepository.save(Friend.newInstance(
userId,
sender.getId(),
sender.getUsername()
));
}

return HandleFriendRequestResponse.builder()
.noticeId(notice.getId())
.memberName(sender.getUsername())
.isOkay(request.isOkay())
.updatedAt(LocalDateTime.now())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@

public interface FriendRepository extends JpaRepository<Friend, Long> {

Integer countBySenderId(Long senderId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
import org.springframework.data.jpa.repository.JpaRepository;

public interface SendFriendRepository extends JpaRepository<SendFriend, Long> {

SendFriend findByNoticeId(Long noticeId);
}
31 changes: 27 additions & 4 deletions src/main/java/io/sobok/SobokSobok/friend/ui/FriendController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
import io.sobok.SobokSobok.common.dto.ApiResponse;
import io.sobok.SobokSobok.exception.SuccessCode;
import io.sobok.SobokSobok.friend.application.FriendService;
import io.sobok.SobokSobok.friend.ui.dto.AddFriendRequest;
import io.sobok.SobokSobok.friend.ui.dto.AddFriendResponse;
import io.sobok.SobokSobok.friend.ui.dto.HandleFriendRequest;
import io.sobok.SobokSobok.friend.ui.dto.HandleFriendRequestResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
Expand All @@ -31,14 +37,31 @@ public class FriendController {
)
public ResponseEntity<ApiResponse<AddFriendResponse>> addFriend(
@AuthenticationPrincipal User user,
@RequestParam final Long memberId,
@RequestParam final String friendName
@RequestBody @Valid final AddFriendRequest request
) {
return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(
SuccessCode.ADD_FRIEND_SUCCESS,
friendService.addFriend(user.getId(), memberId, friendName)
friendService.addFriend(user.getId(), request)
));
}

@PutMapping("/{noticeId}")
@Operation(
summary = "공유 수락 API 메서드",
description = "캘린더 공유를 수락 혹은 거절하는 메서드입니다."
)
public ResponseEntity<ApiResponse<HandleFriendRequestResponse>> handleFriendRequest(
@AuthenticationPrincipal User user,
@PathVariable Long noticeId,
@RequestBody @Valid HandleFriendRequest request
) {
return ResponseEntity
.status(HttpStatus.OK)
.body(ApiResponse.success(
SuccessCode.HANDLE_FRIEND_REQUEST_SUCCESS,
friendService.updateNoticeStatus(user.getId(), noticeId, request)
));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.sobok.SobokSobok.friend.ui.dto;

import io.swagger.v3.oas.annotations.media.Schema;

public record AddFriendRequest(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
Long memberId,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
String friendName
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.sobok.SobokSobok.friend.ui.dto;

import io.sobok.SobokSobok.notice.domain.NoticeStatus;
import io.swagger.v3.oas.annotations.media.Schema;

public record HandleFriendRequest(
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
NoticeStatus isOkay
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.sobok.SobokSobok.friend.ui.dto;

import io.sobok.SobokSobok.notice.domain.NoticeStatus;
import java.time.LocalDateTime;
import lombok.Builder;

@Builder
public record HandleFriendRequestResponse(
Long noticeId,
String memberName,
NoticeStatus isOkay,
LocalDateTime updatedAt
) {

}
4 changes: 4 additions & 0 deletions src/main/java/io/sobok/SobokSobok/notice/domain/Notice.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public class Notice extends BaseEntity {
@Enumerated(EnumType.STRING)
private NoticeStatus isOkay;

public void setIsOkay(NoticeStatus isOkay) {
this.isOkay = isOkay;
}

private Notice(Long senderId, Long receiverId, NoticeType section, NoticeStatus isOkay) {
this.senderId = senderId;
this.receiverId = receiverId;
Expand Down
Loading

0 comments on commit e1a92c3

Please sign in to comment.