Skip to content

Commit

Permalink
feat: Notification 생성 및 조회 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
kpeel5839 committed Oct 20, 2024
1 parent ad3a426 commit f286e04
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package kr.co.conceptbe.notification.app;

import kr.co.conceptbe.auth.presentation.dto.AuthCredentials;
import kr.co.conceptbe.idea.domain.Idea;
import kr.co.conceptbe.idea.domain.event.CreatedIdeaEvent;
import kr.co.conceptbe.member.domain.IdeaNotificationSetting;
import kr.co.conceptbe.member.domain.repository.NotificationSettingRepository;
import kr.co.conceptbe.member.exception.NotFoundAuthCredentialException;
import kr.co.conceptbe.member.persistence.MemberRepository;
import kr.co.conceptbe.notification.app.dto.NotificationResponse;
import kr.co.conceptbe.notification.domain.IdeaNotification;
import kr.co.conceptbe.notification.domain.NotificationTrigger;
import kr.co.conceptbe.notification.domain.repository.NotificationRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class NotificationService {

private final MemberRepository memberRepository;
private final NotificationRepository notificationRepository;
private final NotificationSettingRepository notificationSettingRepository;
private final NotificationTrigger notificationTrigger;

@Transactional(readOnly = true)
public List<NotificationResponse> findAllNotifications(
AuthCredentials authCredentials,
Long cursorId,
Long limit
) {
if (!memberRepository.existsById(authCredentials.id())) {
throw new NotFoundAuthCredentialException(authCredentials.id());
}

return notificationRepository.findAllNotifications(authCredentials.id(), cursorId, limit)
.stream()
.map(NotificationResponse::from)
.toList();
}

@Transactional
public void createNotificationByCreateIdeaEvent(CreatedIdeaEvent createdIdeaEvent) {
Idea idea = createdIdeaEvent.idea();
List<IdeaNotificationSetting> notificationSettings = notificationSettingRepository.findAll();

List<IdeaNotification> ideaNotifications = notificationTrigger.getNotificationByCreatedIdeaEvent(idea, notificationSettings);
notificationRepository.saveAll(ideaNotifications);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package kr.co.conceptbe.notification.app.dto;

import kr.co.conceptbe.notification.domain.IdeaNotification;

import java.util.List;

public record NotificationResponse(
Long id,
Long feedId,
String title,
String createAt,
List<String> badges
) {

public static NotificationResponse from(IdeaNotification notification) {
List<String> ideaBranches = notification.getBranches();
ideaBranches.addAll(notification.getPurposes());
ideaBranches.add(notification.getCooperationWay());

return new NotificationResponse(
notification.getId(),
notification.getIdeaId(),
notification.getTitle(),
notification.getCreatedAt().toString(),
notification.getBranches()
);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kr.co.conceptbe.notification.app.event;

import kr.co.conceptbe.idea.domain.event.CreatedIdeaEvent;
import kr.co.conceptbe.notification.app.NotificationService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class NotificationEventListener {

private final NotificationService notificationService;

@EventListener
private void createIdea(CreatedIdeaEvent createdIdeaEvent) {
notificationService.createNotificationByCreateIdeaEvent(createdIdeaEvent);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package kr.co.conceptbe.notification.domain;

import kr.co.conceptbe.branch.domain.Branch;
import kr.co.conceptbe.idea.domain.Idea;
import kr.co.conceptbe.idea.domain.IdeaBranch;
import kr.co.conceptbe.idea.domain.IdeaPurpose;
import kr.co.conceptbe.member.domain.IdeaNotificationSetting;
import kr.co.conceptbe.member.domain.vo.NotificationSettingBranch;
import kr.co.conceptbe.member.domain.vo.NotificationSettingPurpose;
import kr.co.conceptbe.purpose.domain.Purpose;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class NotificationTrigger {

public List<IdeaNotification> getNotificationByCreatedIdeaEvent(
Idea idea,
List<IdeaNotificationSetting> notificationSettings
) {
return notificationSettings.stream()
.filter(notificationSetting -> isSuitToMeIdea(idea, notificationSetting))
.map(notificationSetting -> IdeaNotification.withIdea(idea))
.toList();
}

private boolean isSuitToMeIdea(Idea idea, IdeaNotificationSetting notificationSetting) {
return isSuitToMemberBranch(idea.getBranches(), notificationSetting)
&& isSuitToMemberPurpose(idea.getPurposes(), notificationSetting)
&& isSuitToMemberCooperationWay(idea.getCooperationWay(), notificationSetting);
}

private boolean isSuitToMemberBranch(
List<IdeaBranch> branches,
IdeaNotificationSetting ideaNotificationSetting
) {
List<Branch> notificationBranches = ideaNotificationSetting.getBranches()
.getNotificationSettingBranches()
.stream()
.map(NotificationSettingBranch::getBranch)
.toList();
List<Branch> ideaBranches = branches.stream()
.map(IdeaBranch::getBranch)
.toList();

for (Branch notificationBranch : notificationBranches) {
for (Branch ideaBranch : ideaBranches) {
if (notificationBranch.isInclude(ideaBranch)) {
return true;
}
}
}

return false;
}

private boolean isSuitToMemberPurpose(
List<IdeaPurpose> purposes,
IdeaNotificationSetting ideaNotificationSetting
) {
List<Purpose> notificationPurposes = ideaNotificationSetting.getPurposes()
.getNotificationSettingPurposes()
.stream()
.map(NotificationSettingPurpose::getPurpose)
.toList();

List<Purpose> ideaPurposes = purposes.stream()
.map(IdeaPurpose::getPurpose)
.toList();

for (Purpose notificationPurpose : notificationPurposes) {
for (Purpose ideaPurpose : ideaPurposes) {
if (notificationPurpose.isInclude(ideaPurpose)) {
return true;
}
}
}

return false;
}

private boolean isSuitToMemberCooperationWay(
String cooperationWay,
IdeaNotificationSetting ideaNotificationSetting
) {
return ideaNotificationSetting.getCooperationWay()
.isInclude(cooperationWay);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kr.co.conceptbe.notification.presentation.swagger;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import kr.co.conceptbe.auth.presentation.dto.AuthCredentials;
import kr.co.conceptbe.common.auth.Auth;
import kr.co.conceptbe.notification.app.dto.NotificationResponse;
import org.springframework.http.ResponseEntity;

import java.util.List;

@Tag(name = "Notification", description = "알림 API")
public interface NotificationSwagger {

ResponseEntity<List<NotificationResponse>> getNotifications(
@Parameter(hidden = true) @Auth AuthCredentials auth,
Long cursorId
);

}

0 comments on commit f286e04

Please sign in to comment.