Skip to content

Commit be7a3a3

Browse files
committed
Merge branch 'main' of https://github.com/prgrms-web-devcourse-final-project/WEB1_1_Bongdari_BE into feature/137-add-search
2 parents 6856bed + 404ae84 commit be7a3a3

File tree

10 files changed

+183
-3
lines changed

10 files changed

+183
-3
lines changed

.github/workflows/CD.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ jobs:
3434
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
3535
DEFAULT_IMG_URL: ${{ secrets.DEFAULT_IMG_URL }}
3636
APP_DEVELOP_MODE: ${{ secrets.APP_DEVELOP_MODE }}
37+
ELASTIC_URI=localhost: ${{ secrets.ELASTIC_URI }}
38+
ELASTIC_USERNAME: ${{ secrets.ELASTIC_USERNAME }}
39+
ELASTIC_PASSWORD: ${{ secrets.ELASTIC_PASSWORD }}
3740

3841
steps:
3942
- name: Github Repository 파일 불러오기

.github/workflows/CI.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ jobs:
4242
S3_SECRET_KEY: ${{ secrets.S3_SECRET_KEY }}
4343
DEFAULT_IMG_URL: ${{ secrets.DEFAULT_IMG_URL }}
4444
APP_DEVELOP_MODE: ${{ secrets.APP_DEVELOP_MODE }}
45+
ELASTIC_URI=localhost: ${{ secrets.ELASTIC_URI }}
46+
ELASTIC_USERNAME: ${{ secrets.ELASTIC_USERNAME }}
47+
ELASTIC_PASSWORD: ${{ secrets.ELASTIC_PASSWORD }}
4548

4649

4750
steps:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.somemore.community.event;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.somemore.global.common.event.ServerEvent;
6+
import com.somemore.global.common.event.ServerEventType;
7+
import com.somemore.notification.domain.NotificationSubType;
8+
import lombok.Getter;
9+
import lombok.experimental.SuperBuilder;
10+
11+
import java.time.LocalDateTime;
12+
import java.util.UUID;
13+
14+
@Getter
15+
@SuperBuilder
16+
public class CommentAddedEvent extends ServerEvent<NotificationSubType> {
17+
18+
private final UUID volunteerId;
19+
private final Long communityBoardId;
20+
21+
@JsonCreator
22+
public CommentAddedEvent(
23+
@JsonProperty(value = "volunteerId", required = true) UUID volunteerId,
24+
@JsonProperty(value = "communityBoardId", required = true) Long communityBoardId
25+
) {
26+
super(ServerEventType.NOTIFICATION, NotificationSubType.COMMENT_ADDED, LocalDateTime.now());
27+
this.volunteerId = volunteerId;
28+
this.communityBoardId = communityBoardId;
29+
}
30+
}

src/main/java/com/somemore/community/service/comment/CreateCommunityCommentService.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
import com.somemore.community.domain.CommunityComment;
44
import com.somemore.community.dto.request.CommunityCommentCreateRequestDto;
5+
import com.somemore.community.event.CommentAddedEvent;
56
import com.somemore.community.repository.board.CommunityBoardRepository;
67
import com.somemore.community.repository.comment.CommunityCommentRepository;
78
import com.somemore.community.usecase.comment.CreateCommunityCommentUseCase;
9+
import com.somemore.global.common.event.ServerEventPublisher;
10+
import com.somemore.global.common.event.ServerEventType;
811
import com.somemore.global.exception.BadRequestException;
12+
import com.somemore.notification.domain.NotificationSubType;
13+
import jakarta.persistence.EntityNotFoundException;
914
import lombok.RequiredArgsConstructor;
1015
import org.springframework.stereotype.Service;
1116
import org.springframework.transaction.annotation.Transactional;
@@ -22,6 +27,7 @@ public class CreateCommunityCommentService implements CreateCommunityCommentUseC
2227

2328
private final CommunityBoardRepository communityBoardRepository;
2429
private final CommunityCommentRepository communityCommentRepository;
30+
private final ServerEventPublisher serverEventPublisher;
2531

2632
@Override
2733
public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto, UUID writerId, Long communityBoardId) {
@@ -33,6 +39,7 @@ public Long createCommunityComment(CommunityCommentCreateRequestDto requestDto,
3339
validateParentCommentExists(communityComment.getParentCommentId());
3440
}
3541

42+
publishCommentAddedEvent(communityComment);
3643
return communityCommentRepository.save(communityComment).getId();
3744
}
3845

@@ -47,4 +54,37 @@ private void validateParentCommentExists(Long parentCommentId) {
4754
throw new BadRequestException(NOT_EXISTS_COMMUNITY_COMMENT.getMessage());
4855
}
4956
}
57+
58+
private void publishCommentAddedEvent(CommunityComment communityComment) {
59+
Long parentCommentId = communityComment.getParentCommentId();
60+
61+
UUID targetVolunteerId = getTargetVolunteerId(communityComment, parentCommentId);
62+
63+
CommentAddedEvent event = CommentAddedEvent.builder()
64+
.type(ServerEventType.NOTIFICATION)
65+
.subType(NotificationSubType.COMMENT_ADDED)
66+
.volunteerId(targetVolunteerId)
67+
.communityBoardId(communityComment.getCommunityBoardId())
68+
.build();
69+
70+
serverEventPublisher.publish(event);
71+
}
72+
73+
private UUID getTargetVolunteerId(CommunityComment communityComment, Long parentCommentId) {
74+
UUID targetVolunteerId;
75+
76+
if (parentCommentId == null) {
77+
targetVolunteerId = communityBoardRepository.findById(communityComment.getCommunityBoardId())
78+
.orElseThrow(EntityNotFoundException::new)
79+
.getWriterId();
80+
81+
return targetVolunteerId;
82+
}
83+
84+
targetVolunteerId = communityCommentRepository.findById(parentCommentId)
85+
.map(CommunityComment::getWriterId)
86+
.orElse(null);
87+
88+
return targetVolunteerId;
89+
}
5090
}

src/main/java/com/somemore/global/common/event/ServerEvent.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,19 @@ protected ServerEvent(
2424
@JsonProperty(value = "subType", required = true) T subType,
2525
@JsonProperty(value = "createdAt", required = true) LocalDateTime createdAt
2626
) {
27+
validate(type, subType);
2728
this.type = type;
2829
this.subType = subType;
2930
this.createdAt = (createdAt == null) ? LocalDateTime.now() : createdAt;
3031
}
32+
33+
private void validate(ServerEventType type, T subType) {
34+
if (!type.getSubtype().isInstance(subType)) {
35+
throw new IllegalArgumentException(String.format(
36+
"잘못된 서브타입: %s는 %s와 일치하지 않습니다.",
37+
subType,
38+
type.getSubtype()
39+
));
40+
}
41+
}
3142
}

src/main/java/com/somemore/notification/converter/MessageConverter.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.somemore.notification.converter;
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
4-
import com.fasterxml.jackson.databind.JsonMappingException;
54
import com.fasterxml.jackson.databind.JsonNode;
65
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import com.somemore.community.event.CommentAddedEvent;
77
import com.somemore.facade.event.VolunteerReviewRequestEvent;
88
import com.somemore.notification.domain.Notification;
99
import com.somemore.notification.domain.NotificationSubType;
1010
import com.somemore.volunteerapply.domain.ApplyStatus;
11+
import com.somemore.volunteerapply.event.VolunteerApplyEvent;
1112
import com.somemore.volunteerapply.event.VolunteerApplyStatusChangeEvent;
1213
import lombok.RequiredArgsConstructor;
1314
import lombok.extern.slf4j.Slf4j;
@@ -29,6 +30,8 @@ public Notification from(String message) {
2930
case NOTE_BLAH_BLAH -> throw new UnsupportedOperationException("NOTE 알림 타입 처리 로직 미구현");
3031
case VOLUNTEER_REVIEW_REQUEST -> buildVolunteerReviewRequestNotification(message);
3132
case VOLUNTEER_APPLY_STATUS_CHANGE -> buildVolunteerApplyStatusChangeNotification(message);
33+
case COMMENT_ADDED -> buildCommentAddedNotification(message);
34+
case VOLUNTEER_APPLY -> buildVolunteerApplyNotification(message);
3235
};
3336
} catch (Exception e) {
3437
log.error(e.getMessage());
@@ -58,6 +61,28 @@ private Notification buildVolunteerApplyStatusChangeNotification(String message)
5861
.build();
5962
}
6063

64+
private Notification buildCommentAddedNotification(String message) throws JsonProcessingException {
65+
CommentAddedEvent event = objectMapper.readValue(message, CommentAddedEvent.class);
66+
67+
return Notification.builder()
68+
.receiverId(event.getVolunteerId())
69+
.title(createCommentAddedNotificationTitle())
70+
.type(NotificationSubType.COMMENT_ADDED)
71+
.relatedId(event.getCommunityBoardId())
72+
.build();
73+
}
74+
75+
private Notification buildVolunteerApplyNotification(String message) throws JsonProcessingException {
76+
VolunteerApplyEvent event = objectMapper.readValue(message, VolunteerApplyEvent.class);
77+
78+
return Notification.builder()
79+
.receiverId(event.getCenterId())
80+
.title(createVolunteerApplyNotificationTitle())
81+
.type(NotificationSubType.VOLUNTEER_APPLY)
82+
.relatedId(event.getRecruitBoardId())
83+
.build();
84+
}
85+
6186
private String createVolunteerReviewRequestNotificationTitle() {
6287
return "최근 활동하신 활동의 후기를 작성해 주세요!";
6388
}
@@ -72,4 +97,12 @@ private String createVolunteerApplyStatusChangeNotificationTitle(ApplyStatus new
7297
}
7398
};
7499
}
100+
101+
private String createCommentAddedNotificationTitle() {
102+
return "새로운 댓글이 작성되었습니다.";
103+
}
104+
105+
private String createVolunteerApplyNotificationTitle() {
106+
return "봉사 활동 모집에 새로운 신청이 있습니다.";
107+
}
75108
}

src/main/java/com/somemore/notification/domain/NotificationSubType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
public enum NotificationSubType {
99
NOTE_BLAH_BLAH("쪽지"),
1010
VOLUNTEER_REVIEW_REQUEST("봉사 후기 요청"),
11-
VOLUNTEER_APPLY_STATUS_CHANGE("신청 상태 변경")
11+
VOLUNTEER_APPLY_STATUS_CHANGE("신청 상태 변경"),
12+
COMMENT_ADDED("댓글 대댓글 추가"),
13+
VOLUNTEER_APPLY("봉사 신청"),
1214
;
1315

1416
private final String description;

src/main/java/com/somemore/notification/dto/NotificationResponseDto.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import java.time.LocalDateTime;
1010

1111
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
12-
@Schema(description = "알림 응답 전송 DTO")
12+
@Schema(description = "알림 응답 DTO")
1313
public record NotificationResponseDto(
14+
@Schema(description = "알림 ID", example = "1")
15+
Long id,
1416
@Schema(description = "알림 제목", example = "봉사 활동 신청이 승인되었습니다.")
1517
String title,
1618

@@ -25,6 +27,7 @@ public record NotificationResponseDto(
2527

2628
public static NotificationResponseDto from(Notification notification) {
2729
return new NotificationResponseDto(
30+
notification.getId(),
2831
notification.getTitle(),
2932
notification.getType(),
3033
notification.getRelatedId(),
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.somemore.volunteerapply.event;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.somemore.global.common.event.ServerEvent;
6+
import com.somemore.global.common.event.ServerEventType;
7+
import com.somemore.notification.domain.NotificationSubType;
8+
import lombok.Getter;
9+
import lombok.experimental.SuperBuilder;
10+
11+
import java.time.LocalDateTime;
12+
import java.util.UUID;
13+
14+
@Getter
15+
@SuperBuilder
16+
public class VolunteerApplyEvent extends ServerEvent<NotificationSubType> {
17+
private final UUID volunteerId;
18+
private final Long volunteerApplyId;
19+
private final UUID centerId;
20+
private final Long recruitBoardId;
21+
22+
@JsonCreator
23+
public VolunteerApplyEvent(
24+
@JsonProperty(value = "volunteerId", required = true) UUID volunteerId,
25+
@JsonProperty(value = "volunteerApplyId", required = true) Long volunteerApplyId,
26+
@JsonProperty(value = "centerId", required = true) UUID centerId,
27+
@JsonProperty(value = "recruitBoardId", required = true) Long recruitBoardId
28+
) {
29+
super(ServerEventType.NOTIFICATION, NotificationSubType.VOLUNTEER_APPLY, LocalDateTime.now());
30+
this.volunteerId = volunteerId;
31+
this.volunteerApplyId = volunteerApplyId;
32+
this.centerId = centerId;
33+
this.recruitBoardId = recruitBoardId;
34+
}
35+
}

src/main/java/com/somemore/volunteerapply/service/ApplyVolunteerApplyService.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
import static com.somemore.global.exception.ExceptionMessage.DUPLICATE_APPLICATION;
44
import static com.somemore.global.exception.ExceptionMessage.RECRUITMENT_NOT_OPEN;
55

6+
import com.somemore.global.common.event.ServerEventPublisher;
7+
import com.somemore.global.common.event.ServerEventType;
68
import com.somemore.global.exception.BadRequestException;
9+
import com.somemore.notification.domain.NotificationSubType;
710
import com.somemore.recruitboard.domain.RecruitBoard;
811
import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase;
912
import com.somemore.volunteerapply.domain.VolunteerApply;
1013
import com.somemore.volunteerapply.dto.request.VolunteerApplyCreateRequestDto;
14+
import com.somemore.volunteerapply.event.VolunteerApplyEvent;
1115
import com.somemore.volunteerapply.repository.VolunteerApplyRepository;
1216
import com.somemore.volunteerapply.usecase.ApplyVolunteerApplyUseCase;
1317
import java.util.UUID;
@@ -22,6 +26,7 @@ public class ApplyVolunteerApplyService implements ApplyVolunteerApplyUseCase {
2226

2327
private final VolunteerApplyRepository volunteerApplyRepository;
2428
private final RecruitBoardQueryUseCase recruitBoardQueryUseCase;
29+
private final ServerEventPublisher serverEventPublisher;
2530

2631
@Override
2732
public Long apply(VolunteerApplyCreateRequestDto requestDto, UUID volunteerId) {
@@ -33,6 +38,8 @@ public Long apply(VolunteerApplyCreateRequestDto requestDto, UUID volunteerId) {
3338
VolunteerApply apply = requestDto.toEntity(volunteerId);
3439
volunteerApplyRepository.save(apply);
3540

41+
publishVolunteerApplyEvent(apply, board);
42+
3643
return apply.getId();
3744
}
3845

@@ -50,4 +57,17 @@ private void validateDuplicatedApply(UUID volunteerId, RecruitBoard board) {
5057
throw new BadRequestException(DUPLICATE_APPLICATION);
5158
}
5259
}
60+
61+
private void publishVolunteerApplyEvent(VolunteerApply apply, RecruitBoard board) {
62+
VolunteerApplyEvent event = VolunteerApplyEvent.builder()
63+
.type(ServerEventType.NOTIFICATION)
64+
.subType(NotificationSubType.VOLUNTEER_APPLY)
65+
.volunteerId(apply.getVolunteerId())
66+
.volunteerApplyId(apply.getId())
67+
.centerId(board.getCenterId())
68+
.recruitBoardId(board.getId())
69+
.build();
70+
71+
serverEventPublisher.publish(event);
72+
}
5373
}

0 commit comments

Comments
 (0)