Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 쓴 피드백은 피드백 모아보기에서 바로 볼 수 있도록 변경 + 리팩터링(#613) #617

Merged
merged 12 commits into from
Oct 19, 2024
Merged
1 change: 1 addition & 0 deletions backend/src/main/java/corea/exception/ExceptionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public enum ExceptionType {
INVALID_TOKEN(HttpStatus.UNAUTHORIZED, "토큰이 올바르지 않습니다."),
AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED, "인증에 실패했습니다."),
ROOM_DELETION_AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED, "방 삭제 권한이 없습니다. 방 생성자만 방을 삭제할 수 있습니다."),
FEEDBACK_UPDATE_AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED, "피드백 수정 권한이 없습니다. 피드백 작성자만 피드백을 수정할 수 있습니다."),

MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 멤버를 찾을 수 없습니다."),
ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "방을 찾을 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import corea.auth.annotation.LoginMember;
import corea.auth.domain.AuthInfo;
import corea.feedback.dto.DevelopFeedbackRequest;
import corea.feedback.dto.DevelopFeedbackCreateRequest;
import corea.feedback.dto.DevelopFeedbackResponse;
import corea.feedback.dto.DevelopFeedbackUpdateRequest;
import corea.feedback.service.DevelopFeedbackService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -16,15 +17,13 @@ public class DevelopFeedbackController implements DevelopFeedbackControllerSpeci

private final DevelopFeedbackService developFeedbackService;

@Override
@PostMapping
public ResponseEntity<Void> create(@PathVariable long roomId, @LoginMember AuthInfo authInfo, @RequestBody DevelopFeedbackRequest request) {
public ResponseEntity<Void> create(@PathVariable long roomId, @LoginMember AuthInfo authInfo, @RequestBody DevelopFeedbackCreateRequest request) {
developFeedbackService.create(roomId, authInfo.getId(), request);
return ResponseEntity.ok()
.build();
}

@Override
@GetMapping
public ResponseEntity<DevelopFeedbackResponse> developFeedback(
@PathVariable long roomId, @RequestParam String username, @LoginMember AuthInfo authInfo) {
Expand All @@ -33,10 +32,9 @@ public ResponseEntity<DevelopFeedbackResponse> developFeedback(
.body(response);
}

@Override
@PutMapping("/{feedbackId}")
public ResponseEntity<Void> update(
@PathVariable long roomId, @PathVariable long feedbackId, @LoginMember AuthInfo authInfo, @RequestBody DevelopFeedbackRequest request) {
@PathVariable long roomId, @PathVariable long feedbackId, @LoginMember AuthInfo authInfo, @RequestBody DevelopFeedbackUpdateRequest request) {
developFeedbackService.update(feedbackId, authInfo.getId(), request);
return ResponseEntity.ok()
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import corea.auth.domain.AuthInfo;
import corea.exception.ExceptionType;
import corea.feedback.dto.DevelopFeedbackRequest;
import corea.feedback.dto.DevelopFeedbackCreateRequest;
import corea.feedback.dto.DevelopFeedbackResponse;
import corea.feedback.dto.DevelopFeedbackUpdateRequest;
import corea.global.annotation.ApiErrorResponses;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand All @@ -26,7 +27,7 @@ ResponseEntity<Void> create(
@Parameter(description = "방 아이디", example = "1")
long roomId,
AuthInfo authInfo,
DevelopFeedbackRequest request);
DevelopFeedbackCreateRequest request);

@Operation(summary = "개발 관련 피드백 리스트를 반환합니다.",
description = "자신에게 사람들이 남긴 개발 능력 관련 피드백을 읽어옵니다. <br>" +
Expand Down Expand Up @@ -59,5 +60,5 @@ ResponseEntity<Void> update(
@Parameter(description = "피드백 아이디", example = "2")
long feedbackId,
AuthInfo authInfo,
DevelopFeedbackRequest request);
DevelopFeedbackUpdateRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ public DevelopFeedback(long roomId, Member deliver, Member receiver, int evaluat
this(null, roomId, deliver, receiver, evaluatePoint, keywords, feedBackText, recommendationPoint);
}

public boolean isNotMatchingDeliver(long deliverId) {
return deliver.isNotMatchingId(deliverId);
}

public void update(int evaluationPoint, List<String> feedbackKeywords, String feedbackText, int recommendationPoint) {
this.evaluatePoint = evaluationPoint;
this.keywords = FeedbackKeywordConverter.convertToKeywords(feedbackKeywords);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package corea.feedback.domain;

import corea.exception.CoreaException;
import corea.exception.ExceptionType;
import corea.feedback.dto.FeedbackOutput;
import corea.feedback.repository.DevelopFeedbackRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class DevelopFeedbackReader {

private final DevelopFeedbackRepository developFeedbackRepository;

public Map<Long, List<FeedbackOutput>> collectDeliverDevelopFeedback(long feedbackDeliverId) {
return developFeedbackRepository.findAllByDeliverId(feedbackDeliverId)
.stream()
.map(FeedbackOutput::fromDeliver)
.collect(Collectors.groupingBy(FeedbackOutput::roomId));
}

public Map<Long, List<FeedbackOutput>> collectReceivedDevelopFeedback(long feedbackReceiverId) {
return developFeedbackRepository.findAllByReceiverId(feedbackReceiverId)
.stream()
.map(FeedbackOutput::fromReceiver)
.collect(Collectors.groupingBy(FeedbackOutput::roomId));
}

public DevelopFeedback findById(long feedbackId) {
return developFeedbackRepository.findById(feedbackId)
.orElseThrow(() -> new CoreaException(ExceptionType.FEEDBACK_NOT_FOUND));
}

public DevelopFeedback findDevelopFeedback(long roomId, long deliverId, String username) {
return developFeedbackRepository.findByRoomIdAndDeliverIdAndReceiverUsername(roomId, deliverId, username)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 근본적으로 HTTP API 가 username 이 아닌 receiverId 를 받는것도 생각해봐야 겠네요
( 인덱스 지정 및 명확하게 하려면 )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

username 이 아닌 receiverId 를 받는것도 생각해봐야 겠네요
( 인덱스 지정 및 명확하게 하려면 )

👍 동의요~!

근데 memberId를 외부로 노출시키지 않기 위해 username으로 받은 설계를 했던 것 같은데, 그럼 이런 느낌으로 되는게 맞겠죠?

public class DevelopFeedbackService {

    public DevelopFeedbackResponse findDevelopFeedback(long roomId, long deliverId, String username) {
        // 여기서 username을 통해 memberId를 찾는다.
        long receiverId = ...;

        DevelopFeedback developFeedback = developFeedbackReader.findDevelopFeedback(roomId, deliverId, receiverId);
        return DevelopFeedbackResponse.from(developFeedback);
    }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뽀로로 의견이 좋은 것 같습니다용 👍

.orElseThrow(() -> new CoreaException(ExceptionType.FEEDBACK_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package corea.feedback.domain;

import corea.exception.CoreaException;
import corea.exception.ExceptionType;
import corea.feedback.dto.DevelopFeedbackUpdateInput;
import corea.feedback.repository.DevelopFeedbackRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Component
@RequiredArgsConstructor
@Transactional
public class DevelopFeedbackWriter {

private final DevelopFeedbackRepository developFeedbackRepository;

public DevelopFeedback create(DevelopFeedback developFeedback, long roomId, long deliverId, long receiverId) {
validateAlreadyExist(roomId, deliverId, receiverId);
log.info("개발 피드백 작성 [방 ID={}, 작성자 ID={}, 수신자 ID={}]", roomId, deliverId, receiverId);

return developFeedbackRepository.save(developFeedback);
}

private void validateAlreadyExist(long roomId, long deliverId, long receiverId) {
if (developFeedbackRepository.existsByRoomIdAndDeliverIdAndReceiverId(roomId, deliverId, receiverId)) {
throw new CoreaException(ExceptionType.ALREADY_COMPLETED_FEEDBACK);
}
}

public void update(DevelopFeedback developFeedback, long deliverId, DevelopFeedbackUpdateInput input) {
validateUpdateAuthority(developFeedback, deliverId);
log.info("개발 피드백 업데이트 [피드백 ID={}, 작성자 ID={}, 요청값={}]", developFeedback.getId(), developFeedback, input);

developFeedback.update(
input.evaluationPoint(),
input.feedbackKeywords(),
input.feedbackText(),
input.recommendationPoint()
);
}

private void validateUpdateAuthority(DevelopFeedback developFeedback, long deliverId) {
if (developFeedback.isNotMatchingDeliver(deliverId)) {
throw new CoreaException(ExceptionType.FEEDBACK_UPDATE_AUTHORIZATION_ERROR);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세부 예외 처리 👍

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package corea.feedback.domain;

import corea.feedback.dto.FeedbackOutput;
import corea.feedback.repository.SocialFeedbackRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SocialFeedbackReader {

private final SocialFeedbackRepository socialFeedbackRepository;

public Map<Long, List<FeedbackOutput>> collectDeliverSocialFeedback(long feedbackDeliverId) {
return socialFeedbackRepository.findAllByDeliverId(feedbackDeliverId)
.stream()
.map(FeedbackOutput::fromDeliver)
.collect(Collectors.groupingBy(FeedbackOutput::roomId));
}

public Map<Long, List<FeedbackOutput>> collectReceivedSocialFeedback(long feedbackReceiverId) {
return socialFeedbackRepository.findAllByReceiverId(feedbackReceiverId)
.stream()
.map(FeedbackOutput::fromReceiver)
.collect(Collectors.groupingBy(FeedbackOutput::roomId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package corea.feedback.dto;

import corea.feedback.domain.DevelopFeedback;
import corea.feedback.util.FeedbackKeywordConverter;
import corea.member.domain.Member;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

import java.util.List;

@Schema(description = "개발 능력 관련 피드백 작성 요청")
public record DevelopFeedbackCreateRequest(@Schema(description = "리뷰이 아이디", example = "2")
@NotNull
long receiverId,

@Schema(description = "평가 점수", example = "4")
@NotNull
int evaluationPoint,

@Schema(description = "선택한 피드백 키워드", example = "[\"코드를 이해하기 쉬웠어요\", \"컨벤션이 잘 지켜졌어요\"]")
@NotNull
List<String> feedbackKeywords,

@Schema(description = "부가 작성 가능한 피드백 텍스트", example = "처음 자바를 접해봤다고 했는데 생각보다 매우 잘 구성되어 있는 코드였습니다. ...")
String feedbackText,

@Schema(description = "랭킹에 필요한 추천 점수", example = "2")
int recommendationPoint) {

public DevelopFeedback toEntity(long roomId, Member deliver, Member receiver) {
return new DevelopFeedback(
roomId,
deliver,
receiver,
evaluationPoint,
FeedbackKeywordConverter.convertToKeywords(feedbackKeywords),
feedbackText,
recommendationPoint
);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package corea.feedback.dto;

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

import java.util.List;

@Schema(description = "개발 능력 관련 피드백 업데이트 요청")
public record DevelopFeedbackUpdateInput(@Schema(description = "평가 점수", example = "4")
int evaluationPoint,

@Schema(description = "선택한 피드백 키워드", example = "[\"코드를 이해하기 쉬웠어요\", \"컨벤션이 잘 지켜졌어요\"]")
List<String> feedbackKeywords,

@Schema(description = "부가 작성 가능한 피드백 텍스트", example = "처음 자바를 접해봤다고 했는데 생각보다 매우 잘 구성되어 있는 코드였습니다. ...")
String feedbackText,

@Schema(description = "랭킹에 필요한 추천 점수", example = "2")
int recommendationPoint) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package corea.feedback.dto;

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

import java.util.List;

@Schema(description = "개발 능력 관련 피드백 업데이트 요청")
public record DevelopFeedbackUpdateRequest(@Schema(description = "업데이트할 평가 점수", example = "1")
int evaluationPoint,

@Schema(description = "업데이트할 피드백 키워드", example = "[\"코드를 이해하기 어려웠어요\", \"컨벤션이 안 지켜졌어요\"]")
List<String> feedbackKeywords,

@Schema(description = "업데이트할 피드백 텍스트", example = "처음엔 좋다 생각했는데, 다시 생각하니 별로였어요.")
String feedbackText,

@Schema(description = "업데이트할 랭킹에 필요한 추천 점수", example = "1")
int recommendationPoint) {
}
Loading
Loading