Skip to content

Commit

Permalink
Merge pull request #21 from KUSITMS-MOAMOA/feat/#17
Browse files Browse the repository at this point in the history
[Feat/#17] : AI 만족도 조사 기능 추가
  • Loading branch information
oosedus authored Feb 18, 2025
2 parents 3899eb4 + 0624590 commit e1c9654
Show file tree
Hide file tree
Showing 51 changed files with 542 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.ability.domain.entity.Ability;
import corecord.dev.domain.ability.domain.entity.Keyword;
import corecord.dev.domain.ability.domain.enums.Keyword;
import corecord.dev.domain.ability.domain.repository.AbilityRepository;
import corecord.dev.domain.folder.domain.entity.Folder;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import corecord.dev.domain.ability.domain.converter.AbilityConverter;
import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.ability.domain.entity.Ability;
import corecord.dev.domain.ability.domain.entity.Keyword;
import corecord.dev.domain.ability.domain.enums.Keyword;
import corecord.dev.domain.ability.exception.AbilityException;
import corecord.dev.domain.ability.status.AbilityErrorStatus;
import corecord.dev.domain.analysis.domain.entity.Analysis;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.ability.domain.entity.Ability;
import corecord.dev.domain.ability.domain.entity.Keyword;
import corecord.dev.domain.ability.domain.enums.Keyword;
import corecord.dev.domain.analysis.domain.entity.Analysis;
import corecord.dev.domain.user.domain.entity.User;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package corecord.dev.domain.ability.domain.dto.response;

import corecord.dev.domain.ability.domain.entity.Keyword;
import corecord.dev.domain.ability.domain.enums.Keyword;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package corecord.dev.domain.ability.domain.entity;

import corecord.dev.common.base.BaseEntity;
import corecord.dev.domain.ability.domain.enums.Keyword;
import corecord.dev.domain.analysis.domain.entity.Analysis;
import corecord.dev.domain.user.domain.entity.User;
import jakarta.persistence.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package corecord.dev.domain.ability.domain.entity;
package corecord.dev.domain.ability.domain.enums;

import lombok.AllArgsConstructor;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.ability.domain.entity.Ability;
import corecord.dev.domain.ability.domain.entity.Keyword;
import corecord.dev.domain.ability.domain.enums.Keyword;
import corecord.dev.domain.folder.domain.entity.Folder;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.analysis.domain.dto.response.AnalysisResponse;
import corecord.dev.domain.analysis.domain.entity.Analysis;
import corecord.dev.domain.record.domain.entity.RecordType;
import corecord.dev.domain.record.domain.enums.RecordType;
import corecord.dev.domain.record.domain.entity.Record;

import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package corecord.dev.domain.analysis.domain.dto.response;

import corecord.dev.domain.ability.domain.dto.response.AbilityResponse;
import corecord.dev.domain.record.domain.entity.RecordType;
import corecord.dev.domain.record.domain.enums.RecordType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package corecord.dev.domain.feedback.application;

import corecord.dev.domain.analysis.domain.entity.Analysis;
import corecord.dev.domain.chat.domain.entity.Chat;
import corecord.dev.domain.feedback.domain.dto.request.FeedbackRequest;
import corecord.dev.domain.record.domain.entity.Record;

import java.util.List;

public interface FeedbackAlarmSender {
void sendChatFeedbackAlarm(Record record, FeedbackRequest.FeedbackDto feedbackDto, List<Chat> chatList);
void sendAnalysisFeedbackAlarm(Record record, FeedbackRequest.FeedbackDto feedbackDto, Analysis analysis);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package corecord.dev.domain.feedback.application;

import corecord.dev.domain.feedback.domain.entity.Feedback;
import corecord.dev.domain.feedback.domain.repository.FeedbackRepository;
import corecord.dev.domain.user.domain.entity.User;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class FeedbackDbService {
private final FeedbackRepository feedbackRepository;

@Transactional
public void saveFeedback(Feedback feedback) {
feedbackRepository.save(feedback);
}

@Transactional
public boolean existsByUserAndRecordId(User user, Long recordId) {
return feedbackRepository.existsByUserAndRecordId(user, recordId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package corecord.dev.domain.feedback.application;

import corecord.dev.domain.feedback.domain.dto.request.FeedbackRequest;

public interface FeedbackService {
void saveFeedback(Long userId, FeedbackRequest.FeedbackDto feedbackDto);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package corecord.dev.domain.feedback.application;

import corecord.dev.domain.analysis.application.AnalysisDbService;
import corecord.dev.domain.analysis.domain.entity.Analysis;
import corecord.dev.domain.chat.application.ChatDbService;
import corecord.dev.domain.chat.domain.entity.Chat;
import corecord.dev.domain.feedback.domain.converter.FeedbackConverter;
import corecord.dev.domain.feedback.domain.dto.request.FeedbackRequest;
import corecord.dev.domain.feedback.domain.entity.Feedback;
import corecord.dev.domain.feedback.domain.enums.FeedbackType;
import corecord.dev.domain.feedback.domain.enums.Satisfaction;
import corecord.dev.domain.feedback.domain.exception.FeedbackException;
import corecord.dev.domain.feedback.domain.status.FeedbackErrorStatus;
import corecord.dev.domain.record.application.RecordDbService;
import corecord.dev.domain.record.domain.entity.Record;
import corecord.dev.domain.user.application.UserDbService;
import corecord.dev.domain.user.domain.entity.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class FeedbackServiceImpl implements FeedbackService {
private final UserDbService userDbService;
private final RecordDbService recordDbService;
private final FeedbackDbService feedbackDbService;
private final ChatDbService chatDbService;
private final AnalysisDbService analysisDbService;
private final FeedbackAlarmSender feedbackAlarmSender;

/**
* 피드백 저장
*
* @param userId
* @param feedbackDto
*/

public void saveFeedback(Long userId, FeedbackRequest.FeedbackDto feedbackDto) {
User user = userDbService.findUserById(userId);

// 해당 user의 Record 확인 & 피드백 중복 검사
Record record = getValidatedRecord(user, feedbackDto.getRecordId());
checkAlreadyFeedback(user, record.getRecordId());

// 불만족 피드백 처리
if (feedbackDto.getSatisfaction() == Satisfaction.BAD) {
checkCommentLength(feedbackDto.getComment());
sendFeedbackAlarm(record, feedbackDto);
}

// 피드백 저장
Feedback feedback = FeedbackConverter.toFeedbackEntity(user, feedbackDto);
feedbackDbService.saveFeedback(feedback);
}

private Record getValidatedRecord(User user, Long recordId) {
Record record = recordDbService.findRecordById(recordId);
if (!record.getUser().getUserId().equals(user.getUserId())) {
throw new FeedbackException(FeedbackErrorStatus.UNAUTHORIZED_FEEDBACK);
}
return record;
}

private void checkAlreadyFeedback(User user, Long recordId) {
if (feedbackDbService.existsByUserAndRecordId(user, recordId)) {
throw new FeedbackException(FeedbackErrorStatus.ALREADY_FEEDBACK);
}
}

private void checkCommentLength(String comment) {
if (comment != null && comment.length() > 200) {
throw new FeedbackException(FeedbackErrorStatus.OVERFLOW_FEEDBACK_COMMENT);
}
}

private void sendFeedbackAlarm(Record record, FeedbackRequest.FeedbackDto feedbackDto) {
switch (feedbackDto.getFeedbackType()) {
case FeedbackType.CHAT -> {
List<Chat> chatHistory = chatDbService.findChatsByChatRoom(record.getChatRoom());
feedbackAlarmSender.sendChatFeedbackAlarm(record, feedbackDto, chatHistory);
}
case FeedbackType.ANALYSIS -> {
Analysis analysis = analysisDbService.findAnalysisById(record.getAnalysis().getAnalysisId());
feedbackAlarmSender.sendAnalysisFeedbackAlarm(record, feedbackDto, analysis);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package corecord.dev.domain.feedback.domain.converter;

import corecord.dev.domain.feedback.domain.dto.request.FeedbackRequest;
import corecord.dev.domain.feedback.domain.entity.Feedback;
import corecord.dev.domain.user.domain.entity.User;

public class FeedbackConverter {
public static Feedback toFeedbackEntity(User user, FeedbackRequest.FeedbackDto feedbackDto) {
return Feedback.builder()
.satisfaction(feedbackDto.getSatisfaction())
.feedbackType(feedbackDto.getFeedbackType())
.issue(feedbackDto.getIssue())
.comment(feedbackDto.getComment())
.recordId(feedbackDto.getRecordId())
.user(user)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package corecord.dev.domain.feedback.domain.dto.request;

import corecord.dev.domain.feedback.domain.enums.FeedbackType;
import corecord.dev.domain.feedback.domain.enums.Issue;
import corecord.dev.domain.feedback.domain.enums.Satisfaction;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Data;

public class FeedbackRequest {

@Data
@Builder
public static class FeedbackDto {
@NotNull(message = "recordId를 입력해주세요.")
private Long recordId;
@NotNull(message = "만족 여부를 입력해주세요.")
private Satisfaction satisfaction;
private FeedbackType feedbackType;
private Issue issue;
private String comment;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package corecord.dev.domain.feedback.domain.entity;

import corecord.dev.common.base.BaseEntity;
import corecord.dev.domain.feedback.domain.enums.FeedbackType;
import corecord.dev.domain.feedback.domain.enums.Issue;
import corecord.dev.domain.feedback.domain.enums.Satisfaction;
import corecord.dev.domain.user.domain.entity.User;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "feedback")
public class Feedback extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "feedback_id", nullable = false)
private Long feedbackId;

@Enumerated(EnumType.STRING)
@Column(name = "satisfaction", nullable = false)
private Satisfaction satisfaction;

@Enumerated(EnumType.STRING)
@Column(name = "feedback_type", nullable = true)
private FeedbackType feedbackType;

@Enumerated(EnumType.STRING)
@Column(name = "issue", nullable = true)
private Issue issue;

@Column(name = "comment", nullable = true, length = 200)
private String comment;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;

@Column(name = "record_id", nullable = false)
private Long recordId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package corecord.dev.domain.feedback.domain.enums;

public enum FeedbackType {
CHAT, ANALYSIS
}
24 changes: 24 additions & 0 deletions src/main/java/corecord/dev/domain/feedback/domain/enums/Issue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package corecord.dev.domain.feedback.domain.enums;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public enum Issue {
// chat issue
IRRELEVANT_ANSWER("제 경험과 관련없는 답변을 해요"),
TOO_SIMPLE("질문이 너무 모호하거나 단순해요"),
REPETITIVE("자연스럽지 않고 같은 질문을 반복해요"),
NO_SPECIFIC("경험을 더 구체적으로 정리할 수 없어요"),

// analysis issue
IRRELEVANT_KEYWORD("경험과 관련없은 역량 키워드에요"),
TOO_SHORT("코멘트가 짧고 피드백이 구체적이지 않아요"),
AWKWARD("문장이 자연스럽지 않고 어색해요"),
VAGUE_COMMENT("코멘트가 모호해서 개선할 점을 모르겠어요");

private final String description;

public String getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package corecord.dev.domain.feedback.domain.enums;

public enum Satisfaction {
GOOD, BAD
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package corecord.dev.domain.feedback.domain.exception;

import corecord.dev.common.base.BaseErrorStatus;
import corecord.dev.common.exception.GeneralException;
import lombok.Getter;

@Getter
public class FeedbackException extends GeneralException {

public FeedbackException(BaseErrorStatus errorStatus) {
super(errorStatus);
}

@Override
public String getMessage() {
return errorStatus.getMessage();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package corecord.dev.domain.feedback.domain.repository;

import corecord.dev.domain.feedback.domain.entity.Feedback;
import corecord.dev.domain.user.domain.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface FeedbackRepository extends JpaRepository<Feedback, Long> {
boolean existsByUserAndRecordId(User user, Long recordId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package corecord.dev.domain.feedback.domain.status;

import corecord.dev.common.base.BaseErrorStatus;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
@AllArgsConstructor
public enum FeedbackErrorStatus implements BaseErrorStatus {
OVERFLOW_FEEDBACK_COMMENT(HttpStatus.BAD_REQUEST, "E203_OVERFLOW_FEEDBACK_COMMENT", "피드백 내용은 200자 이내여야 합니다."),
UNAUTHORIZED_FEEDBACK(HttpStatus.UNAUTHORIZED, "E203_FEEDBACK_UNAUTHORIZED", "유저가 해당 피드백에 대한 권한이 없습니다."),
ALREADY_FEEDBACK(HttpStatus.BAD_REQUEST, "E203_ALREADY_FEEDBACK", "이미 피드백을 작성한 경험입니다."),
;

private final HttpStatus httpStatus;
private final String code;
private final String message;
}
Loading

0 comments on commit e1c9654

Please sign in to comment.