Skip to content

Commit

Permalink
feat : 공연 알림 저장 후 조회 구현 (#27)
Browse files Browse the repository at this point in the history
  • Loading branch information
GaBaljaintheroom authored Nov 11, 2024
1 parent d1f0f10 commit 8dcd822
Show file tree
Hide file tree
Showing 31 changed files with 602 additions and 3 deletions.
4 changes: 4 additions & 0 deletions app/api/alarm-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
implementation project(":app:domain:alarm-domain")
implementation project(":app:api:common-api")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.example.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({
AlarmDomainConfig.class
})
@ComponentScan(basePackages = "org.example")
@RequiredArgsConstructor
public class AlarmApiConfig {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.example.controller;

import jakarta.validation.constraints.Max;
import java.util.Optional;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.example.controller.dto.param.ShowAlarmPaginationApiParam;
import org.example.controller.dto.response.ShowAlarmActivateApiResponse;
import org.example.dto.response.CursorApiResponse;
import org.example.dto.response.PaginationApiResponse;
import org.example.service.ShowAlarmService;
import org.example.service.dto.request.ShowAlarmsServiceRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/show-alarm")
public class ShowAlarmController {

private final ShowAlarmService showAlarmService;

@PostMapping
public ResponseEntity<PaginationApiResponse<ShowAlarmPaginationApiParam>> getShowAlarms(
@RequestParam(value = "fcmToken") String fcmToken,
@RequestParam(value = "cursorId", required = false) UUID cursorId,
@RequestParam(value = "size") @Max(value = 30, message = "조회하는 데이터의 최대 개수는 30입니다.")
Integer size
) {
var response = showAlarmService.getShowAlarms(
ShowAlarmsServiceRequest.builder()
.fcmToken(fcmToken)
.cursorId(cursorId)
.size(size)
.build()
);
var data = response.data().stream()
.map(ShowAlarmPaginationApiParam::from)
.toList();

CursorApiResponse cursor = Optional.ofNullable(CursorApiResponse.getLastElement(data))
.map(element -> CursorApiResponse.toCursorId(element.id()))
.orElse(CursorApiResponse.noneCursor());

return ResponseEntity.ok(
PaginationApiResponse.<ShowAlarmPaginationApiParam>builder()
.hasNext(response.hasNext())
.data(data)
.cursor(cursor)
.build()
);
}

@GetMapping("/checked")
public ResponseEntity<ShowAlarmActivateApiResponse> getShowAlarmActivate(
@RequestParam(value = "fcmToken") String fcmToken
) {
return ResponseEntity.ok(
ShowAlarmActivateApiResponse.from(
showAlarmService.getShowAlarmActivate(fcmToken)
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.example.controller.dto.param;

import java.time.LocalDateTime;
import java.util.UUID;
import lombok.Builder;
import org.example.service.dto.param.ShowAlarmPaginationServiceParam;

@Builder
public record ShowAlarmPaginationApiParam(
UUID id,
String title,
String content,
LocalDateTime createAt
) {

public static ShowAlarmPaginationApiParam from(ShowAlarmPaginationServiceParam param) {
return ShowAlarmPaginationApiParam.builder()
.id(param.id())
.title(param.title())
.content(param.content())
.createAt(param.createAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example.controller.dto.response;

import org.example.service.dto.response.ShowAlarmActivateServiceResponse;

public record ShowAlarmActivateApiResponse(
boolean isActivate
) {

public static ShowAlarmActivateApiResponse from(ShowAlarmActivateServiceResponse response) {
return new ShowAlarmActivateApiResponse(response.isActivate());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.example.service;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.example.dto.request.ShowAlarmsCheckedRequest;
import org.example.dto.response.PaginationServiceResponse;
import org.example.service.dto.param.ShowAlarmPaginationServiceParam;
import org.example.service.dto.request.ShowAlarmsServiceRequest;
import org.example.service.dto.response.ShowAlarmActivateServiceResponse;
import org.example.usecase.ShowAlarmUseCase;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ShowAlarmService {

private final ShowAlarmUseCase showAlarmUseCase;


public PaginationServiceResponse<ShowAlarmPaginationServiceParam> getShowAlarms(
ShowAlarmsServiceRequest request
) {
var response = showAlarmUseCase.findShowAlarms(request.toDomainRequest());
showAlarmUseCase.updateUncheckedAlarms(response.data().stream()
.map(ShowAlarmsCheckedRequest::from)
.toList()
);

List<ShowAlarmPaginationServiceParam> data = response.data().stream()
.map(ShowAlarmPaginationServiceParam::from)
.toList();

return PaginationServiceResponse.of(data, response.hasNext());
}

public ShowAlarmActivateServiceResponse getShowAlarmActivate(String fcmToken) {
return ShowAlarmActivateServiceResponse.from(showAlarmUseCase.hasUncheckedAlarms(fcmToken));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.example.service.dto.param;

import java.time.LocalDateTime;
import java.util.UUID;
import lombok.Builder;
import org.example.dto.response.ShowAlarmDomainResponse;

@Builder
public record ShowAlarmPaginationServiceParam(
UUID id,
String title,
String content,
LocalDateTime createAt
) {

public static ShowAlarmPaginationServiceParam from(ShowAlarmDomainResponse response) {
return ShowAlarmPaginationServiceParam.builder()
.id(response.id())
.title(response.title())
.content(response.content())
.createAt(response.createAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.service.dto.request;

import java.util.UUID;
import lombok.Builder;
import org.example.dto.request.ShowAlarmsDomainRequest;

@Builder
public record ShowAlarmsServiceRequest(
String fcmToken,
UUID cursorId,
Integer size
) {
public ShowAlarmsDomainRequest toDomainRequest() {
return ShowAlarmsDomainRequest.builder()
.fcmToken(fcmToken)
.cursorId(cursorId)
.size(size)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.example.service.dto.response;

public record ShowAlarmActivateServiceResponse(
boolean isActivate
) {

public static ShowAlarmActivateServiceResponse from(boolean hasUncheckedAlarms) {
return new ShowAlarmActivateServiceResponse(hasUncheckedAlarms);
}

}
1 change: 1 addition & 0 deletions app/api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ dependencies {
// for config registry
implementation project(":app:api:subscription-api")
implementation project(":app:api:ticketing-api")
implementation project(":app:api:alarm-api")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.example.dto.response;

import java.util.List;

public record CursorApiResponse(

Object id,

Object value
) {

public static CursorApiResponse toCursorResponse(Object id, Object value) {
return new CursorApiResponse(id, value);
}

public static CursorApiResponse toCursorId(Object id) {
return new CursorApiResponse(id, null);
}

public static CursorApiResponse noneCursor() {
return new CursorApiResponse(null, null);
}

public static <T> T getLastElement(List<T> list) {
return list.isEmpty() ? null : list.get(list.size() - 1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.example.dto.response;

import java.util.List;
import lombok.Builder;

public record PaginationApiResponse<T>(
int size,
boolean hasNext,
List<T> data,
CursorApiResponse cursor
) {

@Builder
public PaginationApiResponse(
List<T> data,
boolean hasNext,
CursorApiResponse cursor
) {
this(data.size(), hasNext, data, cursor);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.example.dto.response;

import java.util.List;

public record PaginationServiceResponse<T>(
boolean hasNext,
List<T> data
) {

public static <T> PaginationServiceResponse<T> of(
List<T> data,
boolean hasNext
) {
if (data == null || data.isEmpty()) {
data = List.of();
}

return new PaginationServiceResponse<>(hasNext, data);
}
}
2 changes: 1 addition & 1 deletion app/api/src/main/java/org/example/config/ApiConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.springframework.context.annotation.Import;

@Configuration
@Import({SubscriptionApiConfig.class, TicketingApiConfig.class})
@Import({SubscriptionApiConfig.class, TicketingApiConfig.class, AlarmApiConfig.class})
public class ApiConfig {

}
1 change: 1 addition & 0 deletions app/api/subscription-api/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dependencies {
implementation project(":app:domain:subscription-domain")
implementation project(":app:domain:alarm-domain")
implementation project(":app:api:common-api")

//redis sub
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.example.SubscriptionMessage;
import org.example.dto.response.ArtistSubscriptionDomainResponse;
import org.example.dto.response.GenreSubscriptionDomainResponse;
import org.example.entity.ShowAlarm;
import org.example.message.MessageParam;
import org.example.message.PushMessageTemplate;
import org.example.service.dto.ArtistSubscriptionMessageServiceRequest;
Expand All @@ -15,17 +16,19 @@
import org.example.service.dto.SubscriptionMessageServiceRequest;
import org.example.usecase.ArtistSubscriptionUseCase;
import org.example.usecase.GenreSubscriptionUseCase;
import org.example.usecase.ShowAlarmUseCase;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class SubscriptionAlarmService {

private final ArtistSubscriptionUseCase artistSubscriptionUseCase;
private final GenreSubscriptionUseCase genreSubscriptionUseCase;
private final ShowAlarmUseCase showAlarmUseCase;
private final SubscriptionMessage subscriptionMessage;


public void showRelationSubscription(SubscriptionMessageServiceRequest request) {
var artistSubscriptions = artistSubscriptionUseCase.findArtistSubscriptionsByArtistIds(request.artistIds());
Map<String, List<String>> artistSubscriptionsMap = artistSubscriptions.stream()
Expand All @@ -42,6 +45,7 @@ public void showRelationSubscription(SubscriptionMessageServiceRequest request)
MessageParam message = PushMessageTemplate.getSubscribedArtistVisitKoreaAlertMessage(artistName);

subscriptionMessage.send(MultipleTargetMessageServiceRequest.of(fcmTokens, message));
saveShowAlarm(fcmTokens, message);
}

var genreSubscriptions = genreSubscriptionUseCase.findGenreSubscriptionsByGenreIds(request.genreIds());
Expand All @@ -59,9 +63,23 @@ public void showRelationSubscription(SubscriptionMessageServiceRequest request)
MessageParam message = PushMessageTemplate.getSubscribedGenreVisitKoreaAlertMessage(genreName);

subscriptionMessage.send(MultipleTargetMessageServiceRequest.of(fcmTokens, message));
saveShowAlarm(fcmTokens, message);
}
}

@Transactional
public void saveShowAlarm(List<String> fcmTokens, MessageParam message) {
fcmTokens.stream()
.map(userFcmToken -> ShowAlarm.builder()
.userFcmToken(userFcmToken)
.title(message.title())
.content(message.body())
.checked(false)
.build()
)
.forEach(showAlarmUseCase::save);
}

public void artistSubscribe(ArtistSubscriptionMessageServiceRequest request) {
artistSubscriptionUseCase.artistSubscribe(request.toDomainRequest());
}
Expand Down
4 changes: 4 additions & 0 deletions app/batch/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ allprojects {
dependencies {
implementation project(":app:api:ticketing-api")
implementation project(":app:domain:ticketing-domain")
implementation project(":app:domain:alarm-domain")
implementation project(":app:domain:common-domain")

implementation 'org.springframework.data:spring-data-commons:3.3.0'
}
Loading

0 comments on commit 8dcd822

Please sign in to comment.