Skip to content

Commit

Permalink
conflict 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
sh0723 committed Nov 14, 2024
2 parents 50eb5a7 + f9ce138 commit 6dfceb3
Show file tree
Hide file tree
Showing 34 changed files with 791 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.gamzabat.algohub.feature.group.studygroup.exception.GroupMemberValidationException;
import com.gamzabat.algohub.feature.group.studygroup.exception.InvalidRoleException;
import com.gamzabat.algohub.feature.notice.exception.NoticeValidationException;
import com.gamzabat.algohub.feature.notification.exception.CannotFoundNotificationSettingException;
import com.gamzabat.algohub.feature.problem.exception.NotBojLinkException;
import com.gamzabat.algohub.feature.problem.exception.SolvedAcApiErrorException;
import com.gamzabat.algohub.feature.solution.exception.CannotFoundSolutionException;
Expand Down Expand Up @@ -121,4 +122,10 @@ protected ResponseEntity<ErrorResponse> handler(CannotFoundProblemException e) {
protected ResponseEntity<ErrorResponse> handler(CannotFoundRankingException e) {
return ResponseEntity.badRequest().body(new ErrorResponse(HttpStatus.NOT_FOUND.value(), e.getError(), null));
}

@ExceptionHandler(CannotFoundNotificationSettingException.class)
protected ResponseEntity<ErrorResponse> handler(CannotFoundNotificationSettingException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(HttpStatus.NOT_FOUND.value(), e.getError(), null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ public interface CommentService<T extends CreateCommentRequest> {
void updateComment(User user, UpdateCommentRequest request);

void deleteComment(User user, Long commentId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
import com.gamzabat.algohub.feature.group.studygroup.repository.GroupMemberRepository;
import com.gamzabat.algohub.feature.group.studygroup.repository.StudyGroupRepository;
import com.gamzabat.algohub.feature.image.service.ImageService;
import com.gamzabat.algohub.feature.notification.domain.NotificationSetting;
import com.gamzabat.algohub.feature.notification.enums.NotificationCategory;
import com.gamzabat.algohub.feature.notification.repository.NotificationSettingRepository;
import com.gamzabat.algohub.feature.notification.service.NotificationService;
import com.gamzabat.algohub.feature.problem.domain.Problem;
import com.gamzabat.algohub.feature.problem.repository.ProblemRepository;
import com.gamzabat.algohub.feature.solution.repository.SolutionRepository;
Expand All @@ -69,6 +73,8 @@ public class StudyGroupService {
private final RankingRepository rankingRepository;

private final ObjectProvider<StudyGroupService> studyGroupServiceProvider;
private final NotificationSettingRepository notificationSettingRepository;
private final NotificationService notificationService;

@Transactional
public GroupCodeResponse createGroup(User user, CreateGroupRequest request, MultipartFile profileImage) {
Expand Down Expand Up @@ -99,6 +105,10 @@ public GroupCodeResponse createGroup(User user, CreateGroupRequest request, Mult
.currentRank(1)
.rankDiff("-")
.build());

notificationSettingRepository.save(
NotificationSetting.builder().member(member).build()
);
log.info("success to save study group");
return new GroupCodeResponse(inviteCode);
}
Expand All @@ -119,6 +129,10 @@ public void joinGroupWithCode(User user, String code) {
.build();
groupMemberRepository.save(member);

notificationSettingRepository.save(
NotificationSetting.builder().member(member).build()
);

rankingRepository.save(Ranking.builder()
.member(member)
.currentRank(groupMemberRepository.countByStudyGroup(studyGroup))
Expand All @@ -127,6 +141,8 @@ public void joinGroupWithCode(User user, String code) {
.build()
);

sendNewMemberNotification(studyGroup, member);

log.info("success to join study group");
}

Expand All @@ -142,7 +158,8 @@ public void deleteGroup(User user, Long groupId) {
if (RoleOfGroupMember.isOwner(groupMember)) { // owner
bookmarkedStudyGroupRepository.deleteAll(bookmarkedStudyGroupRepository.findAllByStudyGroup(studyGroup));
rankingRepository.deleteAll(rankingRepository.findAllByStudyGroup(studyGroup));
groupMemberRepository.delete(groupMember);
notificationSettingRepository.deleteAll(notificationSettingRepository.findAllByStudyGroup(studyGroup));
groupMemberRepository.deleteAll(groupMemberRepository.findAllByStudyGroup(studyGroup));
groupRepository.delete(studyGroup);
} else { // member
studyGroupServiceProvider.getObject().deleteMemberFromStudyGroup(user, groupMember, studyGroup);
Expand Down Expand Up @@ -177,6 +194,7 @@ public void deleteMemberFromStudyGroup(User user, GroupMember groupMember, Study
bookmarkedStudyGroupRepository.findByUserAndStudyGroup(user, studyGroup)
.ifPresent(bookmarkedStudyGroupRepository::delete);
rankingRepository.deleteByMember(groupMember);
notificationSettingRepository.deleteByMember(groupMember);
groupMemberRepository.delete(groupMember);
log.info("success to delete group member");
}
Expand Down Expand Up @@ -475,4 +493,18 @@ public GetStudyGroupListsResponse getOtherStudyGroupList(Long targetUserId) {
private boolean isVisible(StudyGroup group, User user) {
return groupMemberRepository.existsByUserAndStudyGroupAndIsVisible(user, group, true);
}

private void sendNewMemberNotification(StudyGroup studyGroup, GroupMember newMember) {
List<GroupMember> members = groupMemberRepository.findAllByStudyGroup(studyGroup)
.stream()
.filter(member -> !member.getId().equals(newMember.getId()))
.toList();

notificationService.sendNotificationToMembers(
studyGroup,
members,
NotificationCategory.NEW_MEMBER_JOINED,
NotificationCategory.NEW_MEMBER_JOINED.getMessage(newMember.getUser().getNickname())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class Notice {
private String title;
@Column(columnDefinition = "TEXT")
private String content;
private String category;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

Expand All @@ -43,17 +44,20 @@ public class Notice {
private StudyGroup studyGroup;

@Builder
public Notice(User author, StudyGroup studyGroup, String title, String content, LocalDateTime createdAt) {
public Notice(User author, StudyGroup studyGroup, String title, String content, String category,
LocalDateTime createdAt) {
this.author = author;
this.title = title;
this.studyGroup = studyGroup;
this.content = content;
this.category = category;
this.createdAt = createdAt;
}

public void updateNotice(String title, String content) {
public void updateNotice(String title, String content, String category) {
this.title = title;
this.content = content;
this.category = category;
this.updatedAt = LocalDateTime.now();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

public record CreateNoticeRequest(@NotNull(message = "그룹id 는 필수입니다") Long studyGroupId,
public record CreateNoticeRequest(@NotNull(message = "그룹 id 는 필수입니다") Long studyGroupId,
@NotBlank(message = "제목은 필수 입력입니다") String title,
@NotBlank(message = "본문은 필수 입력입니다") String content
@NotBlank(message = "본문은 필수 입력입니다") String content,
@NotBlank(message = "카테고리는 필수 입력입니다") String category
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@
@Builder
public record GetNoticeResponse(String author,
Long noticeId,
String noticeContent,
String noticeTitle,
String content,
String title,
String category,
String createAt) {

public static GetNoticeResponse toDTO(Notice notice) {
return GetNoticeResponse.builder()
.author(notice.getAuthor().getNickname())
.noticeId(notice.getId())
.noticeTitle(notice.getTitle())
.noticeContent(notice.getContent())
.title(notice.getTitle())
.content(notice.getContent())
.category(notice.getCategory())
.createAt(DateFormatUtil.formatDate(notice.getCreatedAt().toLocalDate()))
.build();

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

public record UpdateNoticeRequest(@NotNull(message = "게시글 id는 필수 입니다.") Long noticeId,
@NotBlank(message = "제목은 필수 입력입니다") String title,
@NotBlank(message = "본문은 필수 입력입니다") String content) {
@NotBlank(message = "본문은 필수 입력입니다") String content,
@NotBlank(message = "카테고리는 필수 입력입니다") String category
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public void createNotice(@AuthedUser User user, CreateNoticeRequest request) {
.studyGroup(studyGroup)
.title(request.title())
.content(request.content())
.category(request.category())
.createdAt(LocalDateTime.now())
.build());
log.info("success to create notice");
Expand All @@ -71,8 +72,9 @@ public GetNoticeResponse getNotice(@AuthedUser User user, Long noticeId) {
return GetNoticeResponse.builder()
.author(notice.getAuthor().getNickname())
.noticeId(notice.getId())
.noticeTitle(notice.getTitle())
.noticeContent(notice.getContent())
.title(notice.getTitle())
.content(notice.getContent())
.category(notice.getCategory())
.createAt(DateFormatUtil.formatDate(notice.getCreatedAt().toLocalDate()))
.build();
}
Expand All @@ -98,7 +100,7 @@ public void updateNotice(User user, UpdateNoticeRequest request) {
if (!user.getId().equals(notice.getAuthor().getId()))
throw new UserValidationException("공지를 수정할 수 있는 권한이 없습니다");

notice.updateNotice(request.title(), request.content());
notice.updateNotice(request.title(), request.content(), request.category());
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import com.gamzabat.algohub.common.annotation.AuthedUser;
import com.gamzabat.algohub.exception.RequestException;
import com.gamzabat.algohub.feature.notification.dto.EditNotificationSettingRequest;
import com.gamzabat.algohub.feature.notification.dto.GetNotificationResponse;
import com.gamzabat.algohub.feature.notification.dto.GetNotificationSettingResponse;
import com.gamzabat.algohub.feature.notification.service.NotificationService;
import com.gamzabat.algohub.feature.notification.service.NotificationSettingService;
import com.gamzabat.algohub.feature.user.domain.User;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
Expand All @@ -27,6 +34,7 @@
@Tag(name = "알림 API", description = "알림 관련 API")
public class NotificationController {
private final NotificationService notificationService;
private final NotificationSettingService notificationSettingService;

@GetMapping(value = "/subscribe", produces = TEXT_EVENT_STREAM_VALUE)
@Operation(summary = "SSE 알림 연결 API")
Expand All @@ -47,4 +55,20 @@ public void updateIsRead(@AuthedUser User user) {
notificationService.updateIsRead(user);
}

@GetMapping(value = "/setting")
@Operation(summary = "알림 설정 목록 조회 API", description = "유저가 가입한 그룹들에 대해 알림 설정 목록을 조회하는 API")
public ResponseEntity<List<GetNotificationSettingResponse>> getNotificationSettings(@AuthedUser User user) {
return ResponseEntity.ok().body(notificationSettingService.getNotificationSettings(user));
}

@PatchMapping(value = "/setting")
@Operation(summary = "알림 설정 수정 API")
public ResponseEntity<Void> updateNotificationSettings(@AuthedUser User user, @Valid @RequestBody
EditNotificationSettingRequest request, Errors errors) {
if (errors.hasErrors())
throw new RequestException("알림 설정 수정 요청이 올바르지 않습니다.", errors);
notificationSettingService.editNotificationSettings(user, request);
return ResponseEntity.ok().build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.gamzabat.algohub.feature.notification.domain;

import com.gamzabat.algohub.feature.group.studygroup.domain.GroupMember;

import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class NotificationSetting {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private GroupMember member;

private boolean allNotifications;
private boolean newProblem;
private boolean newSolution;
private boolean newComment;
private boolean newMember;
private boolean deadlineReached;

@Builder
public NotificationSetting(GroupMember member) {
this.member = member;
this.allNotifications = true;
this.newProblem = true;
this.newSolution = true;
this.newComment = true;
this.newMember = true;
this.deadlineReached = true;
}

public void editSettings(boolean all, boolean newProblem, boolean newSolution, boolean newComment,
boolean newMember, boolean deadlineReached) {
this.allNotifications = all;
this.newProblem = newProblem;
this.newSolution = newSolution;
this.newComment = newComment;
this.newMember = newMember;
this.deadlineReached = deadlineReached;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.gamzabat.algohub.feature.notification.dto;

import jakarta.validation.constraints.NotNull;

public record EditNotificationSettingRequest(@NotNull(message = "그룹 아이디는 필수 입력입니다.") Long groupId,
boolean all,
boolean newProblem,
boolean newSolution,
boolean newComment,
boolean newMember,
boolean deadlineReached) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.gamzabat.algohub.feature.notification.dto;

import com.gamzabat.algohub.feature.notification.domain.NotificationSetting;

import lombok.Builder;

@Builder
public record GetNotificationSettingResponse(Long groupId,
String groupName,
boolean allNotifications,
boolean newProblem,
boolean newSolution,
boolean newComment,
boolean newMember,
boolean deadlineReached) {

public static GetNotificationSettingResponse toDTO(NotificationSetting setting) {
return GetNotificationSettingResponse.builder()
.groupId(setting.getMember().getStudyGroup().getId())
.groupName(setting.getMember().getStudyGroup().getName())
.allNotifications(setting.isAllNotifications())
.newProblem(setting.isNewProblem())
.newSolution(setting.isNewSolution())
.newComment(setting.isNewComment())
.newMember(setting.isNewMember())
.deadlineReached(setting.isDeadlineReached())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.gamzabat.algohub.feature.notification.enums;

public enum NotificationCategory {
PROBLEM_STARTED("[%s] 문제가 시작되었습니다! 지금 도전해보세요!"),
NEW_SOLUTION_POSTED("%s님이 새로운 풀이를 등록했습니다! 풀이를 확인하고 의견을 나눠보세요."),
NEW_MEMBER_JOINED("%s님이 스터디에 합류했습니다!"),
NEW_COMMENT_POSTED("%s님이 내 풀이에 코멘트를 남겼습니다! 어떤 리뷰인지 확인해보세요."),
PROBLEM_DEADLINE_REACHED("[%s] 문제의 마감이 오늘입니다! 아직 해결하지 못했다면 지금 도전해보세요!");

private final String message;

NotificationCategory(String message) {
this.message = message;
}

public String getMessage(Object... args) {
return String.format(message, args);
}
}
Loading

0 comments on commit 6dfceb3

Please sign in to comment.