Skip to content

Commit

Permalink
[SAMBAD-301] 손 흔들기 알림 추가 정보 제공 방식 변경 (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
kkjsw17 authored Aug 26, 2024
1 parent 67df6f2 commit a5dd742
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.depromeet.sambad.moring.event.infrastructure.EventProperties;
import org.depromeet.sambad.moring.event.presentation.excepiton.NotFoundEventException;
import org.depromeet.sambad.moring.event.presentation.response.PollingEventListResponse;
import org.depromeet.sambad.moring.meeting.handwaving.domain.HandWaving;
import org.depromeet.sambad.moring.meeting.member.domain.MeetingMemberValidator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -31,21 +32,28 @@ public class EventService {
private final EventProperties eventProperties;

public void publish(Long userId, Long meetingId, EventType type) {
this.publish(userId, meetingId, type, Map.of(), Map.of());
this.publish(userId, meetingId, type, Map.of());
}

public void publish(
Long userId, Long meetingId, EventType type, Map<String, String> contentsMap, Map<String, Object> additionalData
public void publishHandWavingEvent(
Long userId, Long meetingId, EventType type, Map<String, String> contentsMap, HandWaving handWaving
) {
Event event = this.publish(userId, meetingId, type, contentsMap);
handWaving.mapEvent(event);
}

private Event publish(Long userId, Long meetingId, EventType type, Map<String, String> contentsMap) {
if (meetingMemberValidator.isNotUserOfMeeting(userId, meetingId)) {
log.warn("User is not member of meeting. userId: {}, meetingId: {}", userId, meetingId);
return;
return null;
}

String message = constructEventMessage(type, contentsMap);

Event event = Event.publish(userId, meetingId, type, message, additionalData);
Event event = Event.publish(userId, meetingId, type, message);
eventRepository.save(event);

return event;
}

public void inactivate(Long eventId) {
Expand Down Expand Up @@ -86,10 +94,6 @@ public void inactivateLastEventsOfAllMemberByType(Long meetingId, EventType even
}

private String constructEventMessage(EventType type, Map<String, String> contentsMap) {
if (contentsMap.isEmpty()) {
return null;
}

return eventMessageTemplateRepository.findByType(type)
.map(template -> template.replaceTemplateVariables(contentsMap))
.orElse(null);
Expand Down
21 changes: 8 additions & 13 deletions src/main/java/org/depromeet/sambad/moring/event/domain/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
import static jakarta.persistence.GenerationType.*;
import static lombok.AccessLevel.*;
import static org.depromeet.sambad.moring.event.domain.EventStatus.*;
import static org.depromeet.sambad.moring.event.domain.EventType.*;
import static org.depromeet.sambad.moring.meeting.question.domain.MeetingQuestion.*;

import java.time.LocalDateTime;
import java.util.Map;

import org.depromeet.sambad.moring.common.domain.BaseTimeEntity;

import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -44,28 +43,20 @@ public class Event extends BaseTimeEntity {

private LocalDateTime expiredAt;

@Column(columnDefinition = "text")
@Convert(converter = MapToJsonConverter.class)
private Map<String, Object> additionalData = Map.of();

private Event(
Long userId, Long meetingId, EventType type, EventStatus status, String message, LocalDateTime expiredAt,
Map<String, Object> additionalData
Long userId, Long meetingId, EventType type, EventStatus status, String message, LocalDateTime expiredAt
) {
this.userId = userId;
this.meetingId = meetingId;
this.type = type;
this.status = status;
this.message = message;
this.expiredAt = expiredAt;
this.additionalData = additionalData;
}

public static Event publish(
Long userId, Long meetingId, EventType type, String message, Map<String, Object> additionalData
) {
public static Event publish(Long userId, Long meetingId, EventType type, String message) {
LocalDateTime expiredAt = LocalDateTime.now().plusSeconds(RESPONSE_TIME_LIMIT_SECONDS);
return new Event(userId, meetingId, type, ACTIVE, message, expiredAt, additionalData);
return new Event(userId, meetingId, type, ACTIVE, message, expiredAt);
}

public void inactivate() {
Expand All @@ -85,4 +76,8 @@ private boolean isExpired() {
public boolean isActive() {
return status == ACTIVE;
}

public boolean isHandWavingEvent() {
return type == HAND_WAVING_REQUESTED;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public class EventMessageTemplate {
private String template;

public String replaceTemplateVariables(Map<String, String> contentsMap) {
if (contentsMap == null) {
return template;
}

String message = template;
for (String key : contentsMap.keySet()) {
String regex = Pattern.quote("#{" + key + "}");
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package org.depromeet.sambad.moring.event.presentation;

import java.util.List;

import org.depromeet.sambad.moring.event.application.EventService;
import org.depromeet.sambad.moring.event.domain.Event;
import org.depromeet.sambad.moring.event.presentation.response.EventListResponse;
import org.depromeet.sambad.moring.event.presentation.response.PollingEventListResponse;
import org.depromeet.sambad.moring.user.presentation.resolver.UserId;
Expand All @@ -27,20 +24,24 @@
@RequiredArgsConstructor
@RequestMapping("/v1/events")
public class EventController {

private final EventService eventService;
private final EventFacade eventFacade;

@Operation(summary = "알림 목록 조회", description = """
<h2>Description</h2>
모임원이 수령해야 하는 알림 목록을 조회합니다.
<h2>Event Type List</h2>
* <b>QUESTION_REGISTERED</b>: 릴레이 질문이 등록되어 답변 가능한 경우
* <b>TARGET_MEMBER</b>: 릴레이 질문 등록 대상자로 선정된 경우
* <b>HAND_WAVING_REQUESTED</b>: 손 흔들기 요청이 들어온 경우
<h2>Additional Data</h2>
Event Type에 따라 addionalData가 다르게 반환됩니다.
* <b>HAND_WAVING_REQUESTED</b>: {"handWavingId": 1}""")
* <b>HAND_WAVING_REQUESTED</b>: {"handWavingId": 1, "status": "ACCEPTED"}
* <b>status == REQUESTED</b> 일 떄에만 수락 / 거절 버튼 표시되면 될 것 같습니다."""
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "알림 목록 조회 성공"),
@ApiResponse(responseCode = "403", description = "USER_NOT_MEMBER_OF_MEETING")
Expand All @@ -51,13 +52,13 @@ public ResponseEntity<EventListResponse> getEvents(
@Parameter(description = "모임 ID", example = "1", required = true)
@PathVariable("meetingId") @Positive Long meetingId
) {
List<Event> events = eventService.getEvents(userId, meetingId);
return ResponseEntity.ok(EventListResponse.from(events));
EventListResponse response = eventFacade.getEventsResponse(userId, meetingId);
return ResponseEntity.ok(response);
}

@Operation(summary = "사용자가 받아야 하는 이벤트 목록 조회", description = """
사용자가 받아야 하는 이벤트의 목록을 조회합니다.
Event List
* QUESTION_REGISTERED: 릴레이 질문이 등록되어 답변 가능한 경우
* TARGET_MEMBER: 릴레이 질문 등록 대상자로 선정된 경우
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.depromeet.sambad.moring.event.presentation;

import java.util.List;

import org.depromeet.sambad.moring.event.application.EventService;
import org.depromeet.sambad.moring.event.domain.Event;
import org.depromeet.sambad.moring.event.presentation.response.EventListResponse;
import org.depromeet.sambad.moring.event.presentation.response.EventResponse;
import org.depromeet.sambad.moring.meeting.handwaving.application.HandWavingService;
import org.depromeet.sambad.moring.meeting.handwaving.domain.HandWavingSummary;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service
public class EventFacade {

private final EventService eventService;
private final HandWavingService handWavingService;

public EventListResponse getEventsResponse(Long userId, Long meetingId) {
List<Event> events = eventService.getEvents(userId, meetingId);
List<HandWavingSummary> handWavingSummaries = fetchHandWavingEventSummaries(events);

return mapToEventListResponse(events, handWavingSummaries);
}

private List<HandWavingSummary> fetchHandWavingEventSummaries(List<Event> events) {
List<Event> handWavingEvents = events.stream()
.filter(Event::isHandWavingEvent)
.toList();

return handWavingService.getHandWavingSummariesBy(handWavingEvents);
}

private EventListResponse mapToEventListResponse(List<Event> events, List<HandWavingSummary> handWavingSummaries) {
List<EventResponse> responses = events.stream()
.map(event -> mapToResponseConsiderEventType(event, handWavingSummaries))
.toList();

return EventListResponse.from(responses);
}

private EventResponse mapToResponseConsiderEventType(Event event, List<HandWavingSummary> handWavingSummaries) {
HandWavingSummary additionalData = HandWavingSummary.findSummaryByEvent(handWavingSummaries, event);

return EventResponse.from(event, additionalData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@

import java.util.List;

import org.depromeet.sambad.moring.event.domain.Event;

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

public record EventListResponse(
@Schema(description = "이벤트 목록", requiredMode = REQUIRED)
List<EventResponse> contents
) {

public static EventListResponse from(List<Event> events) {
List<EventResponse> contents = events.stream()
.map(EventResponse::from)
.toList();

return new EventListResponse(contents);
public static EventListResponse from(List<EventResponse> events) {
return new EventListResponse(events);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.depromeet.sambad.moring.event.domain.Event;
Expand All @@ -27,12 +26,12 @@ public record EventResponse(
EventStatus status,

@Schema(description = "이벤트 타입 별로 필요한 추가 데이터", example = "{\"handWavingId\": 9}", requiredMode = NOT_REQUIRED)
Map<String, Object> additionalData,
Object additionalData,

@Schema(description = "이벤트 생성 시간 타임 스탬프", example = "1724252079282", requiredMode = REQUIRED)
Long createdAt
) {
public static EventResponse from(Event event) {
public static EventResponse from(Event event, Object additionalData) {
List<String> messages = Optional.ofNullable(event.getMessage())
.map(message -> Arrays.asList(message.split("\n")))
.orElse(List.of());
Expand All @@ -42,7 +41,7 @@ public static EventResponse from(Event event) {
event.getType(),
messages,
event.getStatus(),
event.getAdditionalData(),
additionalData,
event.getCreatedAtWithEpochMilli()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public interface HandWavingRepository {
Optional<HandWaving> findFirstBySenderIdAndReceiverIdOrderByIdDesc(Long senderMemberId, Long receiverMemberId);

List<MeetingMember> findHandWavedMembersByMeetingMemberId(Long meetingMemberId);

List<HandWaving> findAllByEventIdIn(List<Long> eventIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import static org.depromeet.sambad.moring.event.domain.EventType.*;
import static org.depromeet.sambad.moring.meeting.handwaving.domain.HandWavingStatus.NOT_REQUESTED;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.depromeet.sambad.moring.event.application.EventService;
import org.depromeet.sambad.moring.event.domain.Event;
import org.depromeet.sambad.moring.meeting.handwaving.domain.HandWaving;
import org.depromeet.sambad.moring.meeting.handwaving.domain.HandWavingStatus;
import org.depromeet.sambad.moring.meeting.handwaving.domain.HandWavingSummary;
import org.depromeet.sambad.moring.meeting.handwaving.presentation.exception.NotFoundHandWavingException;
import org.depromeet.sambad.moring.meeting.handwaving.presentation.request.HandWavingRequest;
import org.depromeet.sambad.moring.meeting.handwaving.presentation.response.HandWavingStatusResponse;
Expand Down Expand Up @@ -64,6 +66,17 @@ public void ignoreHandWaving(Long userId, Long meetingId, Long handWavingId) {
handWaving.reject();
}

public List<HandWavingSummary> getHandWavingSummariesBy(List<Event> events) {
List<Long> eventIds = events.stream()
.map(Event::getId)
.toList();

return handWavingRepository.findAllByEventIdIn(eventIds)
.stream()
.map(HandWavingSummary::from)
.toList();
}

private Optional<HandWaving> getHandWavingBySenderIdAndReceiverId(Long senderMemberId, Long receiverMemberId) {
return handWavingRepository.findFirstBySenderIdAndReceiverIdOrderByIdDesc(senderMemberId, receiverMemberId);
}
Expand All @@ -82,13 +95,9 @@ private void publishRequestedEvent(HandWaving handWaving) {
"receiver", receiver.getName()
);

Map<String, Object> additionalData = Map.of(
"handWavingId", handWaving.getId()
);

Long userId = receiver.getUser().getId();
Long meetingId = receiver.getMeeting().getId();

eventService.publish(userId, meetingId, HAND_WAVING_REQUESTED, contentsMap, additionalData);
eventService.publishHandWavingEvent(userId, meetingId, HAND_WAVING_REQUESTED, contentsMap, handWaving);
}
}
Loading

0 comments on commit a5dd742

Please sign in to comment.